mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-13 15:19:11 +00:00
The way to Unity, pt.2 (#1671)
This commit is contained in:
@@ -191,7 +191,7 @@ int PthreadCond::Signal() {
|
||||
PthreadMutex* mp = td->mutex_obj;
|
||||
has_user_waiters = SleepqRemove(sq, td);
|
||||
|
||||
std::binary_semaphore* waddr = nullptr;
|
||||
BinarySemaphore* waddr = nullptr;
|
||||
if (mp->m_owner == curthread) {
|
||||
if (curthread->nwaiter_defer >= Pthread::MaxDeferWaiters) {
|
||||
curthread->WakeAll();
|
||||
@@ -211,7 +211,7 @@ int PthreadCond::Signal() {
|
||||
|
||||
struct BroadcastArg {
|
||||
Pthread* curthread;
|
||||
std::binary_semaphore* waddrs[Pthread::MaxDeferWaiters];
|
||||
BinarySemaphore* waddrs[Pthread::MaxDeferWaiters];
|
||||
int count;
|
||||
};
|
||||
|
||||
|
||||
@@ -118,7 +118,6 @@ public:
|
||||
}
|
||||
|
||||
m_bits |= bits;
|
||||
|
||||
m_cond_var.notify_all();
|
||||
}
|
||||
|
||||
|
||||
@@ -380,6 +380,7 @@ int PS4_SYSV_ABI posix_sched_get_priority_min() {
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_rename_np(PthreadT thread, const char* name) {
|
||||
LOG_INFO(Kernel_Pthread, "name = {}", name);
|
||||
Common::SetThreadName(reinterpret_cast<void*>(thread->native_thr.GetHandle()), name);
|
||||
thread->name = name;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "common/enum.h"
|
||||
#include "core/libraries/kernel/sync/mutex.h"
|
||||
#include "core/libraries/kernel/sync/semaphore.h"
|
||||
#include "core/libraries/kernel/time.h"
|
||||
#include "core/thread.h"
|
||||
#include "core/tls.h"
|
||||
@@ -44,7 +46,7 @@ enum class PthreadMutexProt : u32 {
|
||||
};
|
||||
|
||||
struct PthreadMutex {
|
||||
std::timed_mutex m_lock;
|
||||
TimedMutex m_lock;
|
||||
PthreadMutexFlags m_flags;
|
||||
Pthread* m_owner;
|
||||
int m_count;
|
||||
@@ -288,14 +290,14 @@ struct Pthread {
|
||||
int report_events;
|
||||
int event_mask;
|
||||
std::string name;
|
||||
std::binary_semaphore wake_sema{0};
|
||||
BinarySemaphore wake_sema{0};
|
||||
SleepQueue* sleepqueue;
|
||||
void* wchan;
|
||||
PthreadMutex* mutex_obj;
|
||||
bool will_sleep;
|
||||
bool has_user_waiters;
|
||||
int nwaiter_defer;
|
||||
std::binary_semaphore* defer_waiters[MaxDeferWaiters];
|
||||
BinarySemaphore* defer_waiters[MaxDeferWaiters];
|
||||
|
||||
bool InCritical() const noexcept {
|
||||
return locklevel > 0 || critical_count > 0;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <mutex>
|
||||
#include <semaphore>
|
||||
|
||||
#include "core/libraries/kernel/sync/semaphore.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/kernel/kernel.h"
|
||||
#include "core/libraries/kernel/orbis_error.h"
|
||||
@@ -21,7 +23,7 @@ constexpr int ORBIS_KERNEL_SEM_VALUE_MAX = 0x7FFFFFFF;
|
||||
struct PthreadSem {
|
||||
explicit PthreadSem(s32 value_) : semaphore{value_}, value{value_} {}
|
||||
|
||||
std::counting_semaphore<ORBIS_KERNEL_SEM_VALUE_MAX> semaphore;
|
||||
CountingSemaphore semaphore;
|
||||
std::atomic<s32> value;
|
||||
};
|
||||
|
||||
@@ -75,7 +77,7 @@ public:
|
||||
it = wait_list.erase(it);
|
||||
token_count -= waiter->need_count;
|
||||
waiter->was_signaled = true;
|
||||
waiter->cv.notify_one();
|
||||
waiter->sem.release();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -88,7 +90,7 @@ public:
|
||||
}
|
||||
for (auto* waiter : wait_list) {
|
||||
waiter->was_cancled = true;
|
||||
waiter->cv.notify_one();
|
||||
waiter->sem.release();
|
||||
}
|
||||
wait_list.clear();
|
||||
token_count = set_count < 0 ? init_count : set_count;
|
||||
@@ -99,21 +101,21 @@ public:
|
||||
std::scoped_lock lk{mutex};
|
||||
for (auto* waiter : wait_list) {
|
||||
waiter->was_deleted = true;
|
||||
waiter->cv.notify_one();
|
||||
waiter->sem.release();
|
||||
}
|
||||
wait_list.clear();
|
||||
}
|
||||
|
||||
public:
|
||||
struct WaitingThread {
|
||||
std::condition_variable cv;
|
||||
BinarySemaphore sem;
|
||||
u32 priority;
|
||||
s32 need_count;
|
||||
bool was_signaled{};
|
||||
bool was_deleted{};
|
||||
bool was_cancled{};
|
||||
|
||||
explicit WaitingThread(s32 need_count, bool is_fifo) : need_count{need_count} {
|
||||
explicit WaitingThread(s32 need_count, bool is_fifo) : sem{0}, need_count{need_count} {
|
||||
// Retrieve calling thread priority for sorting into waiting threads list.
|
||||
if (!is_fifo) {
|
||||
priority = g_curthread->attr.prio;
|
||||
@@ -134,24 +136,26 @@ public:
|
||||
}
|
||||
|
||||
int Wait(std::unique_lock<std::mutex>& lk, u32* timeout) {
|
||||
lk.unlock();
|
||||
if (!timeout) {
|
||||
// Wait indefinitely until we are woken up.
|
||||
cv.wait(lk);
|
||||
sem.acquire();
|
||||
lk.lock();
|
||||
return GetResult(false);
|
||||
}
|
||||
// Wait until timeout runs out, recording how much remaining time there was.
|
||||
const auto start = std::chrono::high_resolution_clock::now();
|
||||
const auto signaled = cv.wait_for(lk, std::chrono::microseconds(*timeout),
|
||||
[this] { return was_signaled; });
|
||||
sem.try_acquire_for(std::chrono::microseconds(*timeout));
|
||||
const auto end = std::chrono::high_resolution_clock::now();
|
||||
const auto time =
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
|
||||
if (signaled) {
|
||||
lk.lock();
|
||||
if (was_signaled) {
|
||||
*timeout -= time;
|
||||
} else {
|
||||
*timeout = 0;
|
||||
}
|
||||
return GetResult(!signaled);
|
||||
return GetResult(!was_signaled);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user