1 #ifndef R2_TH_H
2 #define R2_TH_H
3 
4 #ifdef _GNU_SOURCE
5 #undef _GNU_SOURCE
6 #endif
7 #define _GNU_SOURCE
8 #include "r_types.h"
9 
10 #define HAVE_PTHREAD 1
11 
12 #if __WINDOWS__
13 #undef HAVE_PTHREAD
14 #define HAVE_PTHREAD 0
15 #define R_TH_TID HANDLE
16 #define R_TH_LOCK_T CRITICAL_SECTION
17 #define R_TH_COND_T CONDITION_VARIABLE
18 #define R_TH_SEM_T HANDLE
19 //HANDLE
20 
21 #elif HAVE_PTHREAD
22 #define __GNU
23 #include <semaphore.h>
24 #include <pthread.h>
25 #if __linux__
26 #include <sched.h>
27 #endif
28 #if __linux__ && __GLIBC_MINOR < 12
29 #define HAVE_PTHREAD_NP 0
30 #else
31 #define HAVE_PTHREAD_NP 1
32 #endif
33 #if __APPLE__
34 #include <pthread.h>
35 #endif
36 #if __FreeBSD__ || __OpenBSD__ || __DragonFly__
37 #if __FreeBSD__
38 #include <sys/cpuset.h>
39 #endif
40 #include <pthread_np.h>
41 #endif
42 #define R_TH_TID pthread_t
43 #define R_TH_LOCK_T pthread_mutex_t
44 #define R_TH_COND_T pthread_cond_t
45 #define R_TH_SEM_T sem_t *
46 
47 #else
48 #error Threading library only supported for pthread and w32
49 #endif
50 
51 typedef enum { R_TH_FREED = -1, R_TH_STOP = 0, R_TH_REPEAT = 1 } RThreadFunctionRet;
52 #define R_TH_FUNCTION(x) RThreadFunctionRet (*x)(struct r_th_t *)
53 
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 typedef struct r_th_sem_t {
59 	R_TH_SEM_T sem;
60 } RThreadSemaphore;
61 
62 typedef struct r_th_lock_t {
63 	R_TH_LOCK_T lock;
64 } RThreadLock;
65 
66 typedef struct r_th_cond_t {
67 	R_TH_COND_T cond;
68 } RThreadCond;
69 
70 typedef struct r_th_t {
71 	R_TH_TID tid;
72 	RThreadLock *lock;
73 	R_TH_FUNCTION(fun);
74 	void *user;    // user pointer
75 	int running;
76 	int breaked;   // thread aims to be interrupted
77 	int delay;     // delay the startup of the thread N seconds
78 	int ready;     // thread is properly setup
79 } RThread;
80 
81 typedef struct r_th_pool_t {
82 	int size;
83 	RThread **threads;
84 } RThreadPool;
85 
86 #ifdef R_API
87 R_API RThread *r_th_new(R_TH_FUNCTION(fun), void *user, int delay);
88 R_API bool r_th_start(RThread *th, int enable);
89 R_API int r_th_wait(RThread *th);
90 R_API int r_th_wait_async(RThread *th);
91 R_API void r_th_break(RThread *th);
92 R_API void *r_th_free(RThread *th);
93 R_API void *r_th_kill_free(RThread *th);
94 R_API bool r_th_kill(RThread *th, bool force);
95 R_API R_TH_TID r_th_self(void);
96 R_API bool r_th_setname(RThread *th, const char *name);
97 R_API bool r_th_getname(RThread *th, char *name, size_t len);
98 R_API bool r_th_setaffinity(RThread *th, int cpuid);
99 
100 R_API RThreadSemaphore *r_th_sem_new(unsigned int initial);
101 R_API void r_th_sem_free(RThreadSemaphore *sem);
102 R_API void r_th_sem_post(RThreadSemaphore *sem);
103 R_API void r_th_sem_wait(RThreadSemaphore *sem);
104 
105 R_API RThreadLock *r_th_lock_new(bool recursive);
106 R_API int r_th_lock_wait(RThreadLock *th);
107 R_API int r_th_lock_tryenter(RThreadLock *thl);
108 R_API int r_th_lock_enter(RThreadLock *thl);
109 R_API int r_th_lock_leave(RThreadLock *thl);
110 R_API void *r_th_lock_free(RThreadLock *thl);
111 
112 R_API RThreadCond *r_th_cond_new(void);
113 R_API void r_th_cond_signal(RThreadCond *cond);
114 R_API void r_th_cond_signal_all(RThreadCond *cond);
115 R_API void r_th_cond_wait(RThreadCond *cond, RThreadLock *lock);
116 R_API void r_th_cond_free(RThreadCond *cond);
117 
118 #endif
119 
120 #ifdef __cplusplus
121 }
122 #endif
123 
124 #endif
125