From 378cfbf96708625e98280c4145d1dbdd9bb009b8 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 10 Jan 2011 01:46:16 +0000 Subject: Working semaphore implementation for OSX. git-svn-id: http://svn.drobilla.net/lad/trunk/raul@2809 a436a847-0d15-0410-975c-d299462d15a1 --- raul/Semaphore.hpp | 67 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 9 deletions(-) (limited to 'raul') diff --git a/raul/Semaphore.hpp b/raul/Semaphore.hpp index 6b7d0d7..c7b29ef 100644 --- a/raul/Semaphore.hpp +++ b/raul/Semaphore.hpp @@ -18,30 +18,56 @@ #ifndef RAUL_SEMAPHORE_HPP #define RAUL_SEMAPHORE_HPP +#ifdef __APPLE__ +#include +#include +#else #include +#endif + #include namespace Raul { -/** Trivial wrapper around POSIX semaphores (zero memory overhead). +/** Counting semaphore. * * \ingroup raul */ class Semaphore : boost::noncopyable { public: - inline Semaphore(unsigned int initial) { sem_init(&_sem, 0, initial); } + inline Semaphore(unsigned int initial) { + #ifdef __APPLE__ + MPCreateSemaphore(UINT_MAX, initial, &_sem); + #else + sem_init(&_sem, 0, initial); + #endif + } - inline ~Semaphore() { sem_destroy(&_sem); } + inline ~Semaphore() { + #ifdef __APPLE__ + MPDeleteSemaphore(_sem); + #else + sem_destroy(&_sem); + #endif + } inline void reset(unsigned int initial) { + #ifdef __APPLE__ + MPDeleteSemaphore(_sem); + MPCreateSemaphore(UINT_MAX, initial, &_sem); + #else sem_destroy(&_sem); sem_init(&_sem, 0, initial); + #endif } inline bool has_waiter() { int val; + #ifdef __APPLE__ + #else sem_getvalue(&_sem, &val); + #endif return (val <= 0); } @@ -49,16 +75,29 @@ public: * * Realtime safe. */ - inline void post() { sem_post(&_sem); } + inline void post() { + #ifdef __APPLE__ + MPSignalSemaphore(_sem); + #else + sem_post(&_sem); + #endif + } /** Wait until count is > 0, then decrement. - * - * Note that sem_wait always returns 0 in practice. It returns nonzero - * when run in GDB, so the while is necessary to allow debugging. * * Obviously not realtime safe. */ - inline void wait() { while (sem_wait(&_sem) != 0) {} } + inline void wait() { + #ifdef __APPLE__ + MPWaitOnSemaphore(_sem, kDurationForever); + #else + /* Note that sem_wait always returns 0 in practice, except in + gdb (at least), where it returns nonzero, so the while is + necessary (and is the correct/safe solution in any case). + */ + while (sem_wait(&_sem) != 0) {} + #endif + } /** Non-blocking version of wait(). * @@ -66,10 +105,20 @@ public: * * Realtime safe? */ - inline bool try_wait() { return (sem_trywait(&_sem) == 0); } + inline bool try_wait() { + #ifdef __APPLE__ + return MPWaitOnSemaphore(_sem, kDurationImmediate) == noErr; + #else + return (sem_trywait(&_sem) == 0); + #endif + } private: + #ifdef __APPLE__ + MPSemaphoreID _sem; + #else sem_t _sem; + #endif }; -- cgit v1.2.1