mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-28 02:26:07 +00:00
semaphore: Add GCD semaphore implementation. (#1677)
This commit is contained in:
parent
7ffa581d4b
commit
e1ecfb8dd1
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include <dispatch/dispatch.h>
|
||||||
#else
|
#else
|
||||||
#include <semaphore>
|
#include <semaphore>
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,25 +23,32 @@ template <s64 max>
|
||||||
class Semaphore {
|
class Semaphore {
|
||||||
public:
|
public:
|
||||||
Semaphore(s32 initialCount)
|
Semaphore(s32 initialCount)
|
||||||
#ifndef _WIN64
|
#if !defined(_WIN64) && !defined(__APPLE__)
|
||||||
: sem{initialCount}
|
: sem{initialCount}
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
sem = CreateSemaphore(nullptr, initialCount, max, nullptr);
|
sem = CreateSemaphore(nullptr, initialCount, max, nullptr);
|
||||||
ASSERT(sem);
|
ASSERT(sem);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
sem = dispatch_semaphore_create(initialCount);
|
||||||
|
ASSERT(sem);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~Semaphore() {
|
~Semaphore() {
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
CloseHandle(sem);
|
CloseHandle(sem);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
dispatch_release(sem);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void release() {
|
void release() {
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
ReleaseSemaphore(sem, 1, nullptr);
|
ReleaseSemaphore(sem, 1, nullptr);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
dispatch_semaphore_signal(sem);
|
||||||
#else
|
#else
|
||||||
sem.release();
|
sem.release();
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,6 +62,13 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
for (;;) {
|
||||||
|
const auto res = dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
|
||||||
|
if (res == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
sem.acquire();
|
sem.acquire();
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,6 +77,8 @@ public:
|
||||||
bool try_acquire() {
|
bool try_acquire() {
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
return WaitForSingleObjectEx(sem, 0, true) == WAIT_OBJECT_0;
|
return WaitForSingleObjectEx(sem, 0, true) == WAIT_OBJECT_0;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
return dispatch_semaphore_wait(sem, DISPATCH_TIME_NOW) == 0;
|
||||||
#else
|
#else
|
||||||
return sem.try_acquire();
|
return sem.try_acquire();
|
||||||
#endif
|
#endif
|
||||||
|
@ -77,6 +95,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
return WaitForSingleObjectEx(sem, timeout_ms, true) == WAIT_OBJECT_0;
|
return WaitForSingleObjectEx(sem, timeout_ms, true) == WAIT_OBJECT_0;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
const auto rel_time_ns = std::chrono::ceil<std::chrono::nanoseconds>(rel_time).count();
|
||||||
|
const auto timeout = dispatch_time(DISPATCH_TIME_NOW, rel_time_ns);
|
||||||
|
return dispatch_semaphore_wait(sem, timeout) == 0;
|
||||||
#else
|
#else
|
||||||
return sem.try_acquire_for(rel_time);
|
return sem.try_acquire_for(rel_time);
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,6 +120,16 @@ public:
|
||||||
|
|
||||||
u64 res = WaitForSingleObjectEx(sem, static_cast<u64>(timeout_ms), true);
|
u64 res = WaitForSingleObjectEx(sem, static_cast<u64>(timeout_ms), true);
|
||||||
return res == WAIT_OBJECT_0;
|
return res == WAIT_OBJECT_0;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
auto abs_s = std::chrono::time_point_cast<std::chrono::seconds>(abs_time);
|
||||||
|
auto abs_ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(abs_time) -
|
||||||
|
std::chrono::time_point_cast<std::chrono::nanoseconds>(abs_s);
|
||||||
|
const timespec abs_timespec = {
|
||||||
|
.tv_sec = abs_s.time_since_epoch().count(),
|
||||||
|
.tv_nsec = abs_ns.count(),
|
||||||
|
};
|
||||||
|
const auto timeout = dispatch_walltime(&abs_timespec, 0);
|
||||||
|
return dispatch_semaphore_wait(sem, timeout) == 0;
|
||||||
#else
|
#else
|
||||||
return sem.try_acquire_until(abs_time);
|
return sem.try_acquire_until(abs_time);
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,6 +138,8 @@ public:
|
||||||
private:
|
private:
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
HANDLE sem;
|
HANDLE sem;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
dispatch_semaphore_t sem;
|
||||||
#else
|
#else
|
||||||
std::counting_semaphore<max> sem;
|
std::counting_semaphore<max> sem;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue