Skip to content

Commit

Permalink
Implemented semaphore for platform blue (#1463)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrouwe authored Jan 18, 2025
1 parent af77fa8 commit 6ae6658
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Jolt/Core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Jolt/Core/PlatformBlue.h>
#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)
Expand Down
26 changes: 20 additions & 6 deletions Jolt/Core/Semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -56,14 +62,16 @@ 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
}

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)
{
Expand All @@ -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
Expand All @@ -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);
Expand Down
16 changes: 11 additions & 5 deletions Jolt/Core/Semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@

#include <Jolt/Core/Atomics.h>

// 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 <semaphore.h>
#define JPH_USE_PTHREADS
#elif defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS)
#include <dispatch/dispatch.h>
#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 <mutex>
#include <condition_variable>
#endif
Expand All @@ -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<int> 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;
Expand Down

0 comments on commit 6ae6658

Please sign in to comment.