all repos — mgba @ 910ff621b32c461a6210aca06f94f38de95b76b3

mGBA Game Boy Advance Emulator

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