aboutsummaryrefslogtreecommitdiff
path: root/include/std/thread_pool.h
blob: f8acf839c05b87087ee685ba7ee89369324b8af8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef AMAL_THREAD_POOL_H
#define AMAL_THREAD_POOL_H

#include "thread.h"
#include "buffer.h"
#include "buffer_view.h"

/*
    Return 0 if there is no error, otherwise return a non-0 value.
    If the result is not 0, then all additional tasks will be stopped.
*/
typedef int(*amal_thread_job_callback)(void *userdata);

typedef enum {
    THREAD_POOL_THREAD_STATUS_NEW,
    THREAD_POOL_THREAD_STATUS_IDLE,
    THREAD_POOL_THREAD_STATUS_RUNNING
} amal_thread_pool_thread_status;

typedef struct {
    amal_thread thread;
    amal_thread_pool_thread_status status;
} amal_thread_pool_thread;

typedef struct {
    amal_thread_job_callback callback;
    void *userdata;
} amal_thread_pool_task;

typedef struct {
    int num_threads;
    amal_thread_pool_thread *threads; /* Size of @threads is @num_threads */
    amal_mutex task_select_mutex;
    Buffer queued_tasks;
    bool dead;
    int num_finished_queued_tasks;
} amal_thread_pool;

typedef struct {
    amal_thread_pool *thread_pool;
    amal_thread_pool_thread *thread_pool_thread;
    amal_thread_job_callback callback;
    void *userdata;
} amal_thread_pool_callback_data;

/*
    If @num_threads is 0, then the number of threads selected will the number
    of physical threads, or 1
*/
CHECK_RESULT int thread_pool_init(amal_thread_pool *self, int num_threads);
void thread_pool_deinit(amal_thread_pool *self);
/*
    Thread-safe. Will fail if one task has failed, in which case it can only be used
    once @thread_pool_join_all_tasks has been called
*/
CHECK_RESULT int thread_pool_add_task(amal_thread_pool *self, amal_thread_job_callback callback, void *userdata);
/*
    Wait until all tasks have finished. Should only be called from one thread.
    Returns true if all tasks finished without any issues (if @thread_pool_mark_dead was not called)
*/
CHECK_RESULT bool thread_pool_join_all_tasks(amal_thread_pool *self);
/*
    Stop tasks as soon as possible and stop dispatch of new tasks.
    This can be used when work on one thread has failed and you want to
    stop tasks on all threads to report errors and stop additional tasks.
*/
void thread_pool_mark_dead(amal_thread_pool *self);

BufferView/*<amal_thread_pool_thread>*/ thread_pool_get_threads(amal_thread_pool *self);

#endif