mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-14 18:37:27 +00:00
sys_lwmutex, sys_lwcond syscalls improved
This commit is contained in:
parent
6462201aac
commit
cdf38d15d2
@ -217,7 +217,7 @@ s32 sys_lwmutex_lock(PPUThread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeout
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lock using the syscall
|
// lock using the syscall
|
||||||
const s32 res = _sys_lwmutex_lock(lwmutex->sleep_queue, timeout);
|
const s32 res = _sys_lwmutex_lock(ppu, lwmutex->sleep_queue, timeout);
|
||||||
|
|
||||||
lwmutex->all_info--;
|
lwmutex->all_info--;
|
||||||
|
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
#include "Emu/SysCalls/SysCalls.h"
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
|
|
||||||
#include "Emu/Cell/PPUThread.h"
|
#include "Emu/Cell/PPUThread.h"
|
||||||
#include "Emu/SysCalls/Modules/sysPrxForUser.h"
|
|
||||||
#include "sleep_queue.h"
|
|
||||||
#include "sys_lwmutex.h"
|
#include "sys_lwmutex.h"
|
||||||
#include "sys_lwcond.h"
|
#include "sys_lwcond.h"
|
||||||
|
|
||||||
@ -14,6 +12,30 @@ SysCallBase sys_lwcond("sys_lwcond");
|
|||||||
|
|
||||||
extern u64 get_system_time();
|
extern u64 get_system_time();
|
||||||
|
|
||||||
|
void lv2_lwcond_t::notify(lv2_lock_t & lv2_lock, sleep_queue_t::iterator it, const std::shared_ptr<lv2_lwmutex_t>& mutex, bool mode2)
|
||||||
|
{
|
||||||
|
CHECK_LV2_LOCK(lv2_lock);
|
||||||
|
|
||||||
|
auto& ppu = static_cast<PPUThread&>(*it->get());
|
||||||
|
|
||||||
|
ppu.GPR[3] = mode2; // set to return CELL_EBUSY
|
||||||
|
|
||||||
|
if (!mode2)
|
||||||
|
{
|
||||||
|
if (!mutex->signaled)
|
||||||
|
{
|
||||||
|
return mutex->sq.emplace_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex->signaled--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ppu.signal())
|
||||||
|
{
|
||||||
|
throw EXCEPTION("Thread already signaled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s32 _sys_lwcond_create(vm::ptr<u32> lwcond_id, u32 lwmutex_id, vm::ptr<sys_lwcond_t> control, u64 name, u32 arg5)
|
s32 _sys_lwcond_create(vm::ptr<u32> lwcond_id, u32 lwmutex_id, vm::ptr<sys_lwcond_t> control, u64 name, u32 arg5)
|
||||||
{
|
{
|
||||||
sys_lwcond.Warning("_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=0x%x, control=*0x%x, name=0x%llx, arg5=0x%x)", lwcond_id, lwmutex_id, control, name, arg5);
|
sys_lwcond.Warning("_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=0x%x, control=*0x%x, name=0x%llx, arg5=0x%x)", lwcond_id, lwmutex_id, control, name, arg5);
|
||||||
@ -36,7 +58,7 @@ s32 _sys_lwcond_destroy(u32 lwcond_id)
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cond->waiters.empty() || cond->signaled1 || cond->signaled2)
|
if (!cond->sq.empty())
|
||||||
{
|
{
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
@ -62,47 +84,39 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod
|
|||||||
|
|
||||||
if (mode != 1 && mode != 2 && mode != 3)
|
if (mode != 1 && mode != 2 && mode != 3)
|
||||||
{
|
{
|
||||||
sys_lwcond.Error("_sys_lwcond_signal(%d): invalid mode (%d)", lwcond_id, mode);
|
throw EXCEPTION("Unknown mode (%d)", mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto found = ~ppu_thread_id ? cond->waiters.find(ppu_thread_id) : cond->waiters.begin();
|
// mode 1: lightweight mutex was initially owned by the calling thread
|
||||||
|
// mode 2: lightweight mutex was not owned by the calling thread and waiter hasn't been increased
|
||||||
|
// mode 3: lightweight mutex was forcefully owned by the calling thread
|
||||||
|
|
||||||
if (mode == 1)
|
// pick waiter; protocol is ignored in current implementation
|
||||||
|
const auto found = !~ppu_thread_id ? cond->sq.begin() : std::find_if(cond->sq.begin(), cond->sq.end(), [=](sleep_queue_t::value_type& thread)
|
||||||
{
|
{
|
||||||
// mode 1: lightweight mutex was initially owned by the calling thread
|
return thread->get_id() == ppu_thread_id;
|
||||||
|
});
|
||||||
|
|
||||||
if (found == cond->waiters.end())
|
if (found == cond->sq.end())
|
||||||
|
{
|
||||||
|
if (mode == 1)
|
||||||
{
|
{
|
||||||
return CELL_EPERM;
|
return CELL_EPERM;
|
||||||
}
|
}
|
||||||
|
else if (mode == 2)
|
||||||
cond->signaled1++;
|
|
||||||
}
|
|
||||||
else if (mode == 2)
|
|
||||||
{
|
|
||||||
// mode 2: lightweight mutex was not owned by the calling thread and waiter hasn't been increased
|
|
||||||
|
|
||||||
if (found == cond->waiters.end())
|
|
||||||
{
|
{
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
cond->signaled2++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// in mode 3, lightweight mutex was forcefully owned by the calling thread
|
|
||||||
|
|
||||||
if (found == cond->waiters.end())
|
|
||||||
{
|
{
|
||||||
return ~ppu_thread_id ? CELL_ENOENT : CELL_EPERM;
|
return ~ppu_thread_id ? CELL_ENOENT : CELL_EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
cond->signaled1++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cond->waiters.erase(found);
|
// signal specified waiting thread
|
||||||
cond->cv.notify_one();
|
cond->notify(lv2_lock, found, mutex, mode == 2);
|
||||||
|
|
||||||
|
cond->sq.erase(found);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -123,36 +137,27 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode)
|
|||||||
|
|
||||||
if (mode != 1 && mode != 2)
|
if (mode != 1 && mode != 2)
|
||||||
{
|
{
|
||||||
sys_lwcond.Error("_sys_lwcond_signal_all(%d): invalid mode (%d)", lwcond_id, mode);
|
throw EXCEPTION("Unknown mode (%d)", mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 count = (u32)cond->waiters.size();
|
// mode 1: lightweight mutex was initially owned by the calling thread
|
||||||
|
// mode 2: lightweight mutex was not owned by the calling thread and waiter hasn't been increased
|
||||||
|
|
||||||
if (count)
|
// signal all waiting threads; protocol is ignored in current implementation
|
||||||
|
for (auto it = cond->sq.begin(); it != cond->sq.end(); it++)
|
||||||
{
|
{
|
||||||
cond->waiters.clear();
|
cond->notify(lv2_lock, it, mutex, mode == 2);
|
||||||
cond->cv.notify_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 1)
|
// in mode 1, return the amount of threads signaled
|
||||||
{
|
const s32 result = mode == 2 ? CELL_OK : static_cast<s32>(cond->sq.size());
|
||||||
// in mode 1, lightweight mutex was initially owned by the calling thread
|
|
||||||
|
|
||||||
cond->signaled1 += count;
|
cond->sq.clear();
|
||||||
|
|
||||||
return count;
|
return result;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// in mode 2, lightweight mutex was not owned by the calling thread and waiter hasn't been increased
|
|
||||||
|
|
||||||
cond->signaled2 += count;
|
|
||||||
|
|
||||||
return CELL_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 timeout)
|
s32 _sys_lwcond_queue_wait(PPUThread& ppu, u32 lwcond_id, u32 lwmutex_id, u64 timeout)
|
||||||
{
|
{
|
||||||
sys_lwcond.Log("_sys_lwcond_queue_wait(lwcond_id=0x%x, lwmutex_id=0x%x, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout);
|
sys_lwcond.Log("_sys_lwcond_queue_wait(lwcond_id=0x%x, lwmutex_id=0x%x, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout);
|
||||||
|
|
||||||
@ -169,64 +174,45 @@ s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// finalize unlocking the mutex
|
// finalize unlocking the mutex
|
||||||
mutex->signaled++;
|
mutex->unlock(lv2_lock);
|
||||||
|
|
||||||
if (mutex->waiters)
|
|
||||||
{
|
|
||||||
mutex->cv.notify_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
// add waiter; protocol is ignored in current implementation
|
// add waiter; protocol is ignored in current implementation
|
||||||
cond->waiters.emplace(CPU.get_id());
|
sleep_queue_entry_t waiter(ppu, cond->sq);
|
||||||
|
|
||||||
while ((!(cond->signaled1 && mutex->signaled) && !cond->signaled2) || cond->waiters.count(CPU.get_id()))
|
// potential mutex waiter (not added immediately)
|
||||||
|
sleep_queue_entry_t mutex_waiter(ppu, cond->sq, defer_sleep);
|
||||||
|
|
||||||
|
while (!ppu.unsignal())
|
||||||
{
|
{
|
||||||
CHECK_EMU_STATUS;
|
CHECK_EMU_STATUS;
|
||||||
|
|
||||||
const bool is_timedout = timeout && get_system_time() - start_time > timeout;
|
if (timeout && waiter)
|
||||||
|
|
||||||
// check timeout
|
|
||||||
if (is_timedout)
|
|
||||||
{
|
{
|
||||||
// cancel waiting
|
const u64 passed = get_system_time() - start_time;
|
||||||
if (!cond->waiters.erase(CPU.get_id()))
|
|
||||||
|
if (passed >= timeout)
|
||||||
{
|
{
|
||||||
if (cond->signaled1 && !mutex->signaled)
|
// try to reown the mutex if timed out
|
||||||
|
if (mutex->signaled)
|
||||||
{
|
{
|
||||||
cond->signaled1--;
|
mutex->signaled--;
|
||||||
|
|
||||||
|
return CELL_EDEADLK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw EXCEPTION("Unexpected values");
|
return CELL_ETIMEDOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex->signaled)
|
ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
|
||||||
{
|
}
|
||||||
mutex->signaled--;
|
else
|
||||||
|
{
|
||||||
return CELL_EDEADLK;
|
ppu.cv.wait(lv2_lock);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return CELL_ETIMEDOUT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(cond->signaled1 ? mutex->cv : cond->cv).wait_for(lv2_lock, std::chrono::milliseconds(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->signaled1 && mutex->signaled)
|
// return cause
|
||||||
{
|
return ppu.GPR[3] ? CELL_EBUSY : CELL_OK;
|
||||||
mutex->signaled--;
|
|
||||||
cond->signaled1--;
|
|
||||||
|
|
||||||
return CELL_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cond->signaled2--;
|
|
||||||
|
|
||||||
return CELL_EBUSY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "sleep_queue.h"
|
||||||
|
|
||||||
namespace vm { using namespace ps3; }
|
namespace vm { using namespace ps3; }
|
||||||
|
|
||||||
struct sys_lwmutex_t;
|
struct sys_lwmutex_t;
|
||||||
@ -23,20 +25,14 @@ struct lv2_lwcond_t
|
|||||||
{
|
{
|
||||||
const u64 name;
|
const u64 name;
|
||||||
|
|
||||||
std::atomic<u32> signaled1; // mode 1 signals
|
sleep_queue_t sq;
|
||||||
std::atomic<u32> signaled2; // mode 2 signals
|
|
||||||
|
|
||||||
// TODO: use sleep queue
|
|
||||||
std::condition_variable cv;
|
|
||||||
std::unordered_set<u32> waiters;
|
|
||||||
|
|
||||||
lv2_lwcond_t(u64 name)
|
lv2_lwcond_t(u64 name)
|
||||||
: name(name)
|
: name(name)
|
||||||
, signaled1(0)
|
|
||||||
, signaled2(0)
|
|
||||||
//, waiters(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notify(lv2_lock_t& lv2_lock, sleep_queue_t::iterator it, const std::shared_ptr<lv2_lwmutex_t>& mutex, bool mode2);
|
||||||
};
|
};
|
||||||
|
|
||||||
REG_ID_TYPE(lv2_lwcond_t, 0x97); // SYS_LWCOND_OBJECT
|
REG_ID_TYPE(lv2_lwcond_t, 0x97); // SYS_LWCOND_OBJECT
|
||||||
@ -49,4 +45,4 @@ s32 _sys_lwcond_create(vm::ptr<u32> lwcond_id, u32 lwmutex_id, vm::ptr<sys_lwcon
|
|||||||
s32 _sys_lwcond_destroy(u32 lwcond_id);
|
s32 _sys_lwcond_destroy(u32 lwcond_id);
|
||||||
s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mode);
|
s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mode);
|
||||||
s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode);
|
s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode);
|
||||||
s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 timeout);
|
s32 _sys_lwcond_queue_wait(PPUThread& ppu, u32 lwcond_id, u32 lwmutex_id, u64 timeout);
|
||||||
|
@ -5,13 +5,36 @@
|
|||||||
#include "Emu/SysCalls/SysCalls.h"
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
|
|
||||||
#include "Emu/Cell/PPUThread.h"
|
#include "Emu/Cell/PPUThread.h"
|
||||||
#include "sleep_queue.h"
|
|
||||||
#include "sys_lwmutex.h"
|
#include "sys_lwmutex.h"
|
||||||
|
|
||||||
SysCallBase sys_lwmutex("sys_lwmutex");
|
SysCallBase sys_lwmutex("sys_lwmutex");
|
||||||
|
|
||||||
extern u64 get_system_time();
|
extern u64 get_system_time();
|
||||||
|
|
||||||
|
void lv2_lwmutex_t::unlock(lv2_lock_t& lv2_lock)
|
||||||
|
{
|
||||||
|
CHECK_LV2_LOCK(lv2_lock);
|
||||||
|
|
||||||
|
if (signaled)
|
||||||
|
{
|
||||||
|
throw EXCEPTION("Unexpected");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sq.size())
|
||||||
|
{
|
||||||
|
if (!sq.front()->signal())
|
||||||
|
{
|
||||||
|
throw EXCEPTION("Thread already signaled");
|
||||||
|
}
|
||||||
|
|
||||||
|
sq.pop_front();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
signaled++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s32 _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, u32 arg4, u64 name, u32 arg6)
|
s32 _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, u32 arg4, u64 name, u32 arg6)
|
||||||
{
|
{
|
||||||
sys_lwmutex.Warning("_sys_lwmutex_create(lwmutex_id=*0x%x, protocol=0x%x, control=*0x%x, arg4=0x%x, name=0x%llx, arg6=0x%x)", lwmutex_id, protocol, control, arg4, name, arg6);
|
sys_lwmutex.Warning("_sys_lwmutex_create(lwmutex_id=*0x%x, protocol=0x%x, control=*0x%x, arg4=0x%x, name=0x%llx, arg6=0x%x)", lwmutex_id, protocol, control, arg4, name, arg6);
|
||||||
@ -45,7 +68,7 @@ s32 _sys_lwmutex_destroy(u32 lwmutex_id)
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex->waiters)
|
if (!mutex->sq.empty())
|
||||||
{
|
{
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
@ -55,7 +78,7 @@ s32 _sys_lwmutex_destroy(u32 lwmutex_id)
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout)
|
s32 _sys_lwmutex_lock(PPUThread& ppu, u32 lwmutex_id, u64 timeout)
|
||||||
{
|
{
|
||||||
sys_lwmutex.Log("_sys_lwmutex_lock(lwmutex_id=0x%x, timeout=0x%llx)", lwmutex_id, timeout);
|
sys_lwmutex.Log("_sys_lwmutex_lock(lwmutex_id=0x%x, timeout=0x%llx)", lwmutex_id, timeout);
|
||||||
|
|
||||||
@ -70,25 +93,36 @@ s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout)
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
// protocol is ignored in current implementation
|
if (mutex->signaled)
|
||||||
mutex->waiters++;
|
{
|
||||||
|
mutex->signaled--;
|
||||||
|
|
||||||
while (!mutex->signaled)
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add waiter; protocol is ignored in current implementation
|
||||||
|
sleep_queue_entry_t waiter(ppu, mutex->sq);
|
||||||
|
|
||||||
|
while (!ppu.unsignal())
|
||||||
{
|
{
|
||||||
CHECK_EMU_STATUS;
|
CHECK_EMU_STATUS;
|
||||||
|
|
||||||
if (timeout && get_system_time() - start_time > timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
mutex->waiters--;
|
const u64 passed = get_system_time() - start_time;
|
||||||
return CELL_ETIMEDOUT;
|
|
||||||
|
if (passed >= timeout)
|
||||||
|
{
|
||||||
|
return CELL_ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ppu.cv.wait(lv2_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex->cv.wait_for(lv2_lock, std::chrono::milliseconds(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex->signaled--;
|
|
||||||
|
|
||||||
mutex->waiters--;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -106,7 +140,7 @@ s32 _sys_lwmutex_trylock(u32 lwmutex_id)
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex->waiters || !mutex->signaled)
|
if (!mutex->sq.empty() || !mutex->signaled)
|
||||||
{
|
{
|
||||||
return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
@ -129,17 +163,7 @@ s32 _sys_lwmutex_unlock(u32 lwmutex_id)
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex->signaled)
|
mutex->unlock(lv2_lock);
|
||||||
{
|
|
||||||
throw EXCEPTION("Already signaled (lwmutex_id=0x%x)", lwmutex_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex->signaled++;
|
|
||||||
|
|
||||||
if (mutex->waiters)
|
|
||||||
{
|
|
||||||
mutex->cv.notify_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "sleep_queue.h"
|
||||||
|
|
||||||
namespace vm { using namespace ps3; }
|
namespace vm { using namespace ps3; }
|
||||||
|
|
||||||
struct sys_lwmutex_attribute_t
|
struct sys_lwmutex_attribute_t
|
||||||
@ -54,27 +56,28 @@ struct lv2_lwmutex_t
|
|||||||
const u32 protocol;
|
const u32 protocol;
|
||||||
const u64 name;
|
const u64 name;
|
||||||
|
|
||||||
// this object is not truly a mutex and its syscall names are wrong, it's probabably sleep queue or something
|
// this object is not truly a mutex and its syscall names may be wrong, it's probably a sleep queue or something
|
||||||
std::atomic<u32> signaled;
|
std::atomic<u32> signaled{ 0 };
|
||||||
|
|
||||||
// TODO: use sleep queue, possibly remove condition variable
|
sleep_queue_t sq;
|
||||||
std::condition_variable cv;
|
|
||||||
std::atomic<u32> waiters;
|
|
||||||
|
|
||||||
lv2_lwmutex_t(u32 protocol, u64 name)
|
lv2_lwmutex_t(u32 protocol, u64 name)
|
||||||
: protocol(protocol)
|
: protocol(protocol)
|
||||||
, name(name)
|
, name(name)
|
||||||
, signaled(0)
|
|
||||||
, waiters(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unlock(lv2_lock_t& lv2_lock);
|
||||||
};
|
};
|
||||||
|
|
||||||
REG_ID_TYPE(lv2_lwmutex_t, 0x95); // SYS_LWMUTEX_OBJECT
|
REG_ID_TYPE(lv2_lwmutex_t, 0x95); // SYS_LWMUTEX_OBJECT
|
||||||
|
|
||||||
|
// Aux
|
||||||
|
class PPUThread;
|
||||||
|
|
||||||
// SysCalls
|
// SysCalls
|
||||||
s32 _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, u32 arg4, u64 name, u32 arg6);
|
s32 _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, u32 arg4, u64 name, u32 arg6);
|
||||||
s32 _sys_lwmutex_destroy(u32 lwmutex_id);
|
s32 _sys_lwmutex_destroy(u32 lwmutex_id);
|
||||||
s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout);
|
s32 _sys_lwmutex_lock(PPUThread& ppu, u32 lwmutex_id, u64 timeout);
|
||||||
s32 _sys_lwmutex_trylock(u32 lwmutex_id);
|
s32 _sys_lwmutex_trylock(u32 lwmutex_id);
|
||||||
s32 _sys_lwmutex_unlock(u32 lwmutex_id);
|
s32 _sys_lwmutex_unlock(u32 lwmutex_id);
|
||||||
|
Loading…
Reference in New Issue
Block a user