Properly check for struct timespec
[openal-soft.git] / include / threads.h
blobc2848ee77318cf099cd96d7f55920155e27a5509
1 #ifndef AL_THREADS_H
2 #define AL_THREADS_H
4 #include <time.h>
6 #ifdef __cplusplus
7 extern "C" {
8 #endif
10 enum {
11 althrd_success = 0,
12 althrd_error,
13 althrd_nomem,
14 althrd_timedout,
15 althrd_busy
18 enum {
19 almtx_plain = 0,
20 almtx_recursive = 1,
21 almtx_timed = 2
24 typedef int (*althrd_start_t)(void*);
25 typedef void (*altss_dtor_t)(void*);
28 #define AL_TIME_UTC 1
31 #ifdef _WIN32
32 #define WIN32_LEAN_AND_MEAN
33 #include <windows.h>
36 #ifndef HAVE_STRUCT_TIMESPEC
37 struct timespec {
38 time_t tv_sec;
39 long tv_nsec;
41 #endif
43 typedef DWORD althrd_t;
44 typedef CRITICAL_SECTION almtx_t;
45 #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
46 typedef CONDITION_VARIABLE alcnd_t;
47 #else
48 typedef struct { void *Ptr; } alcnd_t;
49 #endif
50 typedef DWORD altss_t;
51 typedef LONG alonce_flag;
53 #define AL_ONCE_FLAG_INIT 0
55 int althrd_sleep(const struct timespec *ts, struct timespec *rem);
56 void alcall_once(alonce_flag *once, void (*callback)(void));
59 inline althrd_t althrd_current(void)
61 return GetCurrentThreadId();
64 inline int althrd_equal(althrd_t thr0, althrd_t thr1)
66 return thr0 == thr1;
69 inline void althrd_exit(int res)
71 ExitThread(res);
74 inline void althrd_yield(void)
76 SwitchToThread();
80 inline int almtx_lock(almtx_t *mtx)
82 if(!mtx) return althrd_error;
83 EnterCriticalSection(mtx);
84 return althrd_success;
87 inline int almtx_unlock(almtx_t *mtx)
89 if(!mtx) return althrd_error;
90 LeaveCriticalSection(mtx);
91 return althrd_success;
94 inline int almtx_trylock(almtx_t *mtx)
96 if(!mtx) return althrd_error;
97 if(!TryEnterCriticalSection(mtx))
98 return althrd_busy;
99 return althrd_success;
103 inline void *altss_get(altss_t tss_id)
105 return TlsGetValue(tss_id);
108 inline int altss_set(altss_t tss_id, void *val)
110 if(TlsSetValue(tss_id, val) == 0)
111 return althrd_error;
112 return althrd_success;
115 #else
117 #include <stdint.h>
118 #include <errno.h>
119 #include <pthread.h>
122 typedef pthread_t althrd_t;
123 typedef pthread_mutex_t almtx_t;
124 typedef pthread_cond_t alcnd_t;
125 typedef pthread_key_t altss_t;
126 typedef pthread_once_t alonce_flag;
128 #define AL_ONCE_FLAG_INIT PTHREAD_ONCE_INIT
131 inline althrd_t althrd_current(void)
133 return pthread_self();
136 inline int althrd_equal(althrd_t thr0, althrd_t thr1)
138 return pthread_equal(thr0, thr1);
141 inline void althrd_exit(int res)
143 pthread_exit((void*)(intptr_t)res);
146 inline void althrd_yield(void)
148 sched_yield();
151 inline int althrd_sleep(const struct timespec *ts, struct timespec *rem)
153 int ret = nanosleep(ts, rem);
154 if(ret != 0)
156 ret = ((errno==EINTR) ? -1 : -2);
157 errno = 0;
159 return ret;
163 inline int almtx_lock(almtx_t *mtx)
165 if(pthread_mutex_lock(mtx) != 0)
166 return althrd_error;
167 return althrd_success;
170 inline int almtx_unlock(almtx_t *mtx)
172 if(pthread_mutex_unlock(mtx) != 0)
173 return althrd_error;
174 return althrd_success;
177 inline int almtx_trylock(almtx_t *mtx)
179 int ret = pthread_mutex_trylock(mtx);
180 switch(ret)
182 case 0: return althrd_success;
183 case EBUSY: return althrd_busy;
185 return althrd_error;
189 inline void *altss_get(altss_t tss_id)
191 return pthread_getspecific(tss_id);
194 inline int altss_set(altss_t tss_id, void *val)
196 if(pthread_setspecific(tss_id, val) != 0)
197 return althrd_error;
198 return althrd_success;
202 inline void alcall_once(alonce_flag *once, void (*callback)(void))
204 pthread_once(once, callback);
207 #endif
210 int althrd_create(althrd_t *thr, althrd_start_t func, void *arg);
211 int althrd_detach(althrd_t thr);
212 int althrd_join(althrd_t thr, int *res);
213 void althrd_setname(althrd_t thr, const char *name);
215 int almtx_init(almtx_t *mtx, int type);
216 void almtx_destroy(almtx_t *mtx);
217 int almtx_timedlock(almtx_t *mtx, const struct timespec *ts);
219 int alcnd_init(alcnd_t *cond);
220 int alcnd_signal(alcnd_t *cond);
221 int alcnd_broadcast(alcnd_t *cond);
222 int alcnd_wait(alcnd_t *cond, almtx_t *mtx);
223 int alcnd_timedwait(alcnd_t *cond, almtx_t *mtx, const struct timespec *time_point);
224 void alcnd_destroy(alcnd_t *cond);
226 int altss_create(altss_t *tss_id, altss_dtor_t callback);
227 void altss_delete(altss_t tss_id);
229 int altimespec_get(struct timespec *ts, int base);
231 void al_nssleep(unsigned long nsec);
233 #ifdef __cplusplus
235 #endif
237 #endif /* AL_THREADS_H */