21 #if defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC)
22 #include <mach/mach_init.h>
23 #include <mach/task.h>
25 #elif defined(ION_PLATFORM_ASMJS)
27 #elif !defined(ION_PLATFORM_WINDOWS)
37 #if defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC)
38 semaphore_ = dispatch_semaphore_create(0);
39 #elif defined(ION_PLATFORM_WINDOWS)
40 semaphore_ = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
43 #elif defined(ION_PLATFORM_ASMJS)
46 sem_init(&semaphore_, 0, 0);
51 #if defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC)
52 semaphore_ = dispatch_semaphore_create(0);
55 while (initial_value--)
57 #elif defined(ION_PLATFORM_WINDOWS)
58 semaphore_ = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
62 value_.store(initial_value);
63 #elif defined(ION_PLATFORM_ASMJS)
64 value_ = initial_value;
69 sem_init(&semaphore_, 0, initial_value);
74 #if defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC)
75 #elif defined(ION_PLATFORM_WINDOWS)
77 CloseHandle(semaphore_);
78 #elif defined(ION_PLATFORM_ASMJS)
81 sem_destroy(&semaphore_);
86 #if defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC)
89 ? (dispatch_semaphore_signal(semaphore_) ||
true)
91 #elif defined(ION_PLATFORM_WINDOWS)
97 return ReleaseSemaphore(semaphore_, 1, NULL) != 0;
99 #elif defined(ION_PLATFORM_ASMJS)
103 return sem_post(&semaphore_) == 0;
108 #if defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC)
111 ? (0 == dispatch_semaphore_wait(semaphore_, DISPATCH_TIME_NOW))
113 #elif defined(ION_PLATFORM_WINDOWS)
114 int val = value_.load(std::memory_order_acquire);
123 if (value_.compare_exchange_weak(val, val - 1,
124 std::memory_order_acq_rel,
125 std::memory_order_acquire)) {
131 #elif defined(ION_PLATFORM_ASMJS)
139 return sem_trywait(&semaphore_) == 0;
144 if (timeout_in_ms < 0)
147 #if defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC)
148 static const int64 kMsecToNsec = 1000000;
150 const dispatch_time_t deadline = dispatch_time(DISPATCH_TIME_NOW,
151 timeout_in_ms * kMsecToNsec);
154 ? (0 == dispatch_semaphore_wait(semaphore_, deadline))
156 #elif defined(ION_PLATFORM_WINDOWS)
162 if (WaitForSingleObject(semaphore_, timeout_in_ms) == WAIT_OBJECT_0) {
170 #elif defined(ION_PLATFORM_ASMJS)
174 static const int64 kMsecToNsec = 1000000;
175 static const int64 kNsecPerSec = 1000000000;
179 ::gettimeofday(&now, NULL);
181 const uint64 timeout_in_ns = now.tv_usec * 1000 + timeout_in_ms * kMsecToNsec;
185 timeout.tv_nsec =
static_cast<int32
>(timeout_in_ns % kNsecPerSec);
186 timeout.tv_sec =
static_cast<int32
>(now.tv_sec + timeout_in_ns / kNsecPerSec);
187 #if !defined(ION_PLATFORM_PNACL) && !defined(ION_PLATFORM_NACL)
188 return sem_timedwait(&semaphore_, &timeout) == 0;
193 ::gettimeofday(&now, NULL);
194 if (now.tv_sec > timeout.tv_sec ||
195 (now.tv_sec == timeout.tv_sec &&
196 now.tv_usec * 1000 > timeout.tv_nsec)) {
206 #if defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC)
209 ? (dispatch_semaphore_wait(semaphore_, DISPATCH_TIME_FOREVER) ||
true)
211 #elif defined(ION_PLATFORM_WINDOWS)
214 while (spin_count--) {
226 if (WaitForSingleObject(semaphore_, INFINITE) == WAIT_OBJECT_0) {
235 #elif defined(ION_PLATFORM_ASMJS)
241 "Semaphore::Wait cannot block on a platform without threads.");
245 return sem_wait(&semaphore_) == 0;
bool Post()
Wakes a single thread that is Wait()ing, or the next thread to call Wait().
bool Wait()
Blocks the calling thread until another thread calls Post().
void YieldThread()
Causes the calling thread to relinquish the CPU if there are other threads waiting to execute...
bool TimedWaitMs(int64 timeout_in_ms)
Blocks for a maximum of the passed number of milliseconds before returning.
Semaphore()
Initializes a semaphore with an internal value of zero.
bool TryWait()
Does not block.