mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 20:15:27 +00:00
Lv2 lwcond "true" syscalls
This commit is contained in:
parent
3cf80b0831
commit
befc0f62b8
27 changed files with 212 additions and 71 deletions
|
@ -106,7 +106,7 @@ void CPUThreadManager::RemoveThread(u32 id)
|
|||
}
|
||||
|
||||
// Removing the ID should trigger the actual deletion of the thread
|
||||
Emu.GetIdManager().RemoveID(id);
|
||||
Emu.GetIdManager().RemoveID<CPUThread>(id);
|
||||
Emu.CheckStatus();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
#define ID_MANAGER_INCLUDED
|
||||
|
||||
#define rID_ANY -1 // was wxID_ANY
|
||||
|
||||
enum IDType
|
||||
{
|
||||
// Special objects
|
||||
|
@ -133,11 +131,13 @@ public:
|
|||
Clear();
|
||||
}
|
||||
|
||||
bool CheckID(const u32 id)
|
||||
template<typename T> bool CheckID(const u32 id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
return m_id_map.find(id) != m_id_map.end();
|
||||
auto f = m_id_map.find(id);
|
||||
|
||||
return f != m_id_map.end() && f->second.GetInfo() == typeid(T);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
|
@ -148,12 +148,7 @@ public:
|
|||
m_cur_id = s_first_id;
|
||||
}
|
||||
|
||||
template<typename T
|
||||
#ifdef __GNUG__
|
||||
= char
|
||||
#endif
|
||||
>
|
||||
u32 GetNewID(std::shared_ptr<T>& data = nullptr, const IDType type = TYPE_OTHER)
|
||||
template<typename T> u32 GetNewID(std::shared_ptr<T>& data, const IDType type = TYPE_OTHER)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
|
@ -172,12 +167,12 @@ public:
|
|||
return m_id_map[id];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GetIDData(const u32 id, std::shared_ptr<T>& result)
|
||||
template<typename T> bool GetIDData(const u32 id, std::shared_ptr<T>& result)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
auto f = m_id_map.find(id);
|
||||
|
||||
if (f == m_id_map.end() || f->second.GetInfo() != typeid(T)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -189,23 +184,18 @@ public:
|
|||
|
||||
bool HasID(const u32 id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
if(id == rID_ANY) {
|
||||
return m_id_map.begin() != m_id_map.end();
|
||||
}
|
||||
}
|
||||
return CheckID(id);
|
||||
return m_id_map.find(id) != m_id_map.end();
|
||||
}
|
||||
|
||||
bool RemoveID(const u32 id)
|
||||
template<typename T> bool RemoveID(const u32 id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
auto item = m_id_map.find(id);
|
||||
|
||||
if (item == m_id_map.end()) {
|
||||
if (item == m_id_map.end() || item->second.GetInfo() != typeid(T)) {
|
||||
return false;
|
||||
}
|
||||
if (item->second.GetType() < TYPE_OTHER) {
|
||||
|
|
|
@ -571,7 +571,7 @@ int cellAdecClose(u32 handle)
|
|||
}
|
||||
|
||||
if (adec->adecCb) Emu.GetCPU().RemoveThread(adec->adecCb->GetId());
|
||||
Emu.GetIdManager().RemoveID(handle);
|
||||
Emu.GetIdManager().RemoveID<AudioDecoder>(handle);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -710,7 +710,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr)
|
|||
}
|
||||
}
|
||||
es.dmux = nullptr;
|
||||
Emu.GetIdManager().RemoveID(task.es.es);
|
||||
Emu.GetIdManager().RemoveID<ElementaryStream>(task.es.es);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -880,7 +880,7 @@ int cellDmuxClose(u32 demuxerHandle)
|
|||
}
|
||||
|
||||
if (dmux->dmuxCb) Emu.GetCPU().RemoveThread(dmux->dmuxCb->GetId());
|
||||
Emu.GetIdManager().RemoveID(demuxerHandle);
|
||||
Emu.GetIdManager().RemoveID<Demuxer>(demuxerHandle);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ int cellGifDecClose(u32 mainHandle, u32 subHandle)
|
|||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
cellFsClose(subHandle_data->fd);
|
||||
Emu.GetIdManager().RemoveID(subHandle);
|
||||
Emu.GetIdManager().RemoveID<CellGifDecSubHandle>(subHandle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ int cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
|||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
cellFsClose(subHandle_data->fd);
|
||||
Emu.GetIdManager().RemoveID(subHandle);
|
||||
Emu.GetIdManager().RemoveID<CellJpgDecSubHandle>(subHandle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -615,7 +615,7 @@ int cellVdecClose(u32 handle)
|
|||
}
|
||||
|
||||
if (vdec->vdecCb) Emu.GetCPU().RemoveThread(vdec->vdecCb->GetId());
|
||||
Emu.GetIdManager().RemoveID(handle);
|
||||
Emu.GetIdManager().RemoveID<VideoDecoder>(handle);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ int cellVpostClose(u32 handle)
|
|||
return CELL_VPOST_ERROR_C_ARG_HDL_INVALID;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(handle);
|
||||
Emu.GetIdManager().RemoveID<VpostInstance>(handle);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -352,9 +352,9 @@ s32 sys_lwcond_create(vm::ptr<sys_lwcond_t> lwcond, vm::ptr<sys_lwmutex_t> lwmut
|
|||
{
|
||||
sysPrxForUser.Warning("sys_lwcond_create(lwcond=*0x%x, lwmutex=*0x%x, attr=*0x%x)", lwcond, lwmutex, attr);
|
||||
|
||||
std::shared_ptr<lwcond_t> lwc(new lwcond_t(attr->name_u64));
|
||||
std::shared_ptr<lwcond_t> cond(new lwcond_t(attr->name_u64));
|
||||
|
||||
lwcond->lwcond_queue = Emu.GetIdManager().GetNewID(lwc, TYPE_LWCOND);
|
||||
lwcond->lwcond_queue = Emu.GetIdManager().GetNewID(cond, TYPE_LWCOND);
|
||||
lwcond->lwmutex = lwmutex;
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -368,7 +368,7 @@ s32 sys_lwcond_destroy(vm::ptr<sys_lwcond_t> lwcond)
|
|||
|
||||
if (res == CELL_OK)
|
||||
{
|
||||
lwcond->lwcond_queue = lwmutex::dead;
|
||||
lwcond->lwcond_queue = lwmutex_dead;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -383,6 +383,7 @@ s32 sys_lwcond_signal(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond)
|
|||
if ((lwmutex->attribute.data() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK)) == se32(SYS_SYNC_RETRY))
|
||||
{
|
||||
// TODO (protocol ignored)
|
||||
//return _sys_lwcond_signal(lwcond->lwcond_queue, 0, -1, 2);
|
||||
}
|
||||
|
||||
if (lwmutex->owner.read_relaxed() == CPU.GetId())
|
||||
|
@ -440,6 +441,7 @@ s32 sys_lwcond_signal_all(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond)
|
|||
if ((lwmutex->attribute.data() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK)) == se32(SYS_SYNC_RETRY))
|
||||
{
|
||||
// TODO (protocol ignored)
|
||||
//return _sys_lwcond_signal_all(lwcond->lwcond_queue, lwmutex->sleep_queue, 2);
|
||||
}
|
||||
|
||||
if (lwmutex->owner.read_relaxed() == CPU.GetId())
|
||||
|
@ -496,6 +498,7 @@ s32 sys_lwcond_signal_to(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_t
|
|||
if ((lwmutex->attribute.data() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK)) == se32(SYS_SYNC_RETRY))
|
||||
{
|
||||
// TODO (protocol ignored)
|
||||
//return _sys_lwcond_signal(lwcond->lwcond_queue, 0, ppu_thread_id, 2);
|
||||
}
|
||||
|
||||
if (lwmutex->owner.read_relaxed() == CPU.GetId())
|
||||
|
@ -613,7 +616,7 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
|
|||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
sysPrxForUser.Fatal("sys_lwconde_wait(lwcond=*0x%x): unexpected syscall result (0x%x)", lwcond, res);
|
||||
sysPrxForUser.Fatal("sys_lwcond_wait(lwcond=*0x%x): unexpected syscall result (0x%x)", lwcond, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ s32 cellFsClose(u32 fd)
|
|||
{
|
||||
sys_fs.Warning("cellFsClose(fd=0x%x)", fd);
|
||||
|
||||
if (!Emu.GetIdManager().RemoveID(fd))
|
||||
if (!Emu.GetIdManager().RemoveID<vfsStream>(fd))
|
||||
return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
|
@ -214,7 +214,7 @@ s32 cellFsClosedir(u32 fd)
|
|||
{
|
||||
sys_fs.Warning("cellFsClosedir(fd=0x%x)", fd);
|
||||
|
||||
if (!Emu.GetIdManager().RemoveID(fd))
|
||||
if (!Emu.GetIdManager().RemoveID<vfsDirBase>(fd))
|
||||
return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
|
|
|
@ -125,7 +125,7 @@ u32 sleep_queue_t::signal(u32 protocol)
|
|||
if (m_waiting.size())
|
||||
{
|
||||
res = m_waiting[0];
|
||||
if (!Emu.GetIdManager().CheckID(res))
|
||||
if (!Emu.GetIdManager().CheckID<CPUThread>(res))
|
||||
{
|
||||
LOG_ERROR(HLE, "sleep_queue_t['%s']::signal(SYS_SYNC_FIFO) failed: invalid thread (%d)", m_name.c_str(), res);
|
||||
Emu.Pause();
|
||||
|
|
|
@ -67,7 +67,7 @@ s32 sys_cond_destroy(u32 cond_id)
|
|||
throw __FUNCTION__;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(cond_id);
|
||||
Emu.GetIdManager().RemoveID<cond_t>(cond_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id)
|
|||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (!Emu.GetIdManager().CheckID(thread_id))
|
||||
if (!Emu.GetIdManager().CheckID<CPUThread>(thread_id))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
@ -180,10 +180,16 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout)
|
|||
|
||||
while (!cond->mutex->owner.expired() || !cond->signaled)
|
||||
{
|
||||
if (!cond->signaled && timeout && get_system_time() - start_time > timeout)
|
||||
const bool is_timedout = timeout && get_system_time() - start_time > timeout;
|
||||
|
||||
// check timeout only if no thread signaled (the flaw of avoiding sleep queue)
|
||||
if (is_timedout && cond->mutex->owner.expired() && !cond->signaled)
|
||||
{
|
||||
// TODO: mutex not locked, timeout is possible only when signaled == 0
|
||||
// cancel waiting if the mutex is free, restore its owner and recursive value
|
||||
cond->mutex->owner = thread;
|
||||
cond->mutex->recursive_count = recursive_value;
|
||||
cond->waiters--; assert(cond->waiters >= 0);
|
||||
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -194,14 +200,13 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout)
|
|||
}
|
||||
|
||||
// wait on appropriate condition variable
|
||||
(cond->signaled ? cond->mutex->cv : cond->cv).wait_for(lv2_lock, std::chrono::milliseconds(1));
|
||||
(cond->signaled || is_timedout ? cond->mutex->cv : cond->cv).wait_for(lv2_lock, std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
// reown the mutex and restore recursive value
|
||||
// reown the mutex and restore its recursive value
|
||||
cond->mutex->owner = thread;
|
||||
cond->mutex->recursive_count = recursive_value;
|
||||
|
||||
cond->signaled--; assert(cond->signaled >= 0);
|
||||
cond->signaled--;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,11 @@ struct cond_t
|
|||
const u64 name;
|
||||
const std::shared_ptr<mutex_t> mutex; // associated mutex
|
||||
|
||||
std::atomic<u32> signaled;
|
||||
|
||||
// TODO: use sleep queue, possibly remove condition variable
|
||||
std::condition_variable cv;
|
||||
std::atomic<s32> waiters;
|
||||
std::atomic<s32> signaled;
|
||||
|
||||
cond_t(std::shared_ptr<mutex_t>& mutex, u64 name)
|
||||
: mutex(mutex)
|
||||
|
|
|
@ -100,7 +100,7 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode)
|
|||
}
|
||||
|
||||
Emu.GetEventManager().UnregisterKey(queue->key);
|
||||
Emu.GetIdManager().RemoveID(equeue_id);
|
||||
Emu.GetIdManager().RemoveID<event_queue_t>(equeue_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ s32 sys_event_port_destroy(u32 eport_id)
|
|||
return CELL_EISCONN;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(eport_id);
|
||||
Emu.GetIdManager().RemoveID<event_port_t>(eport_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ s32 sys_event_flag_destroy(u32 id)
|
|||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(id);
|
||||
Emu.GetIdManager().RemoveID<event_flag_t>(id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -15,18 +15,18 @@ SysCallBase sys_lwcond("sys_lwcond");
|
|||
|
||||
void lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name)
|
||||
{
|
||||
std::shared_ptr<lwcond_t> lwc(new lwcond_t(name));
|
||||
std::shared_ptr<lwcond_t> cond(new lwcond_t(name));
|
||||
|
||||
lwcond.lwcond_queue = Emu.GetIdManager().GetNewID(lwc, TYPE_LWCOND);
|
||||
lwcond.lwcond_queue = Emu.GetIdManager().GetNewID(cond, TYPE_LWCOND);
|
||||
}
|
||||
|
||||
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=%d, control=*0x%x, name=0x%llx, arg5=0x%x)", lwcond_id, lwmutex_id, control, name, arg5);
|
||||
|
||||
std::shared_ptr<lwcond_t> lwc(new lwcond_t(name));
|
||||
std::shared_ptr<lwcond_t> cond(new lwcond_t(name));
|
||||
|
||||
*lwcond_id = Emu.GetIdManager().GetNewID(lwc, TYPE_LWCOND);
|
||||
*lwcond_id = Emu.GetIdManager().GetNewID(cond, TYPE_LWCOND);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -37,39 +37,177 @@ s32 _sys_lwcond_destroy(u32 lwcond_id)
|
|||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<lwcond_t> lwc;
|
||||
if (!Emu.GetIdManager().GetIDData(lwcond_id, lwc))
|
||||
std::shared_ptr<lwcond_t> cond;
|
||||
if (!Emu.GetIdManager().GetIDData(lwcond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if (lwc->waiters)
|
||||
if (cond->waiters)
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(lwcond_id);
|
||||
Emu.GetIdManager().RemoveID<lwcond_t>(lwcond_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mode)
|
||||
{
|
||||
sys_lwcond.Fatal("_sys_lwcond_signal(lwcond_id=%d, lwmutex_id=%d, ppu_thread_id=%d, mode=%d)", lwcond_id, lwmutex_id, ppu_thread_id, mode);
|
||||
sys_lwcond.Log("_sys_lwcond_signal(lwcond_id=%d, lwmutex_id=%d, ppu_thread_id=%d, mode=%d)", lwcond_id, lwmutex_id, ppu_thread_id, mode);
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<lwcond_t> cond;
|
||||
if (!Emu.GetIdManager().GetIDData(lwcond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
// lwmutex_id, ppu_thread_id are ignored in current implementation
|
||||
|
||||
if (mode != 1 && mode != 2 && mode != 3)
|
||||
{
|
||||
sys_lwcond.Error("_sys_lwcond_signal(%d): invalid mode (%d)", lwcond_id, mode);
|
||||
}
|
||||
|
||||
if (~ppu_thread_id)
|
||||
{
|
||||
sys_lwcond.Todo("_sys_lwcond_signal(%d): ppu_thread_id (%d)", lwcond_id, ppu_thread_id);
|
||||
}
|
||||
|
||||
if (mode == 1)
|
||||
{
|
||||
// mode 1: lightweight mutex was initially owned by the calling thread
|
||||
|
||||
if (!cond->waiters)
|
||||
{
|
||||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
cond->signaled1++;
|
||||
}
|
||||
else if (mode == 2)
|
||||
{
|
||||
// mode 2: lightweight mutex was not owned by the calling thread and waiter hasn't been increased
|
||||
|
||||
if (!cond->waiters)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
cond->signaled2++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// in mode 3, lightweight mutex was forcefully owned by the calling thread
|
||||
|
||||
if (!cond->waiters)
|
||||
{
|
||||
return ~ppu_thread_id ? CELL_ENOENT : CELL_EPERM;
|
||||
}
|
||||
|
||||
cond->signaled1++;
|
||||
}
|
||||
|
||||
cond->waiters--;
|
||||
cond->cv.notify_one();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode)
|
||||
{
|
||||
sys_lwcond.Fatal("_sys_lwcond_signal_all(lwcond_id=%d, lwmutex_id=%d, mode=%d)", lwcond_id, lwmutex_id, mode);
|
||||
sys_lwcond.Log("_sys_lwcond_signal_all(lwcond_id=%d, lwmutex_id=%d, mode=%d)", lwcond_id, lwmutex_id, mode);
|
||||
|
||||
return CELL_OK;
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<lwcond_t> cond;
|
||||
if (!Emu.GetIdManager().GetIDData(lwcond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
// lwmutex_id is ignored in current implementation
|
||||
|
||||
if (mode != 1 && mode != 2)
|
||||
{
|
||||
sys_lwcond.Error("_sys_lwcond_signal_all(%d): invalid mode (%d)", lwcond_id, mode);
|
||||
}
|
||||
|
||||
const s32 count = cond->waiters.exchange(0);
|
||||
cond->cv.notify_all();
|
||||
|
||||
if (mode == 1)
|
||||
{
|
||||
// in mode 1, lightweight mutex was initially owned by the calling thread
|
||||
|
||||
cond->signaled1 += count;
|
||||
|
||||
return count;
|
||||
}
|
||||
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(u32 lwcond_id, u32 lwmutex_id, u64 timeout)
|
||||
{
|
||||
sys_lwcond.Fatal("_sys_lwcond_queue_wait(lwcond_id=%d, lwmutex_id=%d, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout);
|
||||
sys_lwcond.Log("_sys_lwcond_queue_wait(lwcond_id=%d, lwmutex_id=%d, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout);
|
||||
|
||||
return CELL_OK;
|
||||
const u64 start_time = get_system_time();
|
||||
|
||||
LV2_LOCK;
|
||||
|
||||
std::shared_ptr<lwcond_t> cond;
|
||||
if (!Emu.GetIdManager().GetIDData(lwcond_id, cond))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
// lwmutex_id, protocol are ignored in current implementation
|
||||
cond->waiters++; assert(cond->waiters > 0);
|
||||
|
||||
while (!cond->signaled1 && !cond->signaled2)
|
||||
{
|
||||
const bool is_timedout = timeout && get_system_time() - start_time > timeout;
|
||||
|
||||
// check timeout (TODO)
|
||||
if (is_timedout)
|
||||
{
|
||||
sys_lwcond.Fatal("_sys_lwcond_queue_wait(%d): TIMED OUT", lwcond_id);
|
||||
|
||||
// cancel waiting
|
||||
cond->waiters--; assert(cond->waiters >= 0);
|
||||
|
||||
return CELL_ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
sys_lwcond.Warning("_sys_lwcond_queue_wait(lwcond_id=%d) aborted", lwcond_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
cond->cv.wait_for(lv2_lock, std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
if (cond->signaled1)
|
||||
{
|
||||
cond->signaled1--;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
cond->signaled2--;
|
||||
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ struct lwcond_t
|
|||
{
|
||||
const u64 name;
|
||||
|
||||
std::atomic<u32> signaled1; // mode 1 signals
|
||||
std::atomic<u32> signaled2; // mode 2 signals
|
||||
|
||||
// TODO: use sleep queue
|
||||
std::condition_variable cv;
|
||||
std::atomic<s32> waiters;
|
||||
|
|
|
@ -63,7 +63,7 @@ s32 _sys_lwmutex_destroy(u32 lwmutex_id)
|
|||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(lwmutex_id);
|
||||
Emu.GetIdManager().RemoveID<lwmutex_t>(lwmutex_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ s32 sys_memory_container_destroy(u32 cid)
|
|||
|
||||
// Release the allocated memory and remove the ID.
|
||||
Memory.Free(ct->addr);
|
||||
Emu.GetIdManager().RemoveID(cid);
|
||||
Emu.GetIdManager().RemoveID<MemoryContainerInfo>(cid);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ s32 sys_mmapper_allocate_memory(u32 size, u64 flags, vm::ptr<u32> mem_id)
|
|||
|
||||
// Generate a new mem ID.
|
||||
std::shared_ptr<mmapper_info> info(new mmapper_info(size, flags));
|
||||
*mem_id = Emu.GetIdManager().GetNewID(info);
|
||||
*mem_id = Emu.GetIdManager().GetNewID(info, TYPE_MEM);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ s32 sys_mmapper_free_memory(u32 mem_id)
|
|||
return CELL_ESRCH;
|
||||
|
||||
// Release the allocated memory and remove the ID.
|
||||
Emu.GetIdManager().RemoveID(mem_id);
|
||||
Emu.GetIdManager().RemoveID<mmapper_info>(mem_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ s32 sys_mutex_destroy(u32 mutex_id)
|
|||
return CELL_EPERM;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(mutex_id);
|
||||
Emu.GetIdManager().RemoveID<mutex_t>(mutex_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr<sys_prx_unload_module_optio
|
|||
if (!Emu.GetIdManager().GetIDData(id, prx))
|
||||
return CELL_ESRCH;
|
||||
Memory.Free(prx->address);
|
||||
Emu.GetIdManager().RemoveID(id);
|
||||
Emu.GetIdManager().RemoveID<sys_prx_t>(id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ s32 sys_rwlock_destroy(u32 rw_lock_id)
|
|||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(rw_lock_id);
|
||||
Emu.GetIdManager().RemoveID<rwlock_t>(rw_lock_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ s32 sys_semaphore_destroy(u32 sem)
|
|||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(sem);
|
||||
Emu.GetIdManager().RemoveID<semaphore_t>(sem);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -272,7 +272,7 @@ s32 sys_spu_thread_group_destroy(u32 id)
|
|||
}
|
||||
|
||||
group->state = SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED; // hack
|
||||
Emu.GetIdManager().RemoveID(id);
|
||||
Emu.GetIdManager().RemoveID<spu_group_t>(id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ s32 sys_timer_destroy(u32 timer_id)
|
|||
return CELL_EISCONN;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(timer_id);
|
||||
Emu.GetIdManager().RemoveID<lv2_timer_t>(timer_id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ struct sys_timer_information_t
|
|||
be_t<u32> pad;
|
||||
};
|
||||
|
||||
// "timer_t" conflicts with some definition
|
||||
struct lv2_timer_t
|
||||
{
|
||||
std::weak_ptr<event_queue_t> port; // event queue
|
||||
|
|
Loading…
Add table
Reference in a new issue