![]() |
GHOST
1.1.2
General, Hybrid, and Optimized Sparse Toolkit
|
The tasking functionality is a key feature of GHOST. It is designed to be as general as possible and to allow the use of (a-)synchronous tasks in many situations. The implementation is based on a task queue and a thread pool. There is a single task queue which holds all tasks, regardless of their properties such as hardware affinity.
Besides, there is a pool of shepherd threads which contains all threads which may ever manage a task. The number of threads in the pool is equal to the maximum number of concurrently executing tasks.
Affinity control of the GHOST threads is done by means of the hwloc library.
A pthread is created for each thread of the thread pool in ghost_thpool_create(). Each of the threads enters the specified function as the starting routine where it runs in an infinite loop. In this loop, the threads are waiting on a semaphore which counts the number of tasks in all queues. As soon as a task gets added to a queue, the first thread returning from sem_wait
will have the chance to execute this task. If, for any reason, the thread cannot execute the task (or any other task in the queue), the above-mentioned semaphore gets increased by one and the shepherd thread starts waiting again. Once the task queues are empty and subject to be killed (i.e., at termination of the application), a global variable is set to one and the threads break out of the infinite loop.
A GHOST task is of type ghost_task and should be initialized via ghost_task_create(), given a number of parameters.
There are several types of tasks which can be distinguished by the value of their ghost_task::flags variable. They can be combined by bitwise OR-ing the flags.