11
11
12
12
#ifdef _WIN64
13
13
#include < windows.h>
14
+ #elif defined(__APPLE__)
15
+ #include < dispatch/dispatch.h>
14
16
#else
15
17
#include < semaphore>
16
18
#endif
@@ -21,25 +23,32 @@ template <s64 max>
21
23
class Semaphore {
22
24
public:
23
25
Semaphore (s32 initialCount)
24
- #ifndef _WIN64
26
+ #if !defined( _WIN64) && !defined(__APPLE__)
25
27
: sem{initialCount}
26
28
#endif
27
29
{
28
30
#ifdef _WIN64
29
31
sem = CreateSemaphore (nullptr , initialCount, max, nullptr );
30
32
ASSERT (sem);
33
+ #elif defined(__APPLE__)
34
+ sem = dispatch_semaphore_create (initialCount);
35
+ ASSERT (sem);
31
36
#endif
32
37
}
33
38
34
39
~Semaphore () {
35
40
#ifdef _WIN64
36
41
CloseHandle (sem);
42
+ #elif defined(__APPLE__)
43
+ dispatch_release (sem);
37
44
#endif
38
45
}
39
46
40
47
void release () {
41
48
#ifdef _WIN64
42
49
ReleaseSemaphore (sem, 1 , nullptr );
50
+ #elif defined(__APPLE__)
51
+ dispatch_semaphore_signal (sem);
43
52
#else
44
53
sem.release ();
45
54
#endif
@@ -53,6 +62,13 @@ class Semaphore {
53
62
return ;
54
63
}
55
64
}
65
+ #elif defined(__APPLE__)
66
+ for (;;) {
67
+ const auto res = dispatch_semaphore_wait (sem, DISPATCH_TIME_FOREVER);
68
+ if (res == 0 ) {
69
+ return ;
70
+ }
71
+ }
56
72
#else
57
73
sem.acquire ();
58
74
#endif
@@ -61,6 +77,8 @@ class Semaphore {
61
77
bool try_acquire () {
62
78
#ifdef _WIN64
63
79
return WaitForSingleObjectEx (sem, 0 , true ) == WAIT_OBJECT_0;
80
+ #elif defined(__APPLE__)
81
+ return dispatch_semaphore_wait (sem, DISPATCH_TIME_NOW) == 0 ;
64
82
#else
65
83
return sem.try_acquire ();
66
84
#endif
@@ -77,6 +95,10 @@ class Semaphore {
77
95
}
78
96
79
97
return WaitForSingleObjectEx (sem, timeout_ms, true ) == WAIT_OBJECT_0;
98
+ #elif defined(__APPLE__)
99
+ const auto rel_time_ns = std::chrono::ceil<std::chrono::nanoseconds>(rel_time).count ();
100
+ const auto timeout = dispatch_time (DISPATCH_TIME_NOW, rel_time_ns);
101
+ return dispatch_semaphore_wait (sem, timeout) == 0 ;
80
102
#else
81
103
return sem.try_acquire_for (rel_time);
82
104
#endif
@@ -98,6 +120,16 @@ class Semaphore {
98
120
99
121
u64 res = WaitForSingleObjectEx (sem, static_cast <u64 >(timeout_ms), true );
100
122
return res == WAIT_OBJECT_0;
123
+ #elif defined(__APPLE__)
124
+ auto abs_s = std::chrono::time_point_cast<std::chrono::seconds>(abs_time);
125
+ auto abs_ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(abs_time) -
126
+ std::chrono::time_point_cast<std::chrono::nanoseconds>(abs_s);
127
+ const timespec abs_timespec = {
128
+ .tv_sec = abs_s.time_since_epoch ().count (),
129
+ .tv_nsec = abs_ns.count (),
130
+ };
131
+ const auto timeout = dispatch_walltime (&abs_timespec, 0 );
132
+ return dispatch_semaphore_wait (sem, timeout) == 0 ;
101
133
#else
102
134
return sem.try_acquire_until (abs_time);
103
135
#endif
@@ -106,6 +138,8 @@ class Semaphore {
106
138
private:
107
139
#ifdef _WIN64
108
140
HANDLE sem;
141
+ #elif defined(__APPLE__)
142
+ dispatch_semaphore_t sem;
109
143
#else
110
144
std::counting_semaphore<max> sem;
111
145
#endif
0 commit comments