src/util/threading.h (view raw)
1/* Copyright (c) 2013-2014 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#ifndef THREADING_H
7#define THREADING_H
8
9#include "util/common.h"
10
11#ifdef USE_PTHREADS
12#include <pthread.h>
13#include <sys/time.h>
14
15#define THREAD_ENTRY void*
16typedef THREAD_ENTRY (*ThreadEntry)(void*);
17
18typedef pthread_t Thread;
19typedef pthread_mutex_t Mutex;
20typedef pthread_cond_t Condition;
21
22static inline int MutexInit(Mutex* mutex) {
23 return pthread_mutex_init(mutex, 0);
24}
25
26static inline int MutexDeinit(Mutex* mutex) {
27 return pthread_mutex_destroy(mutex);
28}
29
30static inline int MutexLock(Mutex* mutex) {
31 return pthread_mutex_lock(mutex);
32}
33
34static inline int MutexUnlock(Mutex* mutex) {
35 return pthread_mutex_unlock(mutex);
36}
37
38static inline int ConditionInit(Condition* cond) {
39 return pthread_cond_init(cond, 0);
40}
41
42static inline int ConditionDeinit(Condition* cond) {
43 return pthread_cond_destroy(cond);
44}
45
46static inline int ConditionWait(Condition* cond, Mutex* mutex) {
47 return pthread_cond_wait(cond, mutex);
48}
49
50static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
51 struct timespec ts;
52 struct timeval tv;
53
54 gettimeofday(&tv, 0);
55 ts.tv_sec = tv.tv_sec;
56 ts.tv_nsec = (tv.tv_usec + timeoutMs * 1000L) * 1000L;
57 if (ts.tv_nsec >= 1000000000L) {
58 ts.tv_nsec -= 1000000000L;
59 ++ts.tv_sec;
60 }
61
62 return pthread_cond_timedwait(cond, mutex, &ts);
63}
64
65static inline int ConditionWake(Condition* cond) {
66 return pthread_cond_broadcast(cond);
67}
68
69static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
70 return pthread_create(thread, 0, entry, context);
71}
72
73static inline int ThreadJoin(Thread thread) {
74 return pthread_join(thread, 0);
75}
76
77#elif _WIN32
78#define _WIN32_WINNT 0x0600
79#include <windows.h>
80#define THREAD_ENTRY DWORD WINAPI
81typedef THREAD_ENTRY ThreadEntry(LPVOID);
82
83typedef HANDLE Thread;
84typedef CRITICAL_SECTION Mutex;
85typedef CONDITION_VARIABLE Condition;
86
87static inline int MutexInit(Mutex* mutex) {
88 InitializeCriticalSection(mutex);
89 return GetLastError();
90}
91
92static inline int MutexDeinit(Mutex* mutex) {
93 DeleteCriticalSection(mutex);
94 return GetLastError();
95}
96
97static inline int MutexLock(Mutex* mutex) {
98 EnterCriticalSection(mutex);
99 return GetLastError();
100}
101
102static inline int MutexUnlock(Mutex* mutex) {
103 LeaveCriticalSection(mutex);
104 return GetLastError();
105}
106
107static inline int ConditionInit(Condition* cond) {
108 InitializeConditionVariable(cond);
109 return GetLastError();
110}
111
112static inline int ConditionDeinit(Condition* cond) {
113 // This is a no-op on Windows
114 UNUSED(cond);
115 return 0;
116}
117
118static inline int ConditionWait(Condition* cond, Mutex* mutex) {
119 SleepConditionVariableCS(cond, mutex, INFINITE);
120 return GetLastError();
121}
122
123static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
124 SleepConditionVariableCS(cond, mutex, timeoutMs);
125 return GetLastError();
126}
127
128static inline int ConditionWake(Condition* cond) {
129 WakeAllConditionVariable(cond);
130 return GetLastError();
131}
132
133static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
134 *thread = CreateThread(NULL, 0, entry, context, 0, 0);
135 return GetLastError();
136}
137
138static inline int ThreadJoin(Thread thread) {
139 DWORD error = WaitForSingleObject(thread, INFINITE);
140 if (error == WAIT_FAILED) {
141 return GetLastError();
142 }
143 return 0;
144}
145#else
146#define DISABLE_THREADING
147typedef void* Thread;
148typedef void* Mutex;
149typedef void* Condition;
150
151static inline int MutexInit(Mutex* mutex) {
152 UNUSED(mutex);
153 return 0;
154}
155
156static inline int MutexDeinit(Mutex* mutex) {
157 UNUSED(mutex);
158 return 0;
159}
160
161static inline int MutexLock(Mutex* mutex) {
162 UNUSED(mutex);
163 return 0;
164}
165
166static inline int MutexUnlock(Mutex* mutex) {
167 UNUSED(mutex);
168 return 0;
169}
170
171static inline int ConditionInit(Condition* cond) {
172 UNUSED(cond);
173 return 0;
174}
175
176static inline int ConditionDeinit(Condition* cond) {
177 UNUSED(cond);
178 return 0;
179}
180
181static inline int ConditionWait(Condition* cond, Mutex* mutex) {
182 UNUSED(cond);
183 UNUSED(mutex);
184 return 0;
185}
186
187static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
188 UNUSED(cond);
189 UNUSED(mutex);
190 UNUSED(timeoutMs);
191 return 0;
192}
193
194static inline int ConditionWake(Condition* cond) {
195 UNUSED(cond);
196 return 0;
197}
198#endif
199
200#endif