aboutsummaryrefslogtreecommitdiff
path: root/include/bh/thread.h
blob: 45a0e6edaeed0edce38d68b072969b358d2f8030 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#ifndef BHLIB_THREAD_H
#define BHLIB_THREAD_H

#include "bh.h"

#define BH_THREAD_CLEANUP   (1 << 0)

typedef void (*bh_thread_cb_t)(void *);
typedef struct bh_thread_s bh_thread_t;
typedef struct bh_mutex_s bh_mutex_t;
typedef struct bh_cond_s bh_cond_t;
typedef struct bh_task_s bh_task_t;
typedef struct bh_thread_pool_s bh_thread_pool_t;

#if defined(BHLIB_USE_PTHREAD)
bh_thread_t *bh_thread_new(bh_task_t *task);

bh_thread_pool_t *bh_thread_pool_new(size_t size);
#elif defined(BHLIB_USE_WINTHREAD)
typedef uintptr_t (__cdecl *bh_thread_begin_cb_t)(void *,
                                                  unsigned,
                                                  unsigned (__stdcall *)(void *),
                                                  void *,
                                                  unsigned,
                                                  unsigned *);

typedef uintptr_t (__cdecl *bh_thread_end_cb_t)(unsigned);

bh_thread_t *bh_thread_new_base(bh_task_t *task,
                                bh_thread_begin_cb_t begin,
                                bh_thread_end_cb_t end);

bh_thread_pool_t *bh_thread_pool_new_base(size_t size,
                                          bh_thread_begin_cb_t begin,
                                          bh_thread_end_cb_t end);

#define bh_thread_new(task) \
    bh_thread_new_base((task), _beginthreadex, _endthreadex)

#define bh_thread_pool_new(size) \
    bh_thread_pool_new_base((size), _beginthreadex, _endthreadex);

#endif

/**
 * @brief   Create new task
 *
 * @param   func    Function
 * @param   data    Function data
 * @param   flags   Task flags
 *
 * @return  Pointer to the new task
 *
 * @sa      bh_task_free, bh_task_reuse, bh_task_done
 */
bh_task_t *bh_task_new(void (*func)(void *),
                       void *data,
                       int flags);

/**
 * @brief Free the task.
 *
 * @param   task    Pointer to the task
 */
void bh_task_free(bh_task_t *task);

/**
 * @brief Reuse task.
 *
 * @param   task    Pointer to the task
 * @param   func    Function
 * @param   data    Data
 *
 * @sa      bh_task_free, bh_task_done
 */
void bh_task_reuse(bh_task_t *task,
                   void (*func)(void *),
                   void *data);

/**
 * @brief Check if task is done.
 *
 * @param   task    Pointer to the task
 *
 * @return  The return value is boolean flag, indicating if the task is done.
 */
int bh_task_done(bh_task_t *task);

/**
 * @function bh_thread_new
 *
 * @brief   Create new thread.
 *
 * @param   task    Thread task
 *
 * @return  Pointer to thread
 *
 * @sa      bh_thread_join, bh_thread_detach
 */

/**
 * @function bh_thread_pool_new
 * @brief Create new thread pool.
 *
 * @param   pool    Pointer to the thread pool
 * @param   size    Amount of threads
 *
 * @return  Pointer to thread pool
 *
 * @sa      bh_thread_pool_add, bh_thread_pool_join, bh_thread_pool_free
 */

/**
 * @brief   Join thread.
 *
 * @param   thread  Pointer to the thread
 *
 * @return  0 on success, non-zero otherwise
 *
 * @sa      bh_thread_detach
 */
int bh_thread_join(bh_thread_t *thread);

/**
 * @brief   Detach thread.
 *
 * @param   thread  Pointer to the thread
 *
 * @return  0 on success, non-zero otherwise
 *
 * @sa      bh_thread_join
 */
int bh_thread_detach(bh_thread_t *thread);

/**
 * @brief   Create mutex.
 *
 * @return  Pointer to the mutex
 *
 * @sa      bh_mutex_lock, bh_mutex_try_lock, bh_mutex_destroy
 */
