24 #define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
27 typedef pthread_t thrd_t;
28 typedef pthread_mutex_t mtx_t;
29 typedef pthread_cond_t cnd_t;
30 typedef pthread_key_t tss_t;
31 typedef pthread_once_t once_flag;
33 typedef int (*thrd_start_t)(
void*);
34 typedef void (*tss_dtor_t)(
void*);
59 static inline int thrd_create(thrd_t *thr, thrd_start_t func,
void *arg)
64 return pthread_create(thr, 0, (
void*(*)(
void*))func, arg) == 0 ? thrd_success : thrd_error;
67 static inline void thrd_exit(
int res)
69 pthread_exit((
void*)(
long)res);
72 static inline int thrd_join(thrd_t thr,
int *res)
76 if(pthread_join(thr, &retval) != 0) {
85 static inline int thrd_detach(thrd_t thr)
87 return pthread_detach(thr) == 0 ? thrd_success : thrd_error;
90 static inline thrd_t thrd_current(
void)
92 return pthread_self();
95 static inline int thrd_equal(thrd_t a, thrd_t b)
97 return pthread_equal(a, b);
100 static inline void thrd_sleep(
const xtime *xt)
104 ts.tv_sec = (long)xt->sec;
105 ts.tv_nsec = xt->nsec;
109 res = nanosleep(&ts, &rem);
111 }
while(res == -1 && errno == EINTR);
114 static inline void thrd_yield(
void)
121 static inline int mtx_init(mtx_t *mtx,
int type)
124 pthread_mutexattr_t attr;
126 pthread_mutexattr_init(&attr);
130 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
133 if(type & mtx_timed) {
134 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_TIMED_NP);
137 if(type & mtx_recursive) {
138 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
141 res = pthread_mutex_init(mtx, &attr) == 0 ? thrd_success : thrd_error;
142 pthread_mutexattr_destroy(&attr);
146 static inline void mtx_destroy(mtx_t *mtx)
148 pthread_mutex_destroy(mtx);
151 static inline int mtx_lock(mtx_t *mtx)
153 int res = pthread_mutex_lock(mtx);
157 return res == 0 ? thrd_success : thrd_error;
160 static inline int mtx_trylock(mtx_t *mtx)
162 int res = pthread_mutex_trylock(mtx);
166 return res == 0 ? thrd_success : thrd_error;
169 static inline int mtx_timedlock(mtx_t *mtx,
const xtime *xt)
174 ts.tv_sec = (long)xt->sec;
175 ts.tv_nsec = xt->nsec;
177 if((res = pthread_mutex_timedlock(mtx, &ts)) == EBUSY) {
180 return res == 0 ? thrd_success : thrd_error;
183 static inline int mtx_unlock(mtx_t *mtx)
185 return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;
190 static inline int cnd_init(cnd_t *cond)
192 return pthread_cond_init(cond, 0) == 0 ? thrd_success : thrd_error;
195 static inline void cnd_destroy(cnd_t *cond)
197 pthread_cond_destroy(cond);
200 static inline int cnd_signal(cnd_t *cond)
202 return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
205 static inline int cnd_broadcast(cnd_t *cond)
207 return pthread_cond_broadcast(cond) == 0 ? thrd_success : thrd_error;
210 static inline int cnd_wait(cnd_t *cond, mtx_t *mtx)
212 return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
215 static inline int cnd_timedwait(cnd_t *cond, mtx_t *mtx,
const xtime *xt)
220 ts.tv_sec = (long)xt->sec;
221 ts.tv_nsec = xt->nsec;
223 if((res = pthread_cond_timedwait(cond, mtx, &ts)) != 0) {
224 return res == ETIMEDOUT ? thrd_busy : thrd_error;
231 static inline int tss_create(tss_t *key, tss_dtor_t dtor)
233 return pthread_key_create(key, dtor) == 0 ? thrd_success : thrd_error;
236 static inline void tss_delete(tss_t key)
238 pthread_key_delete(key);
241 static inline int tss_set(tss_t key,
void *val)
243 return pthread_setspecific(key, val) == 0 ? thrd_success : thrd_error;
246 static inline void *tss_get(tss_t key)
248 return pthread_getspecific(key);
253 static inline void call_once(once_flag *flag,
void (*func)(
void))
255 pthread_once(flag, func);
259 static inline int xtime_get(
xtime *xt,
int base)
263 gettimeofday(&tv, 0);
266 xt->nsec = tv.tv_usec * 1000;