mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-08 20:58:41 +00:00
kernel: Improvements to condvars. (#3592)
This commit is contained in:
@@ -87,10 +87,9 @@ public:
|
||||
template <class Rep, class Period>
|
||||
bool try_acquire_for(const std::chrono::duration<Rep, Period>& rel_time) {
|
||||
#ifdef _WIN64
|
||||
const auto start_time = std::chrono::high_resolution_clock::now();
|
||||
auto rel_time_ms = std::chrono::ceil<std::chrono::milliseconds>(rel_time);
|
||||
|
||||
do {
|
||||
const auto start_time = std::chrono::high_resolution_clock::now();
|
||||
u64 timeout_ms = static_cast<u64>(rel_time_ms.count());
|
||||
u64 res = WaitForSingleObjectEx(sem, timeout_ms, true);
|
||||
if (res == WAIT_OBJECT_0) {
|
||||
@@ -105,8 +104,8 @@ public:
|
||||
|
||||
return false;
|
||||
#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);
|
||||
const auto rel_time_ns = std::chrono::ceil<std::chrono::nanoseconds>(rel_time);
|
||||
const auto timeout = dispatch_time(DISPATCH_TIME_NOW, rel_time_ns.count());
|
||||
return dispatch_semaphore_wait(sem, timeout) == 0;
|
||||
#else
|
||||
return sem.try_acquire_for(rel_time);
|
||||
@@ -115,37 +114,11 @@ public:
|
||||
|
||||
template <class Clock, class Duration>
|
||||
bool try_acquire_until(const std::chrono::time_point<Clock, Duration>& abs_time) {
|
||||
#ifdef _WIN64
|
||||
const auto start_time = Clock::now();
|
||||
|
||||
auto rel_time = std::chrono::ceil<std::chrono::milliseconds>(abs_time - start_time);
|
||||
do {
|
||||
u64 timeout_ms = static_cast<u64>(rel_time.count());
|
||||
u64 res = WaitForSingleObjectEx(sem, timeout_ms, true);
|
||||
if (res == WAIT_OBJECT_0) {
|
||||
return true;
|
||||
} else if (res == WAIT_IO_COMPLETION) {
|
||||
auto elapsed_time = Clock::now() - start_time;
|
||||
rel_time -= std::chrono::duration_cast<std::chrono::milliseconds>(elapsed_time);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} while (rel_time.count() > 0);
|
||||
|
||||
return false;
|
||||
#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
|
||||
const auto current = Clock::now();
|
||||
if (current >= abs_time) {
|
||||
return try_acquire();
|
||||
}
|
||||
return try_acquire_for(abs_time - current);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -108,7 +108,7 @@ int PthreadCond::Wait(PthreadMutexT* mutex, const OrbisKernelTimespec* abstime,
|
||||
* us to check it without locking in pthread_cond_signal().
|
||||
*/
|
||||
has_user_waiters = 1;
|
||||
curthread->will_sleep = 1;
|
||||
curthread->will_sleep = true;
|
||||
|
||||
int recurse;
|
||||
mp->CvUnlock(&recurse);
|
||||
@@ -118,7 +118,7 @@ int PthreadCond::Wait(PthreadMutexT* mutex, const OrbisKernelTimespec* abstime,
|
||||
|
||||
int error = 0;
|
||||
for (;;) {
|
||||
void(curthread->wake_sema.try_acquire());
|
||||
curthread->ClearWake();
|
||||
SleepqUnlock(this);
|
||||
|
||||
//_thr_cancel_enter2(curthread, 0);
|
||||
@@ -198,7 +198,7 @@ int PthreadCond::Signal(Pthread* thread) {
|
||||
curthread->WakeAll();
|
||||
}
|
||||
curthread->defer_waiters[curthread->nwaiter_defer++] = &td->wake_sema;
|
||||
mp->m_flags |= PthreadMutexFlags::Defered;
|
||||
mp->m_flags |= PthreadMutexFlags::Deferred;
|
||||
} else {
|
||||
waddr = &td->wake_sema;
|
||||
}
|
||||
@@ -231,7 +231,7 @@ int PthreadCond::Broadcast() {
|
||||
curthread->WakeAll();
|
||||
}
|
||||
curthread->defer_waiters[curthread->nwaiter_defer++] = &td->wake_sema;
|
||||
mp->m_flags |= PthreadMutexFlags::Defered;
|
||||
mp->m_flags |= PthreadMutexFlags::Deferred;
|
||||
} else {
|
||||
if (ba->count >= Pthread::MaxDeferWaiters) {
|
||||
for (int i = 0; i < ba->count; i++) {
|
||||
|
||||
@@ -282,13 +282,13 @@ int PthreadMutex::Unlock() {
|
||||
if (Type() == PthreadMutexType::Recursive && m_count > 0) [[unlikely]] {
|
||||
m_count--;
|
||||
} else {
|
||||
int defered = True(m_flags & PthreadMutexFlags::Defered);
|
||||
m_flags &= ~PthreadMutexFlags::Defered;
|
||||
const bool deferred = True(m_flags & PthreadMutexFlags::Deferred);
|
||||
m_flags &= ~PthreadMutexFlags::Deferred;
|
||||
|
||||
m_owner = nullptr;
|
||||
m_lock.unlock();
|
||||
|
||||
if (curthread->will_sleep == 0 && defered) {
|
||||
if (curthread->will_sleep == 0 && deferred) {
|
||||
curthread->WakeAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ struct Pthread;
|
||||
|
||||
enum class PthreadMutexFlags : u32 {
|
||||
TypeMask = 0xff,
|
||||
Defered = 0x200,
|
||||
Deferred = 0x200,
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(PthreadMutexFlags)
|
||||
|
||||
@@ -319,8 +319,13 @@ struct Pthread {
|
||||
nwaiter_defer = 0;
|
||||
}
|
||||
|
||||
void ClearWake() {
|
||||
// Try to acquire wake semaphore to reset it.
|
||||
void(wake_sema.try_acquire());
|
||||
}
|
||||
|
||||
bool Sleep(const OrbisKernelTimespec* abstime, u64 usec) {
|
||||
will_sleep = 0;
|
||||
will_sleep = false;
|
||||
if (nwaiter_defer > 0) {
|
||||
WakeAll();
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ void SleepqAdd(void* wchan, Pthread* td) {
|
||||
sq->sq_wchan = wchan;
|
||||
/* sq->sq_type = type; */
|
||||
}
|
||||
td->sleepqueue = NULL;
|
||||
td->sleepqueue = nullptr;
|
||||
td->wchan = wchan;
|
||||
sq->sq_blocked.push_front(td);
|
||||
}
|
||||
@@ -88,10 +88,10 @@ void SleepqDrop(SleepQueue* sq, void (*callback)(Pthread*, void*), void* arg) {
|
||||
td->wchan = nullptr;
|
||||
|
||||
auto sq2 = sq->sq_freeq.begin();
|
||||
for (Pthread* td : sq->sq_blocked) {
|
||||
callback(td, arg);
|
||||
td->sleepqueue = std::addressof(*sq2);
|
||||
td->wchan = nullptr;
|
||||
for (Pthread* td2 : sq->sq_blocked) {
|
||||
callback(td2, arg);
|
||||
td2->sleepqueue = std::addressof(*sq2);
|
||||
td2->wchan = nullptr;
|
||||
++sq2;
|
||||
}
|
||||
sq->sq_blocked.clear();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <windows.h>
|
||||
#include "common/ntapi.h"
|
||||
#else
|
||||
#if __APPLE__
|
||||
#ifdef __APPLE__
|
||||
#include <date/tz.h>
|
||||
#endif
|
||||
#include <ctime>
|
||||
|
||||
Reference in New Issue
Block a user