Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented semaphore for platform blue #1463

Merged
merged 1 commit into from
Jan 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading