From 3262de4aba7022a97ac148f2f1e53786fe2c3877 Mon Sep 17 00:00:00 2001 From: Jorrit Rouwe Date: Sat, 18 Jan 2025 15:55:11 +0100 Subject: [PATCH] Implemented semaphore for platform blue --- Jolt/Core/Core.h | 2 +- Jolt/Core/Semaphore.cpp | 26 ++++++++++++++++++++------ Jolt/Core/Semaphore.h | 16 +++++++++++----- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Jolt/Core/Core.h b/Jolt/Core/Core.h index 5940c75fb..2caa59ca7 100644 --- a/Jolt/Core/Core.h +++ b/Jolt/Core/Core.h @@ -388,7 +388,7 @@ // Configuration for a popular game console. // This file is not distributed because it would violate an NDA. // Creating one should only be a couple of minutes of work if you have the documentation for the platform - // (you only need to define JPH_BREAKPOINT, JPH_PLATFORM_BLUE_GET_TICKS, JPH_PLATFORM_BLUE_MUTEX*, JPH_PLATFORM_BLUE_RWLOCK* and include the right header). + // (you only need to define JPH_BREAKPOINT, JPH_PLATFORM_BLUE_GET_TICKS, JPH_PLATFORM_BLUE_MUTEX*, JPH_PLATFORM_BLUE_RWLOCK*, JPH_PLATFORM_BLUE_SEMAPHORE* and include the right header). #include #elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID) || defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS) || defined(JPH_PLATFORM_BSD) #if defined(JPH_CPU_X86) diff --git a/Jolt/Core/Semaphore.cpp b/Jolt/Core/Semaphore.cpp index 41d3d0765..43a054c60 100644 --- a/Jolt/Core/Semaphore.cpp +++ b/Jolt/Core/Semaphore.cpp @@ -45,6 +45,12 @@ Semaphore::Semaphore() Trace("Failed to create semaphore"); std::abort(); } +#elif defined(JPH_PLATFORM_BLUE) + if (!JPH_PLATFORM_BLUE_SEMAPHORE_INIT(mSemaphore)) + { + Trace("Failed to create semaphore"); + std::abort(); + } #endif } @@ -56,6 +62,8 @@ Semaphore::~Semaphore() sem_destroy(&mSemaphore); #elif defined(JPH_USE_GRAND_CENTRAL_DISPATCH) dispatch_release(mSemaphore); +#elif defined(JPH_PLATFORM_BLUE) + JPH_PLATFORM_BLUE_SEMAPHORE_DESTROY(mSemaphore); #endif } @@ -63,7 +71,7 @@ void Semaphore::Release(uint inNumber) { JPH_ASSERT(inNumber > 0); -#if defined(JPH_PLATFORM_WINDOWS) || defined(JPH_USE_PTHREADS) || defined(JPH_USE_GRAND_CENTRAL_DISPATCH) +#if defined(JPH_PLATFORM_WINDOWS) || defined(JPH_USE_PTHREADS) || defined(JPH_USE_GRAND_CENTRAL_DISPATCH) || defined(JPH_PLATFORM_BLUE) int old_value = mCount.fetch_add(inNumber, std::memory_order_release); if (old_value < 0) { @@ -77,6 +85,8 @@ void Semaphore::Release(uint inNumber) #elif defined(JPH_USE_GRAND_CENTRAL_DISPATCH) for (int i = 0; i < num_to_release; ++i) dispatch_semaphore_signal(mSemaphore); + #elif defined(JPH_PLATFORM_BLUE) + JPH_PLATFORM_BLUE_SEMAPHORE_SIGNAL(mSemaphore, num_to_release); #endif } #else @@ -93,20 +103,24 @@ void Semaphore::Acquire(uint inNumber) { JPH_ASSERT(inNumber > 0); -#if defined(JPH_PLATFORM_WINDOWS) || defined(JPH_USE_PTHREADS) || defined(JPH_USE_GRAND_CENTRAL_DISPATCH) +#if defined(JPH_PLATFORM_WINDOWS) || defined(JPH_USE_PTHREADS) || defined(JPH_USE_GRAND_CENTRAL_DISPATCH) || defined(JPH_PLATFORM_BLUE) int old_value = mCount.fetch_sub(inNumber, std::memory_order_acquire); int new_value = old_value - (int)inNumber; if (new_value < 0) { int num_to_acquire = min(old_value, 0) - new_value; + #ifdef JPH_PLATFORM_WINDOWS for (int i = 0; i < num_to_acquire; ++i) - #ifdef JPH_PLATFORM_WINDOWS WaitForSingleObject(mSemaphore, INFINITE); - #elif defined(JPH_USE_PTHREADS) + #elif defined(JPH_USE_PTHREADS) + for (int i = 0; i < num_to_acquire; ++i) sem_wait(&mSemaphore); - #elif defined(JPH_USE_GRAND_CENTRAL_DISPATCH) + #elif defined(JPH_USE_GRAND_CENTRAL_DISPATCH) + for (int i = 0; i < num_to_acquire; ++i) dispatch_semaphore_wait(mSemaphore, DISPATCH_TIME_FOREVER); - #endif + #elif defined(JPH_PLATFORM_BLUE) + JPH_PLATFORM_BLUE_SEMAPHORE_WAIT(mSemaphore, num_to_acquire); + #endif } #else std::unique_lock lock(mLock); diff --git a/Jolt/Core/Semaphore.h b/Jolt/Core/Semaphore.h index 2fcdb07dd..492f8b24b 100644 --- a/Jolt/Core/Semaphore.h +++ b/Jolt/Core/Semaphore.h @@ -6,15 +6,19 @@ #include -// Determine if we will use pthreads or not +// Determine which platform specific construct we'll use JPH_SUPPRESS_WARNINGS_STD_BEGIN -#if defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID) || defined(JPH_PLATFORM_BSD) || defined(JPH_PLATFORM_WASM) +#ifdef JPH_PLATFORM_WINDOWS + // We include windows.h in the cpp file, the semaphore itself is a void pointer +#elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID) || defined(JPH_PLATFORM_BSD) || defined(JPH_PLATFORM_WASM) #include #define JPH_USE_PTHREADS #elif defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS) #include #define JPH_USE_GRAND_CENTRAL_DISPATCH -#elif !defined(JPH_PLATFORM_WINDOWS) +#elif defined(JPH_PLATFORM_BLUE) + // Jolt/Core/PlatformBlue.h should have defined everything that is needed below +#else #include #include #endif @@ -41,16 +45,18 @@ class JPH_EXPORT Semaphore inline int GetValue() const { return mCount.load(std::memory_order_relaxed); } private: -#if defined(JPH_PLATFORM_WINDOWS) || defined(JPH_USE_PTHREADS) || defined(JPH_USE_GRAND_CENTRAL_DISPATCH) +#if defined(JPH_PLATFORM_WINDOWS) || defined(JPH_USE_PTHREADS) || defined(JPH_USE_GRAND_CENTRAL_DISPATCH) || defined(JPH_PLATFORM_BLUE) #ifdef JPH_PLATFORM_WINDOWS using SemaphoreType = void *; #elif defined(JPH_USE_PTHREADS) using SemaphoreType = sem_t; #elif defined(JPH_USE_GRAND_CENTRAL_DISPATCH) using SemaphoreType = dispatch_semaphore_t; +#elif defined(JPH_PLATFORM_BLUE) + using SemaphoreType = JPH_PLATFORM_BLUE_SEMAPHORE; #endif alignas(JPH_CACHE_LINE_SIZE) atomic mCount { 0 }; ///< We increment mCount for every release, to acquire we decrement the count. If the count is negative we know that we are waiting on the actual semaphore. - SemaphoreType mSemaphore; ///< The semaphore is an expensive construct so we only acquire/release it if we know that we need to wait/have waiting threads + SemaphoreType mSemaphore { }; ///< The semaphore is an expensive construct so we only acquire/release it if we know that we need to wait/have waiting threads #else // Other platforms: Emulate a semaphore using a mutex, condition variable and count std::mutex mLock;