diff --git src/tbb/semaphore.h src/tbb/semaphore.h index 9d27f3ac..b8942329 100644 --- src/tbb/semaphore.h +++ src/tbb/semaphore.h @@ -22,8 +22,16 @@ #if _WIN32||_WIN64 #include #elif __APPLE__ +#include +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && !defined(__ppc__) #include #else +#include +#include +#include +#include +#endif +#else #include #ifdef TBB_USE_DEBUG #include @@ -144,6 +152,7 @@ private: }; #elif __APPLE__ //! Edsger Dijkstra's counting semaphore +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && !defined(__ppc__) class semaphore : no_copy { public: //! ctor @@ -160,6 +169,34 @@ public: private: dispatch_semaphore_t my_sem; }; +#else +class semaphore : no_copy { +public: + //! ctor + semaphore(int start_cnt_ = 0) : sem(start_cnt_) { init_semaphore(start_cnt_); } + //! dtor + ~semaphore() { + kern_return_t ret = semaphore_destroy( mach_task_self(), sem ); + __TBB_ASSERT_EX( ret==err_none, nullptr); + } + //! wait/acquire + void P() { + int ret; + do { + ret = semaphore_wait( sem ); + } while( ret==KERN_ABORTED ); + __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" ); + } + //! post/release + void V() { semaphore_signal( sem ); } +private: + semaphore_t sem; + void init_semaphore(int start_cnt_) { + kern_return_t ret = semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, start_cnt_ ); + __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" ); + } +}; +#endif /* __APPLE__ */ #else /* Linux/Unix */ typedef uint32_t sem_count_t; //! Edsger Dijkstra's counting semaphore @@ -231,7 +268,35 @@ private: #endif /* !__TBB_USE_SRWLOCK */ #elif __APPLE__ //! binary_semaphore for concurrent monitor +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && !defined(__ppc__) using binary_semaphore = semaphore; +#else +class binary_semaphore : no_copy { +public: + //! ctor + binary_semaphore() : my_sem(0) { + kern_return_t ret = semaphore_create( mach_task_self(), &my_sem, SYNC_POLICY_FIFO, 0 ); + __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" ); + } + //! dtor + ~binary_semaphore() { + kern_return_t ret = semaphore_destroy( mach_task_self(), my_sem ); + __TBB_ASSERT_EX( ret==err_none, nullptr); + } + //! wait/acquire + void P() { + int ret; + do { + ret = semaphore_wait( my_sem ); + } while( ret==KERN_ABORTED ); + __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" ); + } + //! post/release + void V() { semaphore_signal( my_sem ); } +private: + semaphore_t my_sem; +}; +#endif /* __APPLE__ */ #else /* Linux/Unix */ #if __TBB_USE_FUTEX