25 #ifndef __CPP11OM_SEMAPHORE_H__
26 #define __CPP11OM_SEMAPHORE_H__
46 Semaphore(
const Semaphore& other) =
delete;
47 Semaphore& operator=(
const Semaphore& other) =
delete;
50 Semaphore(
int initialCount = 0)
52 assert(initialCount >= 0);
53 m_hSema = CreateSemaphore(NULL, initialCount, MAXLONG, NULL);
63 WaitForSingleObject(m_hSema, INFINITE);
66 void signal(
int count = 1)
68 ReleaseSemaphore(m_hSema, count, NULL);
73 #elif defined(__MACH__)
79 #include <mach/mach.h>
86 Semaphore(
const Semaphore& other) =
delete;
87 Semaphore& operator=(
const Semaphore& other) =
delete;
90 Semaphore(
int initialCount = 0)
92 assert(initialCount >= 0);
93 semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
98 semaphore_destroy(mach_task_self(), m_sema);
103 semaphore_wait(m_sema);
108 semaphore_signal(m_sema);
111 void signal(
int count)
115 semaphore_signal(m_sema);
121 #elif defined(__unix__)
126 #include <semaphore.h>
133 Semaphore(
const Semaphore& other) =
delete;
134 Semaphore& operator=(
const Semaphore& other) =
delete;
137 Semaphore(
int initialCount = 0)
139 assert(initialCount >= 0);
140 sem_init(&m_sema, 0, initialCount);
145 sem_destroy(&m_sema);
154 rc = sem_wait(&m_sema);
156 while (rc == -1 && errno == EINTR);
164 void signal(
int count)
176 #error Unsupported platform!
187 std::atomic<int> m_count;
190 void waitWithPartialSpinning()
199 oldCount = m_count.load(std::memory_order_relaxed);
200 if ((oldCount > 0) && m_count.compare_exchange_strong(oldCount, oldCount - 1, std::memory_order_acquire))
202 std::atomic_signal_fence(std::memory_order_acquire);
204 oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
214 assert(initialCount >= 0);
219 int oldCount = m_count.load(std::memory_order_relaxed);
220 return (oldCount > 0 && m_count.compare_exchange_strong(oldCount, oldCount - 1, std::memory_order_acquire));
226 waitWithPartialSpinning();
231 int oldCount = m_count.fetch_add(count, std::memory_order_release);
232 int toRelease = -oldCount < count ? -oldCount : count;
235 m_sema.signal(toRelease);
248 #endif // __CPP11OM_SEMAPHORE_H__