From 49f7c99c7786ce257fae28dfeae2f8ee5810424c Mon Sep 17 00:00:00 2001 From: Branimir Karadžić Date: Wed, 29 Mar 2017 17:09:40 +0200 Subject: Update BGFX and BX (nw) --- 3rdparty/bx/src/semaphore.cpp | 282 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 3rdparty/bx/src/semaphore.cpp (limited to '3rdparty/bx/src/semaphore.cpp') diff --git a/3rdparty/bx/src/semaphore.cpp b/3rdparty/bx/src/semaphore.cpp new file mode 100644 index 00000000000..b4369ff0ce6 --- /dev/null +++ b/3rdparty/bx/src/semaphore.cpp @@ -0,0 +1,282 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include + +#if BX_CONFIG_SUPPORTS_THREADING + +#if BX_PLATFORM_POSIX +# include +# include +# include +# include +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOX360 \ + || BX_PLATFORM_XBOXONE +# include +# include +# if BX_PLATFORM_XBOXONE +# include +# 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 + 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_CONFIG_SEMAPHORE_PTHREAD + Semaphore::Semaphore() + { + BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); + + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + si->m_count = 0; + + int result; + + result = pthread_mutex_init(&si->m_mutex, NULL); + BX_CHECK(0 == result, "pthread_mutex_init %d", result); + + result = pthread_cond_init(&si->m_cond, NULL); + BX_CHECK(0 == result, "pthread_cond_init %d", result); + + BX_UNUSED(result); + } + + Semaphore::~Semaphore() + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + int result; + result = pthread_cond_destroy(&si->m_cond); + BX_CHECK(0 == result, "pthread_cond_destroy %d", result); + + result = pthread_mutex_destroy(&si->m_mutex); + BX_CHECK(0 == result, "pthread_mutex_destroy %d", result); + + BX_UNUSED(result); + } + + void Semaphore::post(uint32_t _count) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + int result = pthread_mutex_lock(&si->m_mutex); + BX_CHECK(0 == result, "pthread_mutex_lock %d", result); + + for (uint32_t ii = 0; ii < _count; ++ii) + { + result = pthread_cond_signal(&si->m_cond); + BX_CHECK(0 == result, "pthread_cond_signal %d", result); + } + + si->m_count += _count; + + result = pthread_mutex_unlock(&si->m_mutex); + BX_CHECK(0 == result, "pthread_mutex_unlock %d", result); + + BX_UNUSED(result); + } + + bool Semaphore::wait(int32_t _msecs) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + 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 + && 0 >= si->m_count) + { + result = pthread_cond_wait(&si->m_cond, &si->m_mutex); + } + } + else + { + timespec ts; + ts.tv_sec = _msecs/1000; + ts.tv_nsec = (_msecs%1000)*1000; + + while (0 == result + && 0 >= si->m_count) + { + result = pthread_cond_timedwait_relative_np(&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) + { + --si->m_count; + } + + result = pthread_mutex_unlock(&si->m_mutex); + BX_CHECK(0 == result, "pthread_mutex_unlock %d", result); + + BX_UNUSED(result); + + 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 + si->m_handle = CreateSemaphoreExW(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS); +#else + si->m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL); +#endif + BX_CHECK(NULL != si->m_handle, "Failed to create Semaphore!"); + } + + Semaphore::~Semaphore() + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + CloseHandle(si->m_handle); + } + + void Semaphore::post(uint32_t _count) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + ReleaseSemaphore(si->m_handle, _count, NULL); + } + + bool Semaphore::wait(int32_t _msecs) + { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + DWORD milliseconds = (0 > _msecs) ? INFINITE : _msecs; +#if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT + return WAIT_OBJECT_0 == WaitForSingleObjectEx(si->m_handle, milliseconds, FALSE); +#else + return WAIT_OBJECT_0 == WaitForSingleObject(si->m_handle, milliseconds); +#endif + } +#endif // BX_PLATFORM_ + +} // namespace bx + +#endif // BX_CONFIG_SUPPORTS_THREADING -- cgit v1.2.3-70-g09d2