Explorar o código

Implemented semaphore for platform blue (#1463)

Jorrit Rouwe hai 7 meses
pai
achega
6ae6658220
Modificáronse 3 ficheiros con 32 adicións e 12 borrados
  1. 1 1
      Jolt/Core/Core.h
  2. 20 6
      Jolt/Core/Semaphore.cpp
  3. 11 5
      Jolt/Core/Semaphore.h

+ 1 - 1
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 <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)

+ 20 - 6
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);

+ 11 - 5
Jolt/Core/Semaphore.h

@@ -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
@@ -41,16 +45,18 @@ public:
 	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;