Task Queue Interface

Function Signature Semantics
taskq* Taskq_create(int start_proc, int end_proc, int task_size, int topology) A task queue creation operation. Must be called by all processors. It specifies the range of processors, the size of the task (the size of data that you want to be distributed transparently among the participating processors). Be careful, however. If your task size is too big or if tasks have different sizes, you are probably better off if you enqueue pointers to pointers to data (handles which are of the same size) instead pointers to data. The tasks could be migrated more then once before they reach their final destination.

topology could be one of MESH, RING, HCUBE (you can select the one that performs better. It has nothing to do with the underlying hardware topology).

The return value is a pointer to a taskq data structure and it needs to be passed to all taskq functions.

int Taskq_enqueue(taskq* qid, int priority. void *data, int comp, int comm) Enqueue a task specified by a pointer. qid is the id of a task queue returned by the creation operation. A client also specifies task's priority and estimates of its associated computation and communication costs. You may need to tune these for your applications since the task queue uses these hints to implement load balancing. For example, if communication cost is very high and computation cost is very low, a task of an average priority will not be migrated.
int Taskq_enqueueX(taskq* qid, int proc, int priority. void *data, int comp, int comm) The same as Taskq_enqueue, except the task is placed on the processor specified by proc.
int Taskq_dequeue(taskq* qid, task_info *info, void *data) Dequeue a task. Returned value: 1 - success, a task is dequeued, 0 - failure, no task is dequeued, -1 - termination (no task is dequeued and no task could be generated in the entire system in the future). If task_info is non zero, the following task information structure is returned:
	typedef struct {
		taskq* qid;	
		int home_proc;	
		int task_id;
		int comp_cost;
		int comm_cost;
		int priority;
	} task_info
On success, the task is placed in a user specified data buffer.
int Taskq_terminated(taskq* qid) Check for termination. Termination detection is performed in the background in a lazy fashion. This primitive when executed by an individual processor if the task queue operations are over: there are no local tasks on any processors, there are no transit tasks and no tasks will be generated in the future.
int Taskq_clear(taskq* qid) By calling this primitive, a processor signals the global queue that it is out of tasks, and it will not generate any tasks on its own in the future.
Taskq_poll(taskq* qid) This needs to be called periodically to transfer control to task queue code for buffer management and communication purposes. This is an artifact of a particular implementation, you will need to call it from time to time, especially in the long running loops, to make sure the task queue gets control. Note, that enqueue and dequeue operations call Taskq_poll too, so if you already have these calls, you do not need to use Taskq_poll as well.