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