|
M_threadpool_t * | M_threadpool_create (size_t min_threads, size_t max_threads, M_uint64 idle_time_ms, size_t queue_max_size) |
|
void | M_threadpool_destroy (M_threadpool_t *pool) |
|
M_threadpool_parent_t * | M_threadpool_parent_create (M_threadpool_t *pool) |
|
M_bool | M_threadpool_parent_destroy (M_threadpool_parent_t *parent) |
|
void | M_threadpool_dispatch (M_threadpool_parent_t *parent, void(*task)(void *), void **task_args, size_t num_tasks) |
|
void | M_threadpool_dispatch_notify (M_threadpool_parent_t *parent, void(*task)(void *), void **task_args, size_t num_tasks, void(*finished)(void *)) |
|
size_t | M_threadpool_available_slots (const M_threadpool_t *pool) |
|
void | M_threadpool_wait_available_thread (M_threadpool_parent_t *parent) |
|
size_t | M_threadpool_num_threads (const M_threadpool_t *pool) |
|
void | M_threadpool_parent_wait (M_threadpool_parent_t *parent) |
|
Implementation of a thread pool for having a limited the number of threads available to workers. Threads in the pool will only be destroyed when the pool is destroyed. A maximum number of threads will be created by the pool. Workers are assigned to parents which can be used to logically separate workers by tasks.
Example:
static M_uint32 count = 0;
static void pool_task(void *arg)
{
(void)arg;
}
int main(int argc, char **argv)
{
char args[32];
return 0;
}
M_uint32 M_atomic_inc_u32(volatile M_uint32 *ptr)
ssize_t M_printf(const char *fmt,...)
void * M_mem_set(void *s, int c, size_t n)
void M_threadpool_dispatch(M_threadpool_parent_t *parent, void(*task)(void *), void **task_args, size_t num_tasks)
M_threadpool_t * M_threadpool_create(size_t min_threads, size_t max_threads, M_uint64 idle_time_ms, size_t queue_max_size)
M_bool M_threadpool_parent_destroy(M_threadpool_parent_t *parent)
struct M_threadpool_parent M_threadpool_parent_t
Definition: m_threadpool.h:86
struct M_threadpool M_threadpool_t
Definition: m_threadpool.h:83
M_threadpool_parent_t * M_threadpool_parent_create(M_threadpool_t *pool)
void M_threadpool_destroy(M_threadpool_t *pool)
void M_threadpool_parent_wait(M_threadpool_parent_t *parent)
◆ M_threadpool_t
◆ M_threadpool_parent_t
◆ M_threadpool_create()
M_threadpool_t * M_threadpool_create |
( |
size_t |
min_threads, |
|
|
size_t |
max_threads, |
|
|
M_uint64 |
idle_time_ms, |
|
|
size_t |
queue_max_size |
|
) |
| |
Initializes a new threadpool and spawns the minimum number of threads requested.
- Parameters
-
[in] | min_threads | Minimum number of threads to spawn, 0 to not pre-spawn any. |
[in] | max_threads | Maximum number of threads to spawn, any number above the min_threads number will be spawned on demand, and idle threads will be shutdown after the specified idle time. Must be greater than 0. |
[in] | idle_time_ms | Number of milliseconds a thread can be idle for before it is destroyed when the total thread count is above min_threads. If min_threads and max_threads are the same value, this parameter is ignored. Use M_UINT64_MAX to never terminate an idle thread, or use 0 to never allow idle threads. |
[in] | queue_max_size | If 0, will calculate a desirable queue size based on the maximum thread count. Otherwise, must be at least the size of the thread pool. It often makes sense to have the queue larger than the threadpool size to prevent the threads from sleeping. When inserting into the queue, if there are no available slots the M_threadpool_dispatch() function will block. If blocking is not desirable, use SIZE_MAX to allow an unbounded number of queue slots. |
- Returns
- initialized threadpool or NULL on failure
◆ M_threadpool_destroy()
Shuts down the thread pool, waits for all threads to exit.
- Parameters
-
[in] | pool | initialized threadpool. |
◆ M_threadpool_parent_create()
Creates a new parent/user/consumer of the threadpool.
This is the handle used to insert tasks and wait for task completion specific to the consumer.
It is safe to share this handle across multiple threads if convenient as long as it is guaranteed to not be destroyed until all consumers are done using it. If sharing across multiple threads, it probably would mean you would not be using M_threadpool_parent_wait() from multiple threads simultaneously.
- Parameters
-
[in] | pool | Initialized thread pool. |
- Returns
- initialized parent/user/consumer handle.
◆ M_threadpool_parent_destroy()
Frees the parent handle.
There must be no oustanding tasks prior to calling this. Call M_threadpool_parent_wait() first if unsure to wait on all tasks to complete.
- Parameters
-
[in] | parent | Initialized parent handle. |
- Returns
- M_FALSE if there are tasks remaining, M_TRUE if successfully cleaned up.
◆ M_threadpool_dispatch()
void M_threadpool_dispatch |
( |
M_threadpool_parent_t * |
parent, |
|
|
void(*)(void *) |
task, |
|
|
void ** |
task_args, |
|
|
size_t |
num_tasks |
|
) |
| |
Dispatch a task or set of tasks to the threadpool. Identical to M_threadpool_dispatch_notify() if passed a NULL finished argument.
Requires a callback function to do the processing and an argument that is passed to the function. There is no way to retrieve a return value from the task, so the argument passed to the task should hold a result parameter if it is necessary to know the completion status. Multiple tasks may be queued simultaneously.
This may take a while to complete if there are no queue slots available.
- Parameters
-
[in,out] | parent | Initialized parent handle. |
[in] | task | Task callback. |
[in,out] | task_args | Argument array to pass to each task (one per task). |
[in] | num_tasks | total number of tasks being enqueued. |
◆ M_threadpool_dispatch_notify()
void M_threadpool_dispatch_notify |
( |
M_threadpool_parent_t * |
parent, |
|
|
void(*)(void *) |
task, |
|
|
void ** |
task_args, |
|
|
size_t |
num_tasks, |
|
|
void(*)(void *) |
finished |
|
) |
| |
Dispatch a task or set of tasks to the threadpool and notify on task completion.
Requires a callback function to do the processing and an argument that is passed to the function. There is no way to retrieve a return value from the task, so the argument passed to the task should hold a result parameter if it is necessary to know the completion status. Multiple tasks may be queued simultaneously.
This may take a while to complete if there are no queue slots available.
- Parameters
-
[in,out] | parent | Initialized parent handle. |
[in] | task | Task callback. |
[in,out] | task_args | Argument array to pass to each task (one per task). |
[in] | num_tasks | total number of tasks being enqueued. |
[in] | finished | Optional. Callback to call for each task completion. Will pass the callback the same argument passed to the task. Use NULL if no notification desired. |
◆ M_threadpool_available_slots()
Count the number of queue slots available to be enqueued for a threadpool.
- Parameters
-
[in] | pool | initialized threadpool. |
◆ M_threadpool_wait_available_thread()
Wait for a thread to become available for processing tasks.
This explicitly waits for a THREAD and NOT an available queue slot which there could be available slots. This is meant as an optimization in some instances where you want to ensure you enqueue some things together, especially if you're trying to manage SQL locks for tasks being performed. Typically though, this function would never be used.
- Parameters
-
[in] | parent | Initialized parent handle. |
◆ M_threadpool_num_threads()
Get the current count of the number of threads in the thread pool.
- Parameters
-
[in] | pool | Initialized pool handle. |
- Returns
- count of threads
◆ M_threadpool_parent_wait()
Wait for all queued tasks to complete then return.
This is a blocking function with no return value. It is not recommended to call this from mulitiple threads simultaneously.
- Parameters
-
[in] | parent | the initialized parent/user/consumer handle. |