-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy paththread.h
125 lines (99 loc) · 3.07 KB
/
thread.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// os/winapi/thread.h: Multi-threading functions and types.
//
// CEN64: Cycle-Accurate Nintendo 64 Emulator.
// Copyright (C) 2015, Tyler J. Stachecki.
//
// This file is subject to the terms and conditions defined in
// 'LICENSE', which is part of this source code package.
//
#ifndef CEN64_OS_WINAPI_THREAD
#define CEN64_OS_WINAPI_THREAD
#include "common.h"
#include <errno.h>
#include <windows.h>
#define CEN64_THREAD_RETURN_TYPE DWORD
#define CEN64_THREAD_RETURN_VAL 0
// Type definitions.
typedef HANDLE cen64_thread;
typedef DWORD (*cen64_thread_func)(LPVOID arg);
typedef HANDLE cen64_mutex;
typedef HANDLE cen64_cv;
//
// Threads.
//
// Creates a thread and starts executing 'f' within the thread.
static inline int cen64_thread_create(cen64_thread *t,
cen64_thread_func f, void *arg) {
if (likely((*t = CreateThread(NULL, 0, f, arg, 0, NULL)) != NULL))
return 0;
return 1;
}
//
// Join a thread created with cen64_thread_create. Use this to
// effectively "free" the resources acquired for the thread.
//
static inline int cen64_thread_join(cen64_thread *t) {
if (unlikely(WaitForSingleObject(*t, INFINITE) != WAIT_OBJECT_0))
return 1;
return !CloseHandle(*t);
}
// Sets the name of the thread to a specific value
// This function is API dependent and must be called either
// before starting the thread or with older Windows APIs directly after the creation.
// If you call it at the wrong time or your OS doesn't support custom thread names
// the return value will be non-zero.
// If cen64_thread is not set the name of the current thread will be changed.
//
// Windows isn't supported for the moment.
//
static inline int cen64_thread_setname(cen64_thread t, const char *name) {
return ENOSYS;
}
//
// Mutexes.
//
// Allocates resources for/initializes a mutex.
static inline int cen64_mutex_create(cen64_mutex *m) {
if (unlikely((*m = CreateMutex(NULL, FALSE, NULL)) == NULL))
return 1;
return 0;
}
// Releases resources acquired by cen64_mutex_create.
static inline int cen64_mutex_destroy(cen64_mutex *m) {
return !CloseHandle(*m);
}
// Locks the mutex passed as an argument.
static inline int cen64_mutex_lock(cen64_mutex *m) {
if (likely(WaitForSingleObject(*m, INFINITE) == WAIT_OBJECT_0))
return 0;
return 1;
}
// Unlocks the mutex passed as an argument.
static inline int cen64_mutex_unlock(cen64_mutex *m) {
return !ReleaseMutex(*m);
}
//
// Condition variables.
//
// Allocates resources for/initializes a CV.
static inline int cen64_cv_create(cen64_cv *cv) {
if (unlikely((*cv = CreateSemaphore(NULL, 0, 1, NULL)) == NULL))
return 1;
return 0;
}
// Releases resources acquired by cen64_cv_create.
static inline int cen64_cv_destroy(cen64_cv *cv) {
return !CloseHandle(*cv);
}
// Releases the mutex and waits until cen64_cv_signal is called.
static inline int cen64_cv_wait(cen64_cv *cv, cen64_mutex *m) {
if (likely(SignalObjectAndWait(*m, *cv, INFINITE, FALSE) == WAIT_OBJECT_0))
return 0;
return 1;
}
// Signals the condition variable.
static inline int cen64_cv_signal(cen64_cv *cv) {
return !ReleaseSemaphore(*cv, 1, 0);
}
#endif