all repos — mgba @ 41b591e501790dcf88d7c533fe1109300eb3c984

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#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