-
Notifications
You must be signed in to change notification settings - Fork 0
Thread Pool
Sudheer edited this page Mar 11, 2023
·
12 revisions
Implementation of a minimalist thread pool in C.
Uses ev_queue a lock-free queue, for the purpose of enqueueing tasks to the thread pool.
The worker threads use mutexes to coordinate. Prototype implementation without mutex/lock performs poorly in terms of CPU usage due to busy wait. Since the tasks can come at any instance spread over time, it is more efficient to use the lock based implementation as against a lock free one.
#include <thread_pool.h>
Inclusion of thread_pool.h exposes the following typedefs
typedef struct thread_pool_s thread_pool_s_type;
typedef struct thread_pool_s *thread_pool_type;
typedef void * task_argument_type;
Taks to the thread pool are submitted in the form of a function pointer to a function that performs the desired operation and a function pointer that performs the management of task complete notification.
typedef void (*task_func_type)(task_argument_type);
typedef void* (*task_func_with_return_t)(task_argument_type);
typedef void (*notify_task_completion_t)(void*, void*);
Creates a thread pool with num_threads, with this all the worker threads will be in the state
of waiting to perform a task
Parameters:
num_threads: int
Return:
thread_pool: thread_pool_type
ERROR:
upon error, return value is NULL and the global variable errno is set
EINVAL: invalid value of num_threads.
In case of being unable to create threads, the function aborts printing error to
standard ouput.
Shuts down the thread_pool and frees up allocated memory. All the worker threads are stopped
at the end of this operation.
Parameters:
thread_pool: thread_pool_type
Return:
ret : int, 0 is returned upon success and -1 in case of any error
ERROR:
if ret is -1 the global variable errno is set to
EINVAL: In case the passed thread pool is not valid
EBUSY: In case shutdown process has already been initiated.
Two types of tasks can be submitted to thread pool
- Functions that take an argument and dont have a return, the caller should separately arrange to get results once the task is complete
- Functions that take an argument (task_argument_type) and have a return (task_argument_type), a notification function gets called upon completion and the caller can implement any return data handling in the notification function.
Pushes a type1 task to the thread_pool queue.
Parameters:
thread_pool: thread_pool_type
task_func: task_func_type
arg: task_argument_type
Return:
void
ERROR:
TBD: Backlog
void enqueue_task_function(thread_pool_type, task_func_with_return_t,
task_argument_type, void * ref_data, notify_task_completion_t);
Pushes a type2 task to the queue. The task function will return upon completion and the notification function
will be invoked with return value of the task function and ref_data as arguments.
Parameters:
threa_pool: thread_pool_type
task_func: task_func_with_return_t
arg: task_argument_type
ref_data: void*
notification_func: notify_task_completion_t
Return:
none
ERROR:
TBD: Backlog