| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 | /* StarPU --- Runtime system for heterogeneous multicore architectures. * * Copyright (C) 2010,2011 University of Bordeaux * * StarPU is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * StarPU is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU Lesser General Public License in COPYING.LGPL for more details. */#include "socl.h"#include "task.h"#include "gc.h"/** * WARNING: command queues do NOT hold references on events. Only events hold references * on command queues. This way, event release will automatically remove the event from * its command queue. *//** * Returned implicit dependencies for a task * Command queue must be locked! */void command_queue_dependencies_implicit(	cl_command_queue cq, 	/* Command queue */	char is_barrier,	/* Is the task a barrier */	cl_int * ret_num_events,	/* Returned number of dependencies */	cl_event ** ret_events	/* Returned dependencies */) {	/*********************	 * Count dependencies	 *********************/	int ndeps = 0;	/* Add dependency to last barrier if applicable */	if (cq->barrier != NULL)		ndeps++;	/* Add dependencies to out-of-order events (if any) */	if (is_barrier) {		command_list cl = cq->commands;		while (cl != NULL) {			ndeps++;			cl = cl->next;		}	}	/*********************	 * Return dependencies	 *********************/	cl_event * evs = malloc(ndeps * sizeof(cl_event));	int n = 0;	/* Add dependency to last barrier if applicable */	if (cq->barrier != NULL)		evs[n++] = cq->barrier->event;	/* Add dependencies to out-of-order events (if any) */	if (is_barrier) {		command_list cl = cq->commands;		while (cl != NULL) {			evs[n++] = cl->cmd->event;			cl = cl->next;		}	}	*ret_num_events = ndeps;	*ret_events = evs;}	/** * Insert a command in the command queue * The command queue must be locked! */void command_queue_insert(	cl_command_queue 	cq, 	/* Command queue */	cl_command 		cmd,	/* Command */	int 			is_barrier		/* Is the task a barrier */) {	int in_order = !(cq->properties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE);	if (is_barrier)		cq->commands = NULL;	/* Add command to the list of out-of-order commands */	if (!in_order)		cq->commands = command_list_cons(cmd, cq->commands);	/* Register this event as last barrier */	if (is_barrier || in_order)		cq->barrier = cmd;	/* Add reference to the command queue */	gc_entity_store(&cmd->event->cq, cq);}/** * Return implicit and explicit dependencies for a task * The command queue must be locked! */void command_queue_dependencies(	cl_command_queue 	cq,		/* Command queue */	int 			is_barrier,	/* Is the task a barrier */	cl_int 			num_events,	/* Number of explicit dependencies */	const cl_event *	events,		/* Explicit dependencies */	cl_int * 		ret_num_events,	/* Returned number of dependencies */	cl_event ** 		ret_events	/* Returned dependencies */) {	cl_int implicit_num_events;	cl_event * implicit_events;	/* Implicit dependencies */	command_queue_dependencies_implicit(cq, is_barrier, &implicit_num_events, &implicit_events);	/* Explicit dependencies */	cl_int ndeps = implicit_num_events + num_events;	cl_event * evs = malloc(sizeof(cl_event) * ndeps);	memcpy(evs, implicit_events, sizeof(cl_event) * implicit_num_events);	memcpy(&evs[implicit_num_events], events, sizeof(cl_event) * num_events);	*ret_num_events = ndeps;	*ret_events = evs;}void command_queue_enqueue_ex(cl_command_queue cq, cl_command cmd, cl_uint num_events, const cl_event * events) {	/* Check if the command is a barrier */	int is_barrier = 0;	if (cmd->typ == CL_COMMAND_BARRIER) {		is_barrier = 1;		/* OpenCL has no CL_COMMAND_BARRIER type, so we fall back on CL_COMMAND_MARKER */		cmd->typ = CL_COMMAND_MARKER;	}	/* Set command queue field */	cmd->cq = cq;	/* Lock command queue */	pthread_mutex_lock(&cq->mutex);	//FIXME: crappy separation (command_queue_dependencies + command_queue_insert)	/* Get all (explicit + implicit) dependencies */	cl_int all_num_events;	cl_event * all_events;	command_queue_dependencies(cq, is_barrier, num_events, events, &all_num_events, &all_events);	/* Make all dependencies explicit for the command */	cmd->num_events = all_num_events;	cmd->events = all_events;	/* Insert command in the queue */	command_queue_insert(cq, cmd, is_barrier);	/* Unlock command queue */	pthread_mutex_unlock(&cq->mutex);}
 |