SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
Windows/pthread.h
1 /* Very minimal pthread implementation for Windows */
2 #include <Windows.h>
3 #include <assert.h>
4
5 typedef HANDLE pthread_t;
6 typedef struct pthread_attr_s pthread_attr_t;
7
8 static inline int pthread_create(pthread_t *pthread,
9 const pthread_attr_t *attrs,
10 LPTHREAD_START_ROUTINE function,
11 void *context)
12 {
13 assert(!attrs);
14 *pthread = CreateThread(NULL, 0, function,
15 context, 0, NULL);
16 return *pthread? 0 : GetLastError();
17 }
18
19
20 typedef struct {
21 unsigned status;
22 CRITICAL_SECTION cs;
23 } pthread_mutex_t;
24 #define PTHREAD_MUTEX_INITIALIZER {0,}
25
26 static inline CRITICAL_SECTION *pthread_mutex_to_cs(pthread_mutex_t *mutex)
27 {
28 retry:
29 if (mutex->status == 2) return &mutex->cs;
30
31 unsigned expected = 0;
32 unsigned desired = 1;
33 if (__atomic_compare_exchange(&mutex->status, &expected, &desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) {
34 InitializeCriticalSection(&mutex->cs);
35 mutex->status = 2;
36 return &mutex->cs;
37 }
38 goto retry;
39 }
40
41 static inline int pthread_mutex_lock(pthread_mutex_t *mutex)
42 {
43 EnterCriticalSection(pthread_mutex_to_cs(mutex));
44 return 0;
45 }
46
47 static inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
48 {
49 LeaveCriticalSection(pthread_mutex_to_cs(mutex));
50 return 0;
51 }
52
53 typedef struct {
54 unsigned status;
55 CONDITION_VARIABLE cond;
56 } pthread_cond_t;
57 #define PTHREAD_COND_INITIALIZER {0,}
58
59 static inline CONDITION_VARIABLE *pthread_cond_to_win(pthread_cond_t *cond)
60 {
61 retry:
62 if (cond->status == 2) return &cond->cond;
63
64 unsigned expected = 0;
65 unsigned desired = 1;
66 if (__atomic_compare_exchange(&cond->status, &expected, &desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) {
67 InitializeConditionVariable(&cond->cond);
68 cond->status = 2;
69 return &cond->cond;
70 }
71 goto retry;
72 }
73
74
75 static inline int pthread_cond_signal(pthread_cond_t *cond)
76 {
77 WakeConditionVariable(pthread_cond_to_win(cond));
78 return 0;
79 }
80
81 static inline int pthread_cond_wait(pthread_cond_t *cond,
82 pthread_mutex_t *mutex)
83 {
84 // Mutex is locked therefore already initialized
85 return SleepConditionVariableCS(pthread_cond_to_win(cond), &mutex->cs, INFINITE);
86 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.