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
284
285
286
287
288
289
290
291
292
293
294
295
296
|
#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_semaphore_s bh_semaphore_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)
#include <windows.h>
#include <process.h>
typedef uintptr_t (__cdecl *bh_thread_begin_cb_t)(void *,
unsigned,
unsigned (__stdcall *)(void *),
void *,
unsigned,
unsigned *);
typedef void (__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);
bh_semaphore_t *bh_semaphore_new(int count);
void bh_semaphore_free(bh_semaphore_t *semaphore);
int bh_semaphore_post(bh_semaphore_t *semaphore);
int bh_semaphore_wait(bh_semaphore_t *semaphore);
int bh_semaphore_wait_for(bh_semaphore_t *semaphore,
unsigned long timeout);
int bh_semaphore_try_wait(bh_semaphore_t *semaphore);
/**
* @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 */
|