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
14#define THREAD_ENTRY void*
15typedef THREAD_ENTRY (*ThreadEntry)(void*);
16
17typedef pthread_t Thread;
18typedef pthread_mutex_t Mutex;
19typedef pthread_cond_t Condition;
20
21static inline int MutexInit(Mutex* mutex) {
22 return pthread_mutex_init(mutex, 0);
23}
24
25static inline int MutexDeinit(Mutex* mutex) {
26 return pthread_mutex_destroy(mutex);
27}
28
29static inline int MutexLock(Mutex* mutex) {
30 return pthread_mutex_lock(mutex);
31}
32
33static inline int MutexUnlock(Mutex* mutex) {
34 return pthread_mutex_unlock(mutex);
35}
36
37static inline int ConditionInit(Condition* cond) {
38 return pthread_cond_init(cond, 0);
39}
40
41static inline int ConditionDeinit(Condition* cond) {
42 return pthread_cond_destroy(cond);
43}
44
45static inline int ConditionWait(Condition* cond, Mutex* mutex) {
46 return pthread_cond_wait(cond, mutex);
47}
48
49static inline int ConditionWake(Condition* cond) {
50 return pthread_cond_broadcast(cond);
51}
52
53static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
54 return pthread_create(thread, 0, entry, context);
55}
56
57static inline int ThreadJoin(Thread thread) {
58 return pthread_join(thread, 0);
59}
60
61#elif _WIN32
62#define _WIN32_WINNT 0x0600
63#include <windows.h>
64#define THREAD_ENTRY DWORD WINAPI
65typedef THREAD_ENTRY ThreadEntry(LPVOID);
66
67typedef HANDLE Thread;
68typedef CRITICAL_SECTION Mutex;
69typedef CONDITION_VARIABLE Condition;
70
71static inline int MutexInit(Mutex* mutex) {
72 InitializeCriticalSection(mutex);
73 return GetLastError();
74}
75
76static inline int MutexDeinit(Mutex* mutex) {
77 DeleteCriticalSection(mutex);
78 return GetLastError();
79}
80
81static inline int MutexLock(Mutex* mutex) {
82 EnterCriticalSection(mutex);
83 return GetLastError();
84}
85
86static inline int MutexUnlock(Mutex* mutex) {
87 LeaveCriticalSection(mutex);
88 return GetLastError();
89}
90
91static inline int ConditionInit(Condition* cond) {
92 InitializeConditionVariable(cond);
93 return GetLastError();
94}
95
96static inline int ConditionDeinit(Condition* cond) {
97 // This is a no-op on Windows
98 UNUSED(cond);
99 return 0;
100}
101
102static inline int ConditionWait(Condition* cond, Mutex* mutex) {
103 SleepConditionVariableCS(cond, mutex, INFINITE);
104 return GetLastError();
105}
106
107static inline int ConditionWake(Condition* cond) {
108 WakeAllConditionVariable(cond);
109 return GetLastError();
110}
111
112static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
113 *thread = CreateThread(NULL, 0, entry, context, 0, 0);
114 return GetLastError();
115}
116
117static inline int ThreadJoin(Thread thread) {
118 DWORD error = WaitForSingleObject(thread, INFINITE);
119 if (error == WAIT_FAILED) {
120 return GetLastError();
121 }
122 return 0;
123}
124#else
125#define DISABLE_THREADING
126typedef void* Thread;
127typedef void* Mutex;
128typedef void* Condition;
129#endif
130
131#endif