diff options
Diffstat (limited to '3rdparty/bx/src/semaphore.cpp')
-rw-r--r-- | 3rdparty/bx/src/semaphore.cpp | 187 |
1 files changed, 79 insertions, 108 deletions
diff --git a/3rdparty/bx/src/semaphore.cpp b/3rdparty/bx/src/semaphore.cpp index b4369ff0ce6..f321240be18 100644 --- a/3rdparty/bx/src/semaphore.cpp +++ b/3rdparty/bx/src/semaphore.cpp @@ -3,18 +3,21 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ +#include "bx_p.h" #include <bx/semaphore.h> #if BX_CONFIG_SUPPORTS_THREADING -#if BX_PLATFORM_POSIX +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS +# include <dispatch/dispatch.h> +#elif BX_PLATFORM_POSIX # include <errno.h> # include <pthread.h> # include <semaphore.h> # include <time.h> #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE # include <windows.h> # include <limits.h> @@ -23,36 +26,87 @@ # endif // BX_PLATFORM_XBOXONE #endif // BX_PLATFORM_ -#ifndef BX_CONFIG_SEMAPHORE_PTHREAD -# define BX_CONFIG_SEMAPHORE_PTHREAD (0 \ - || BX_PLATFORM_OSX \ - || BX_PLATFORM_IOS \ - ) -#endif // BX_CONFIG_SEMAPHORE_PTHREAD - namespace bx { struct SemaphoreInternal { -#if BX_PLATFORM_POSIX -# if BX_CONFIG_SEMAPHORE_PTHREAD +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS + dispatch_semaphore_t m_handle; +#elif BX_PLATFORM_POSIX pthread_mutex_t m_mutex; pthread_cond_t m_cond; int32_t m_count; -# else - sem_t m_handle; -# endif // BX_CONFIG_SEMAPHORE_PTHREAD #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE HANDLE m_handle; #endif // BX_PLATFORM_ }; -#if BX_PLATFORM_POSIX +#if BX_PLATFORM_OSX \ +|| BX_PLATFORM_IOS + + Semaphore::Semaphore() + { + BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); + + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + si->m_handle = dispatch_semaphore_create(0); + BX_CHECK(NULL != si->m_handle, "dispatch_semaphore_create failed."); + } + + Semaphore::~Semaphore() + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + dispatch_release(si->m_handle); + } + + void Semaphore::post(uint32_t _count) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + for (uint32_t ii = 0; ii < _count; ++ii) + { + dispatch_semaphore_signal(si->m_handle); + } + } + + bool Semaphore::wait(int32_t _msecs) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + dispatch_time_t dt = 0 > _msecs + ? DISPATCH_TIME_FOREVER + : dispatch_time(DISPATCH_TIME_NOW, _msecs*1000000) + ; + return !dispatch_semaphore_wait(si->m_handle, dt); + } + +#elif BX_PLATFORM_POSIX + + uint64_t toNs(const timespec& _ts) + { + return _ts.tv_sec*UINT64_C(1000000000) + _ts.tv_nsec; + } + + void toTimespecNs(timespec& _ts, uint64_t _nsecs) + { + _ts.tv_sec = _nsecs/UINT64_C(1000000000); + _ts.tv_nsec = _nsecs%UINT64_C(1000000000); + } + + void toTimespecMs(timespec& _ts, int32_t _msecs) + { + toTimespecNs(_ts, _msecs*1000000); + } + + void add(timespec& _ts, int32_t _msecs) + { + uint64_t ns = toNs(_ts); + toTimespecNs(_ts, ns + _msecs*1000000); + } -# if BX_CONFIG_SEMAPHORE_PTHREAD Semaphore::Semaphore() { BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); @@ -113,15 +167,6 @@ namespace bx int result = pthread_mutex_lock(&si->m_mutex); BX_CHECK(0 == result, "pthread_mutex_lock %d", result); -# if BX_PLATFORM_NACL || BX_PLATFORM_OSX - BX_UNUSED(_msecs); - BX_CHECK(-1 == _msecs, "NaCl and OSX don't support pthread_cond_timedwait at this moment."); - while (0 == result - && 0 >= si->m_count) - { - result = pthread_cond_wait(&si->m_cond, &si->m_mutex); - } -# elif BX_PLATFORM_IOS if (-1 == _msecs) { while (0 == result @@ -133,27 +178,16 @@ namespace bx else { timespec ts; - ts.tv_sec = _msecs/1000; - ts.tv_nsec = (_msecs%1000)*1000; + clock_gettime(CLOCK_REALTIME, &ts); + add(ts, _msecs); while (0 == result && 0 >= si->m_count) { - result = pthread_cond_timedwait_relative_np(&si->m_cond, &si->m_mutex, &ts); + result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts); } } -# else - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += _msecs/1000; - ts.tv_nsec += (_msecs%1000)*1000; - - while (0 == result - && 0 >= si->m_count) - { - result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts); - } -# endif // BX_PLATFORM_ + bool ok = 0 == result; if (ok) @@ -169,80 +203,16 @@ namespace bx return ok; } -# else - - Semaphore::Semaphore() - { - BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); - - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result = sem_init(&si->m_handle, 0, 0); - BX_CHECK(0 == result, "sem_init failed. errno %d", errno); - BX_UNUSED(result); - } - - Semaphore::~Semaphore() - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result = sem_destroy(&si->m_handle); - BX_CHECK(0 == result, "sem_destroy failed. errno %d", errno); - BX_UNUSED(result); - } - - void Semaphore::post(uint32_t _count) - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - - int32_t result; - for (uint32_t ii = 0; ii < _count; ++ii) - { - result = sem_post(&si->m_handle); - BX_CHECK(0 == result, "sem_post failed. errno %d", errno); - } - BX_UNUSED(result); - } - - bool Semaphore::wait(int32_t _msecs) - { - SemaphoreInternal* si = (SemaphoreInternal*)m_internal; - -# if BX_PLATFORM_NACL || BX_PLATFORM_OSX - BX_CHECK(-1 == _msecs, "NaCl and OSX don't support sem_timedwait at this moment."); BX_UNUSED(_msecs); - return 0 == sem_wait(&si->m_handle); -# else - if (0 > _msecs) - { - int32_t result; - do - { - result = sem_wait(&si->m_handle); - } // keep waiting when interrupted by a signal handler... - while (-1 == result && EINTR == errno); - BX_CHECK(0 == result, "sem_wait failed. errno %d", errno); - return 0 == result; - } - - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += _msecs/1000; - ts.tv_nsec += (_msecs%1000)*1000; - return 0 == sem_timedwait(&si->m_handle, &ts); -# endif // BX_PLATFORM_ - } -# endif // BX_CONFIG_SEMAPHORE_PTHREAD - #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 \ || BX_PLATFORM_XBOXONE Semaphore::Semaphore() { SemaphoreInternal* si = (SemaphoreInternal*)m_internal; -#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINRT \ +|| BX_PLATFORM_XBOXONE si->m_handle = CreateSemaphoreExW(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS); #else si->m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL); @@ -269,7 +239,8 @@ namespace bx SemaphoreInternal* si = (SemaphoreInternal*)m_internal; DWORD milliseconds = (0 > _msecs) ? INFINITE : _msecs; -#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +#if BX_PLATFORM_WINRT \ +|| BX_PLATFORM_XBOXONE return WAIT_OBJECT_0 == WaitForSingleObjectEx(si->m_handle, milliseconds, FALSE); #else return WAIT_OBJECT_0 == WaitForSingleObject(si->m_handle, milliseconds); |