From d90e26f6d05098a5c739c9d5ea71d7b6627dfdcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 14 Nov 2017 21:01:05 -0800 Subject: [PATCH 1/3] Cleanup. --- src/semaphore.cpp | 177 ++++++++++++---------------------------------- 1 file changed, 45 insertions(+), 132 deletions(-) diff --git a/src/semaphore.cpp b/src/semaphore.cpp index bd2aca8..f321240 100644 --- a/src/semaphore.cpp +++ b/src/semaphore.cpp @@ -26,12 +26,6 @@ # endif // BX_PLATFORM_XBOXONE #endif // BX_PLATFORM_ -#ifndef BX_CONFIG_SEMAPHORE_PTHREAD -# define BX_CONFIG_SEMAPHORE_PTHREAD (0 \ - || BX_PLATFORM_LINUX \ - ) -#endif // BX_CONFIG_SEMAPHORE_PTHREAD - namespace bx { struct SemaphoreInternal @@ -40,13 +34,9 @@ namespace bx || BX_PLATFORM_IOS dispatch_semaphore_t m_handle; #elif 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_XBOXONE @@ -54,7 +44,46 @@ namespace bx #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) { @@ -78,7 +107,6 @@ namespace bx toTimespecNs(_ts, ns + _msecs*1000000); } -# if BX_CONFIG_SEMAPHORE_PTHREAD Semaphore::Semaphore() { BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); @@ -139,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_OSX - BX_UNUSED(_msecs); -// BX_CHECK(-1 == _msecs, "OSX doesn'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); - } -# else if (-1 == _msecs) { while (0 == result @@ -159,15 +178,6 @@ namespace bx else { timespec ts; -# if BX_PLATFORM_IOS - toTimespecMs(ts, _msecs); - - while (0 == result - && 0 >= si->m_count) - { - result = pthread_cond_timedwait_relative_np(&si->m_cond, &si->m_mutex, &ts); - } -# else clock_gettime(CLOCK_REALTIME, &ts); add(ts, _msecs); @@ -176,9 +186,8 @@ namespace bx { result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts); } -# endif // BX_PLATFORM_IOS } -# endif // BX_PLATFORM_ + bool ok = 0 == result; if (ok) @@ -194,104 +203,6 @@ namespace bx return ok; } -# elif 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); - } - -# 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 (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); - add(ts, _msecs); - return 0 == sem_timedwait(&si->m_handle, &ts); - } - -# endif // BX_CONFIG_SEMAPHORE_PTHREAD - #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ || BX_PLATFORM_XBOXONE @@ -300,7 +211,8 @@ namespace bx { 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); @@ -327,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); From 493c559e8aaab3cf9daa8d989b83e604ae87a040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 14 Nov 2017 22:09:52 -0800 Subject: [PATCH 2/3] Removed use of new/delete, switched to use allocator instead. --- include/bx/inline/mpscqueue.inl | 6 ++++-- include/bx/inline/spscqueue.inl | 20 ++++++++++++-------- include/bx/mpscqueue.h | 5 +++-- include/bx/spscqueue.h | 12 ++++++------ include/bx/thread.h | 2 +- src/thread.cpp | 3 +++ tests/queue_test.cpp | 6 ++++-- tests/thread_test.cpp | 3 ++- 8 files changed, 35 insertions(+), 22 deletions(-) diff --git a/include/bx/inline/mpscqueue.inl b/include/bx/inline/mpscqueue.inl index 0216b50..7a33678 100644 --- a/include/bx/inline/mpscqueue.inl +++ b/include/bx/inline/mpscqueue.inl @@ -10,7 +10,8 @@ namespace bx { template - inline MpScUnboundedQueueT::MpScUnboundedQueueT() + inline MpScUnboundedQueueT::MpScUnboundedQueueT(AllocatorI* _allocator) + : m_queue(_allocator) { } @@ -39,7 +40,8 @@ namespace bx } template - inline MpScUnboundedBlockingQueue::MpScUnboundedBlockingQueue() + inline MpScUnboundedBlockingQueue::MpScUnboundedBlockingQueue(AllocatorI* _allocator) + : m_queue(_allocator) { } diff --git a/include/bx/inline/spscqueue.inl b/include/bx/inline/spscqueue.inl index 140b4ec..7469953 100644 --- a/include/bx/inline/spscqueue.inl +++ b/include/bx/inline/spscqueue.inl @@ -10,8 +10,9 @@ namespace bx { // http://drdobbs.com/article/print?articleId=210604448&siteSectionName= - inline SpScUnboundedQueue::SpScUnboundedQueue() - : m_first(new Node(NULL) ) + inline SpScUnboundedQueue::SpScUnboundedQueue(AllocatorI* _allocator) + : m_allocator(_allocator) + , m_first(BX_NEW(m_allocator, Node)(NULL) ) , m_divider(m_first) , m_last(m_first) { @@ -23,19 +24,19 @@ namespace bx { Node* node = m_first; m_first = node->m_next; - delete node; + BX_DELETE(m_allocator, node); } } inline void SpScUnboundedQueue::push(void* _ptr) { - m_last->m_next = new Node(_ptr); + m_last->m_next = BX_NEW(m_allocator, Node)(_ptr); atomicExchangePtr( (void**)&m_last, m_last->m_next); while (m_first != m_divider) { Node* node = m_first; m_first = m_first->m_next; - delete node; + BX_DELETE(m_allocator, node); } } @@ -68,7 +69,8 @@ namespace bx } template - inline SpScUnboundedQueueT::SpScUnboundedQueueT() + inline SpScUnboundedQueueT::SpScUnboundedQueueT(AllocatorI* _allocator) + : m_queue(_allocator) { } @@ -96,7 +98,8 @@ namespace bx } #if BX_CONFIG_SUPPORTS_THREADING - inline SpScBlockingUnboundedQueue::SpScBlockingUnboundedQueue() + inline SpScBlockingUnboundedQueue::SpScBlockingUnboundedQueue(AllocatorI* _allocator) + : m_queue(_allocator) { } @@ -126,7 +129,8 @@ namespace bx } template - inline SpScBlockingUnboundedQueueT::SpScBlockingUnboundedQueueT() + inline SpScBlockingUnboundedQueueT::SpScBlockingUnboundedQueueT(AllocatorI* _allocator) + : m_queue(_allocator) { } diff --git a/include/bx/mpscqueue.h b/include/bx/mpscqueue.h index 0ac8f82..1735e83 100644 --- a/include/bx/mpscqueue.h +++ b/include/bx/mpscqueue.h @@ -6,6 +6,7 @@ #ifndef BX_MPSCQUEUE_H_HEADER_GUARD #define BX_MPSCQUEUE_H_HEADER_GUARD +#include "allocator.h" #include "mutex.h" #include "spscqueue.h" @@ -22,7 +23,7 @@ namespace bx public: /// - MpScUnboundedQueueT(); + MpScUnboundedQueueT(AllocatorI* _allocator); /// ~MpScUnboundedQueueT(); @@ -52,7 +53,7 @@ namespace bx public: /// - MpScUnboundedBlockingQueue(); + MpScUnboundedBlockingQueue(AllocatorI* _allocator); /// ~MpScUnboundedBlockingQueue(); diff --git a/include/bx/spscqueue.h b/include/bx/spscqueue.h index 4d37d63..c79b595 100644 --- a/include/bx/spscqueue.h +++ b/include/bx/spscqueue.h @@ -6,7 +6,7 @@ #ifndef BX_SPSCQUEUE_H_HEADER_GUARD #define BX_SPSCQUEUE_H_HEADER_GUARD -#include "bx.h" +#include "allocator.h" #include "cpu.h" #include "semaphore.h" @@ -22,7 +22,7 @@ namespace bx public: /// - SpScUnboundedQueue(); + SpScUnboundedQueue(AllocatorI* _allocator); /// ~SpScUnboundedQueue(); @@ -46,6 +46,7 @@ namespace bx Node* m_next; }; + AllocatorI* m_allocator; Node* m_first; Node* m_divider; Node* m_last; @@ -62,7 +63,7 @@ namespace bx public: /// - SpScUnboundedQueueT(); + SpScUnboundedQueueT(AllocatorI* _allocator); /// ~SpScUnboundedQueueT(); @@ -80,7 +81,6 @@ namespace bx SpScUnboundedQueue m_queue; }; - #if BX_CONFIG_SUPPORTS_THREADING /// class SpScBlockingUnboundedQueue @@ -92,7 +92,7 @@ namespace bx public: /// - SpScBlockingUnboundedQueue(); + SpScBlockingUnboundedQueue(AllocatorI* _allocator); /// ~SpScBlockingUnboundedQueue(); @@ -122,7 +122,7 @@ namespace bx public: /// - SpScBlockingUnboundedQueueT(); + SpScBlockingUnboundedQueueT(AllocatorI* _allocator); /// ~SpScBlockingUnboundedQueueT(); diff --git a/include/bx/thread.h b/include/bx/thread.h index 30e7478..3ba17e6 100644 --- a/include/bx/thread.h +++ b/include/bx/thread.h @@ -6,7 +6,7 @@ #ifndef BX_THREAD_H_HEADER_GUARD #define BX_THREAD_H_HEADER_GUARD -#include "bx.h" +#include "allocator.h" #include "mpscqueue.h" namespace bx diff --git a/src/thread.cpp b/src/thread.cpp index 2850418..09a5f76 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -36,6 +36,8 @@ using namespace Windows::System::Threading; namespace bx { + static DefaultAllocator s_allocator; + struct ThreadInternal { #if BX_PLATFORM_WINDOWS \ @@ -76,6 +78,7 @@ namespace bx Thread::Thread() : m_fn(NULL) , m_userData(NULL) + , m_queue(&s_allocator) , m_stackSize(0) , m_exitCode(kExitSuccess) , m_running(false) diff --git a/tests/queue_test.cpp b/tests/queue_test.cpp index 48fd270..81a2b44 100644 --- a/tests/queue_test.cpp +++ b/tests/queue_test.cpp @@ -21,14 +21,16 @@ uintptr_t ptrToBits(void* _ptr) TEST_CASE("SpSc", "") { - bx::SpScUnboundedQueue queue; + bx::DefaultAllocator allocator; + bx::SpScUnboundedQueue queue(&allocator); queue.push(bitsToPtr(0xdeadbeef) ); REQUIRE(0xdeadbeef == ptrToBits(queue.pop() ) ); } TEST_CASE("MpSc", "") { - bx::MpScUnboundedQueueT queue; + bx::DefaultAllocator allocator; + bx::MpScUnboundedQueueT queue(&allocator); queue.push(bitsToPtr(0xdeadbeef) ); REQUIRE(0xdeadbeef == ptrToBits(queue.pop() ) ); } diff --git a/tests/thread_test.cpp b/tests/thread_test.cpp index acea2f6..7137819 100644 --- a/tests/thread_test.cpp +++ b/tests/thread_test.cpp @@ -6,7 +6,8 @@ #include "test.h" #include -bx::MpScUnboundedBlockingQueue s_mpsc; +bx::DefaultAllocator s_allocator; +bx::MpScUnboundedBlockingQueue s_mpsc(&s_allocator); int32_t threadExit0(bx::Thread* _thread, void*) { From 5fdeb8515740f97150bc2f6d38c4daad1ba706c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Wed, 15 Nov 2017 09:27:29 -0800 Subject: [PATCH 3/3] Lazy init default thread allocator. --- src/thread.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/thread.cpp b/src/thread.cpp index 09a5f76..fe7f349 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -36,7 +36,11 @@ using namespace Windows::System::Threading; namespace bx { - static DefaultAllocator s_allocator; + static AllocatorI* getAllocator() + { + static DefaultAllocator s_allocator; + return &s_allocator; + } struct ThreadInternal { @@ -78,7 +82,7 @@ namespace bx Thread::Thread() : m_fn(NULL) , m_userData(NULL) - , m_queue(&s_allocator) + , m_queue(getAllocator() ) , m_stackSize(0) , m_exitCode(kExitSuccess) , m_running(false)