-
Notifications
You must be signed in to change notification settings - Fork 2
/
thread.h
121 lines (103 loc) · 3.95 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
#ifndef _H_THREAD
#define _H_THREAD
#include <stdlib.h> //for NULL
//////////////////////////////////////////////////////////////////////
// NOTES
//
// Windows Vista and later has almost one-to-one compatibility with pthreads.
// Here I provide a wrapper to give the functionality provided by both
// libraries a common interface. I try to follow the pthread symantics when
// possible. Below are some exceptions:
//
// Thread_Alloc() and Thread_Free()
//
// - need alloc/free symantics because of how windows allocates
// threads.
//
// Thread_Exit(unsigned)
//
// - windows threads return a DWORD that is usually interpreted as an exit
// code. Pthreads return a void* that may point to the result of some
// computation. The pthread convention is maintained by Thread_Join().
// That is, threads return a (void*).
//
// Thread_Exit causes a thread to immediately abort. There's no real
// isomorphism between pthread and windows here. The return type
// of a windows thread isn't wide enough to use as a pointer on 64-bit
// systems. As a result, it doesn't get used for Thread_Join().
//
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// CONFIG
//////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
#define USE_WIN32_THREADS
#else
#define USE_PTHREAD
#endif
#ifdef __cplusplus
extern "C"{
#endif
#ifdef USE_PTHREAD
#include <pthread.h>
typedef pthread_t native_thread_t;
typedef pthread_t native_thread_id_t;
typedef pthread_mutex_t native_mutex_t;
typedef pthread_cond_t native_cond_t;
#define MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,PTHREAD_MUTEX_INITIALIZER,0}
#define CONDITION_INITIALIZER PTHREAD_COND_INITIALIZER
#endif //USE_PTHREAD
#ifdef USE_WIN32_THREADS
#ifndef RTL_CONDITION_VARIABLE_INIT
#define RTL_CONDITION_VARIABLE_INIT {0}
#endif
#define MUTEX_INITIALIZER {0,0,0}
#define CONDITION_INITIALIZER RTL_CONDITION_VARIABLE_INIT
//#include <windows.h> // can't do this bc windows defines UINT8 etc... these collide with mylib names
// so we fake it
typedef void* _HANDLE;
typedef unsigned _DWORD;
typedef void* _SRWLOCK;
typedef struct{void* Ptr;} _CONDITION_VARIABLE;
typedef _HANDLE native_thread_t;
typedef _DWORD native_thread_id_t;
typedef _SRWLOCK native_mutex_t;
typedef _CONDITION_VARIABLE native_cond_t;
#endif //USE_WIN32_THREADS
typedef struct _mutex_t
{ native_mutex_t lock;
native_mutex_t self_lock;
native_thread_id_t owner;
int is_owned;
} Mutex;
typedef void Thread;
typedef native_cond_t Condition;
extern const Mutex MUTEX_INITIALIZER_INSTANCE;
extern const Condition CONDITION_INITIALIZER_INSTANCE;
//Prefer pthread-style thread proc specification
typedef void* (*ThreadProc)(void*);
typedef void* ThreadProcArg;
typedef void* ThreadProcRet;
Thread* Thread_Alloc ( ThreadProc function, ThreadProcArg arg);
void Thread_Free ( Thread* self);
void* Thread_Join ( Thread* self);
void Thread_Exit ( unsigned exitcode);
void Thread_Self ( Thread* out );
extern int Thread_Equal ( native_thread_id_t a, native_thread_id_t b);
extern native_thread_id_t Thread_SelfID ( );
Mutex* Mutex_Alloc ( );
void Mutex_Free ( Mutex* self);
void Mutex_Lock ( Mutex* self);
// TODO:? int Mutex_Try_Lock(Mutex* self);
void Mutex_Unlock( Mutex* self);
Condition* Condition_Alloc ( );
void Condition_Initialize( Condition* self);
void Condition_Free ( Condition* self);
void Condition_Wait ( Condition* self, Mutex* lock);
int Condition_Timed_Wait( Condition* self, Mutex* lock, unsigned timeout_ms);
void Condition_Notify ( Condition* self);
void Condition_Notify_All( Condition* self);
#ifdef __cplusplus
}
#endif
#endif //#ifndef _H_THREAD