bh_mutex_t *bh_mutex_new(void);

/**
 * @brief   Free mutex.
 *
 * @param   mutex   Pointer ot the mutex
 */
void bh_mutex_free(bh_mutex_t *mutex);

/**
 * @brief   Lock mutex.
 *
 * @param   mutex   Pointer to the mutex
 *
 * @return  0 on success, non-zero otherwise
 *
 * @note    Locking already locked mutex will block thread until mutex is
 *          released
 *
 * @sa      bh_mutex_try_lock, bh_mutex_unlock
 */
int bh_mutex_lock(bh_mutex_t *mutex);

/**
 * @brief   Try to lock mutex.
 *
 * @param   mutex   Pointer to the mutex
 *
 * @return  0 on success, positive value if mutex is locked, negative value on
 *          error
 *
 * @sa      bh_mutex_lock, bh_mutex_unlock
 */
int bh_mutex_try_lock(bh_mutex_t *mutex);

/**
 * @brief   Unlock mutex.
 *
 * @param   mutex   Pointer to the mutex
 *
 * @return  0 on success, non-zero otherwise
 *
 * @sa      bh_mutex_lock, bh_mutex_try_lock
 */
int bh_mutex_unlock(bh_mutex_t *mutex);

/**
 * @brief   Create condition variable.
 *
 * @return  Pointer to the condition variable
 */
bh_cond_t *bh_cond_new(void);

/**
 * @brief   Destroy condition variable.
 *
 * @param   cond    Pointer to the conditional variable
 */
void bh_cond_free(bh_cond_t *cond);

/**
 * @brief   Block on conditional variable.
 *
 * @param   cond    Pointer to the condition variable
 * @param   mutex   Pointer to the mutex
 *
 * @return  0 on success, non-zero otherwise
 *
 * @sa      bh_cond_wait_for, bh_cond_signal, bh_cond_broadcast
 */
int bh_cond_wait(bh_cond_t *cond,
                 bh_mutex_t *mutex);

/**
 * @brief   Block on conditional variable for a period of the time.
 *
 * @param   cond    Pointer to the conditional variable
 * @param   mutex   Pointer to the mutex
 * @param   timeout Timeout in miliseconds
 *
 * @return  0 on success, positive value on timeout, negative on error
 *
 * @sa      bh_cond_wait, bh_cond_signal, bh_cond_broadcast
 */
int bh_cond_wait_for(bh_cond_t *cond,
                     bh_mutex_t *mutex,
                     unsigned long timeout);

/**
 * @brief   Unblock (notify) thread.
 *
 * @param   cond    Pointer to the condition variable
 *
 * @return  0 on success, non-zero otherwise
 *
 * @sa      bh_cond_broadcast, bh_cond_wait, bh_cond_wait_for
 */
int bh_cond_signal(bh_cond_t *cond);

/**
 * @brief   Unblock all threads.
 *
 * @param   cond    Pointer to the conditional variable
 *
 * @return  0 on success, non-zero otherwise
 *
 * @sa      bh_cond_signal, bh_cond_wait, bh_cond_wait_for
 */
int bh_cond_broadcast(bh_cond_t *cond);

/**
 * @brief   Submit task to the thread pool.
 *
 * @param   pool    Pointer to the thread pool
 * @param   func    Task function
 * @param   data    Task data
 *
 * @return  0 on success, non-zero otherwise
 *
 * @sa      bh_thread_pool_join
 */
int bh_thread_pool_add(bh_thread_pool_t *pool,
                       bh_task_t *task);

/**
 * @brief   Wait until all tasks are finished.
 *
 * @param   pool    Pointer to the thread pool
 * @return  0 on success, non-zero otherwise
 *
 * @sa      bh_thread_pool_add
 */
int bh_thread_pool_wait(bh_thread_pool_t *pool);

/**
 * @brief   Destroy thread pool.
 *
 * @param   pool    Pointer to the thread pool
 */
void bh_thread_pool_free(bh_thread_pool_t *pool);

#endif /* BHLIB_THREAD_H */