mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 23:11:25 +12:00
rCriticalSection & rSemaphore removed
SC_Semaphore errors fixed Room for interrupt threads
This commit is contained in:
parent
2fad8039f5
commit
30b8e51234
15 changed files with 84 additions and 148 deletions
|
@ -1,68 +1,5 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
rSemaphore::rSemaphore()
|
|
||||||
{
|
|
||||||
handle = reinterpret_cast<void*>(new wxSemaphore());
|
|
||||||
}
|
|
||||||
|
|
||||||
rSemaphore::~rSemaphore()
|
|
||||||
{
|
|
||||||
delete reinterpret_cast<wxSemaphore*>(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
rSemaphore::rSemaphore(int initial_count, int max_count)
|
|
||||||
{
|
|
||||||
handle = reinterpret_cast<void*>(new wxSemaphore(initial_count,max_count));
|
|
||||||
}
|
|
||||||
|
|
||||||
void rSemaphore::Wait()
|
|
||||||
{
|
|
||||||
reinterpret_cast<wxSemaphore*>(handle)->Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
rSemaStatus rSemaphore::TryWait()
|
|
||||||
{
|
|
||||||
wxSemaError err = reinterpret_cast<wxSemaphore*>(handle)->TryWait();
|
|
||||||
if (err == wxSEMA_BUSY)
|
|
||||||
{
|
|
||||||
return rSEMA_BUSY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return rSEMA_OTHER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rSemaphore::Post()
|
|
||||||
{
|
|
||||||
reinterpret_cast<wxSemaphore*>(handle)->Post();
|
|
||||||
}
|
|
||||||
|
|
||||||
void rSemaphore::WaitTimeout(u64 timeout)
|
|
||||||
{
|
|
||||||
reinterpret_cast<wxSemaphore*>(handle)->WaitTimeout(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
rCriticalSection::rCriticalSection()
|
|
||||||
{
|
|
||||||
handle = reinterpret_cast<void*>(new wxCriticalSection());
|
|
||||||
}
|
|
||||||
|
|
||||||
rCriticalSection::~rCriticalSection()
|
|
||||||
{
|
|
||||||
delete reinterpret_cast<wxCriticalSection*>(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rCriticalSection::Enter()
|
|
||||||
{
|
|
||||||
reinterpret_cast<wxCriticalSection*>(handle)->Enter();
|
|
||||||
}
|
|
||||||
|
|
||||||
void rCriticalSection::Leave()
|
|
||||||
{
|
|
||||||
reinterpret_cast<wxCriticalSection*>(handle)->Leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
rTimer::rTimer()
|
rTimer::rTimer()
|
||||||
{
|
{
|
||||||
handle = reinterpret_cast<void*>(new wxTimer());
|
handle = reinterpret_cast<void*>(new wxTimer());
|
||||||
|
@ -93,17 +30,6 @@ void rMicroSleep(u64 time)
|
||||||
wxMicroSleep(time);
|
wxMicroSleep(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
rCriticalSectionLocker::rCriticalSectionLocker(const rCriticalSection &sec)
|
|
||||||
{
|
|
||||||
handle = reinterpret_cast<void*>(new wxCriticalSectionLocker(*reinterpret_cast<wxCriticalSection*>(sec.handle)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
rCriticalSectionLocker::~rCriticalSectionLocker()
|
|
||||||
{
|
|
||||||
delete reinterpret_cast<wxCriticalSectionLocker*>(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rThread::IsMain()
|
bool rThread::IsMain()
|
||||||
{
|
{
|
||||||
return wxThread::IsMain();
|
return wxThread::IsMain();
|
||||||
|
|
|
@ -1,34 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
enum rSemaStatus
|
|
||||||
{
|
|
||||||
rSEMA_BUSY,
|
|
||||||
rSEMA_OTHER
|
|
||||||
};
|
|
||||||
struct rSemaphore
|
|
||||||
{
|
|
||||||
rSemaphore();
|
|
||||||
rSemaphore(const rSemaphore& other) = delete;
|
|
||||||
~rSemaphore();
|
|
||||||
rSemaphore(int initial_count, int max_count);
|
|
||||||
void Wait();
|
|
||||||
rSemaStatus TryWait();
|
|
||||||
void Post();
|
|
||||||
void WaitTimeout(u64 timeout);
|
|
||||||
private:
|
|
||||||
void *handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rCriticalSection
|
|
||||||
{
|
|
||||||
rCriticalSection();
|
|
||||||
rCriticalSection(const rCriticalSection& other) = delete;
|
|
||||||
~rCriticalSection();
|
|
||||||
void Enter();
|
|
||||||
void Leave();
|
|
||||||
void *handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rTimer
|
struct rTimer
|
||||||
{
|
{
|
||||||
rTimer();
|
rTimer();
|
||||||
|
@ -43,14 +14,6 @@ private:
|
||||||
void rSleep(u32 time);
|
void rSleep(u32 time);
|
||||||
void rMicroSleep(u64 time);
|
void rMicroSleep(u64 time);
|
||||||
|
|
||||||
struct rCriticalSectionLocker
|
|
||||||
{
|
|
||||||
rCriticalSectionLocker(const rCriticalSection& other);
|
|
||||||
~rCriticalSectionLocker();
|
|
||||||
private:
|
|
||||||
void *handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rThread
|
struct rThread
|
||||||
{
|
{
|
||||||
static bool IsMain();
|
static bool IsMain();
|
||||||
|
|
|
@ -85,13 +85,13 @@ void CPUThread::SetName(const std::string& name)
|
||||||
|
|
||||||
void CPUThread::Wait(bool wait)
|
void CPUThread::Wait(bool wait)
|
||||||
{
|
{
|
||||||
rCriticalSectionLocker lock(m_cs_sync);
|
std::lock_guard<std::mutex> lock(m_cs_sync);
|
||||||
m_sync_wait = wait;
|
m_sync_wait = wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUThread::Wait(const CPUThread& thr)
|
void CPUThread::Wait(const CPUThread& thr)
|
||||||
{
|
{
|
||||||
rCriticalSectionLocker lock(m_cs_sync);
|
std::lock_guard<std::mutex> lock(m_cs_sync);
|
||||||
m_wait_thread_id = thr.GetId();
|
m_wait_thread_id = thr.GetId();
|
||||||
m_sync_wait = true;
|
m_sync_wait = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ public:
|
||||||
|
|
||||||
u32 m_wait_thread_id;
|
u32 m_wait_thread_id;
|
||||||
|
|
||||||
rCriticalSection m_cs_sync;
|
std::mutex m_cs_sync;
|
||||||
bool m_sync_wait;
|
bool m_sync_wait;
|
||||||
void Wait(bool wait);
|
void Wait(bool wait);
|
||||||
void Wait(const CPUThread& thr);
|
void Wait(const CPUThread& thr);
|
||||||
|
|
|
@ -6,7 +6,6 @@ class CPUThreadManager
|
||||||
{
|
{
|
||||||
std::vector<CPUThread*> m_threads;
|
std::vector<CPUThread*> m_threads;
|
||||||
std::mutex m_mtx_thread;
|
std::mutex m_mtx_thread;
|
||||||
rSemaphore m_sem_task;
|
|
||||||
u32 m_raw_spu_num;
|
u32 m_raw_spu_num;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -900,6 +900,13 @@ public:
|
||||||
switch(ch)
|
switch(ch)
|
||||||
{
|
{
|
||||||
case SPU_WrOutIntrMbox:
|
case SPU_WrOutIntrMbox:
|
||||||
|
if (!group) // if RawSPU
|
||||||
|
{
|
||||||
|
// TODO: run PPU interrupt thread
|
||||||
|
ConLog.Error("SPU_WrOutIntrMbox interrupt unimplemented");
|
||||||
|
Emu.Pause();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
u8 code = v >> 24;
|
u8 code = v >> 24;
|
||||||
if (code < 64)
|
if (code < 64)
|
||||||
|
@ -933,7 +940,9 @@ public:
|
||||||
|
|
||||||
if (!port.eq)
|
if (!port.eq)
|
||||||
{
|
{
|
||||||
SPU.In_MBox.PushUncond(CELL_ENOTCONN); // check error passing
|
// spu_printf fails there
|
||||||
|
ConLog.Warning("sys_spu_thread_send_event(spup=%d, data0=0x%x, data1=0x%x): event queue not connected", spup, v & 0x00ffffff, data);
|
||||||
|
SPU.In_MBox.PushUncond(CELL_ENOTCONN); // TODO: check error passing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
{
|
{
|
||||||
switch(m_type)
|
switch(m_type)
|
||||||
{
|
{
|
||||||
case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.Enter(); break;
|
case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.lock(); break;
|
||||||
case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.wait(); break;
|
case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.wait(); break;
|
||||||
case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.wait(); break;
|
case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.wait(); break;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
{
|
{
|
||||||
switch(m_type)
|
switch(m_type)
|
||||||
{
|
{
|
||||||
case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.Leave(); break;
|
case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.unlock(); break;
|
||||||
case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.post(); break;
|
case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.post(); break;
|
||||||
case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.post(); break;
|
case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.post(); break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1877,7 +1877,7 @@ void RSXThread::Task()
|
||||||
ConLog.Warning("RSX thread aborted");
|
ConLog.Warning("RSX thread aborted");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rCriticalSectionLocker lock(m_cs_main);
|
std::lock_guard<std::mutex> lock(m_cs_main);
|
||||||
|
|
||||||
inc=1;
|
inc=1;
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ public:
|
||||||
u32 m_draw_array_first;
|
u32 m_draw_array_first;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
rCriticalSection m_cs_main;
|
std::mutex m_cs_main;
|
||||||
SSemaphore m_sem_flush;
|
SSemaphore m_sem_flush;
|
||||||
SSemaphore m_sem_flip;
|
SSemaphore m_sem_flip;
|
||||||
Callback m_flip_handler;
|
Callback m_flip_handler;
|
||||||
|
|
|
@ -201,15 +201,15 @@ extern void sys_spinlock_unlock(mem_ptr_t<spinlock> lock);
|
||||||
//ppu_thread
|
//ppu_thread
|
||||||
extern void sys_ppu_thread_exit(u64 errorcode);
|
extern void sys_ppu_thread_exit(u64 errorcode);
|
||||||
extern int sys_ppu_thread_yield();
|
extern int sys_ppu_thread_yield();
|
||||||
extern int sys_ppu_thread_join(u32 thread_id, mem64_t vptr);
|
extern int sys_ppu_thread_join(u64 thread_id, mem64_t vptr);
|
||||||
extern int sys_ppu_thread_detach(u32 thread_id);
|
extern int sys_ppu_thread_detach(u64 thread_id);
|
||||||
extern void sys_ppu_thread_get_join_state(u32 isjoinable_addr);
|
extern void sys_ppu_thread_get_join_state(u32 isjoinable_addr);
|
||||||
extern int sys_ppu_thread_set_priority(u32 thread_id, int prio);
|
extern int sys_ppu_thread_set_priority(u64 thread_id, int prio);
|
||||||
extern int sys_ppu_thread_get_priority(u32 thread_id, u32 prio_addr);
|
extern int sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr);
|
||||||
extern int sys_ppu_thread_get_stack_information(u32 info_addr);
|
extern int sys_ppu_thread_get_stack_information(u32 info_addr);
|
||||||
extern int sys_ppu_thread_stop(u32 thread_id);
|
extern int sys_ppu_thread_stop(u64 thread_id);
|
||||||
extern int sys_ppu_thread_restart(u32 thread_id);
|
extern int sys_ppu_thread_restart(u64 thread_id);
|
||||||
extern int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
|
extern int sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
|
||||||
extern void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry);
|
extern void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry);
|
||||||
extern int sys_ppu_thread_get_id(const u32 id_addr);
|
extern int sys_ppu_thread_get_id(const u32 id_addr);
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,12 @@ u32 SleepQueue::count()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
return list.size();
|
u32 result = 0;
|
||||||
|
for (u32 i = 0; i < list.size(); i++)
|
||||||
|
{
|
||||||
|
if (list[i]) result++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SleepQueue::finalize()
|
bool SleepQueue::finalize()
|
||||||
|
|
|
@ -10,12 +10,19 @@
|
||||||
extern Module *sysPrxForUser;
|
extern Module *sysPrxForUser;
|
||||||
|
|
||||||
static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU;
|
static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SYS_PPU_THREAD_ONCE_INIT,
|
SYS_PPU_THREAD_ONCE_INIT,
|
||||||
SYS_PPU_THREAD_DONE_INIT,
|
SYS_PPU_THREAD_DONE_INIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ppu_thread_flags : u64
|
||||||
|
{
|
||||||
|
SYS_PPU_THREAD_CREATE_JOINABLE = 0x1,
|
||||||
|
SYS_PPU_THREAD_CREATE_INTERRUPT = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
void sys_ppu_thread_exit(u64 errorcode)
|
void sys_ppu_thread_exit(u64 errorcode)
|
||||||
{
|
{
|
||||||
sysPrxForUser->Log("sys_ppu_thread_exit(0x%llx)", errorcode);
|
sysPrxForUser->Log("sys_ppu_thread_exit(0x%llx)", errorcode);
|
||||||
|
@ -40,7 +47,7 @@ int sys_ppu_thread_yield()
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_join(u32 thread_id, mem64_t vptr)
|
int sys_ppu_thread_join(u64 thread_id, mem64_t vptr)
|
||||||
{
|
{
|
||||||
sysPrxForUser->Warning("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr.GetAddr());
|
sysPrxForUser->Warning("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr.GetAddr());
|
||||||
|
|
||||||
|
@ -61,7 +68,7 @@ int sys_ppu_thread_join(u32 thread_id, mem64_t vptr)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_detach(u32 thread_id)
|
int sys_ppu_thread_detach(u64 thread_id)
|
||||||
{
|
{
|
||||||
sysPrxForUser->Error("sys_ppu_thread_detach(thread_id=%d)", thread_id);
|
sysPrxForUser->Error("sys_ppu_thread_detach(thread_id=%d)", thread_id);
|
||||||
|
|
||||||
|
@ -81,7 +88,7 @@ void sys_ppu_thread_get_join_state(u32 isjoinable_addr)
|
||||||
Memory.Write32(isjoinable_addr, GetCurrentPPUThread().IsJoinable());
|
Memory.Write32(isjoinable_addr, GetCurrentPPUThread().IsJoinable());
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_set_priority(u32 thread_id, int prio)
|
int sys_ppu_thread_set_priority(u64 thread_id, int prio)
|
||||||
{
|
{
|
||||||
sysPrxForUser->Log("sys_ppu_thread_set_priority(thread_id=%d, prio=%d)", thread_id, prio);
|
sysPrxForUser->Log("sys_ppu_thread_set_priority(thread_id=%d, prio=%d)", thread_id, prio);
|
||||||
|
|
||||||
|
@ -93,7 +100,7 @@ int sys_ppu_thread_set_priority(u32 thread_id, int prio)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_get_priority(u32 thread_id, u32 prio_addr)
|
int sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr)
|
||||||
{
|
{
|
||||||
sysPrxForUser->Log("sys_ppu_thread_get_priority(thread_id=%d, prio_addr=0x%x)", thread_id, prio_addr);
|
sysPrxForUser->Log("sys_ppu_thread_get_priority(thread_id=%d, prio_addr=0x%x)", thread_id, prio_addr);
|
||||||
|
|
||||||
|
@ -120,7 +127,7 @@ int sys_ppu_thread_get_stack_information(u32 info_addr)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_stop(u32 thread_id)
|
int sys_ppu_thread_stop(u64 thread_id)
|
||||||
{
|
{
|
||||||
sysPrxForUser->Warning("sys_ppu_thread_stop(thread_id=%d)", thread_id);
|
sysPrxForUser->Warning("sys_ppu_thread_stop(thread_id=%d)", thread_id);
|
||||||
|
|
||||||
|
@ -132,7 +139,7 @@ int sys_ppu_thread_stop(u32 thread_id)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_restart(u32 thread_id)
|
int sys_ppu_thread_restart(u64 thread_id)
|
||||||
{
|
{
|
||||||
sysPrxForUser->Warning("sys_ppu_thread_restart(thread_id=%d)", thread_id);
|
sysPrxForUser->Warning("sys_ppu_thread_restart(thread_id=%d)", thread_id);
|
||||||
|
|
||||||
|
@ -145,30 +152,50 @@ int sys_ppu_thread_restart(u32 thread_id)
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr)
|
int sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr)
|
||||||
{
|
{
|
||||||
std::string threadname = "";
|
std::string threadname = "";
|
||||||
if (Memory.IsGoodAddr(threadname_addr))
|
if (Memory.IsGoodAddr(threadname_addr))
|
||||||
{
|
{
|
||||||
threadname = Memory.ReadString(threadname_addr);
|
threadname = Memory.ReadString(threadname_addr);
|
||||||
sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))",
|
sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))",
|
||||||
thread_id_addr, entry, arg, prio, stacksize, flags, threadname_addr, threadname.c_str());
|
thread_id.GetAddr(), entry, arg, prio, stacksize, flags, threadname_addr, threadname.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x)",
|
sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x)",
|
||||||
thread_id_addr, entry, arg, prio, stacksize, flags, threadname_addr);
|
thread_id.GetAddr(), entry, arg, prio, stacksize, flags, threadname_addr);
|
||||||
if (threadname_addr != 0) return CELL_EFAULT;
|
if (threadname_addr != 0) return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Memory.IsGoodAddr(entry) || !Memory.IsGoodAddr(thread_id_addr))
|
if (!Memory.IsGoodAddr(entry) || !thread_id.IsGood())
|
||||||
{
|
{
|
||||||
return CELL_EFAULT;
|
return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_joinable = false;
|
||||||
|
bool is_interrupt = false;
|
||||||
|
|
||||||
|
switch (flags)
|
||||||
|
{
|
||||||
|
case 0: break;
|
||||||
|
case SYS_PPU_THREAD_CREATE_JOINABLE:
|
||||||
|
{
|
||||||
|
is_joinable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SYS_PPU_THREAD_CREATE_INTERRUPT:
|
||||||
|
{
|
||||||
|
sysPrxForUser->Error("sys_ppu_thread_create: unimplemented flag (SYS_PPU_THREAD_CREATE_INTERRUPT)");
|
||||||
|
is_interrupt = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: sysPrxForUser->Error("sys_ppu_thread_create(): unknown flags value (0x%llx)", flags); return CELL_EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||||
|
|
||||||
Memory.Write64(thread_id_addr, new_thread.GetId());
|
thread_id = new_thread.GetId();
|
||||||
new_thread.SetEntry(entry);
|
new_thread.SetEntry(entry);
|
||||||
new_thread.SetArg(0, arg);
|
new_thread.SetArg(0, arg);
|
||||||
new_thread.SetPrio(prio);
|
new_thread.SetPrio(prio);
|
||||||
|
@ -176,7 +203,7 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u64 arg, int prio, u32
|
||||||
//new_thread.flags = flags;
|
//new_thread.flags = flags;
|
||||||
new_thread.SetName(threadname);
|
new_thread.SetName(threadname);
|
||||||
|
|
||||||
ConLog.Write("*** New PPU Thread [%s] (): id = %d", new_thread.GetName().c_str(), new_thread.GetId());
|
ConLog.Write("*** New PPU Thread [%s] (flags=0x%llx, entry=0x%x): id = %d", new_thread.GetName().c_str(), flags, entry, new_thread.GetId());
|
||||||
|
|
||||||
new_thread.Run();
|
new_thread.Run();
|
||||||
new_thread.Exec();
|
new_thread.Exec();
|
||||||
|
|
|
@ -17,14 +17,15 @@ int sys_semaphore_create(mem32_t sem, mem_ptr_t<sys_semaphore_attribute> attr, i
|
||||||
return CELL_EFAULT;
|
return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_count <= 0)
|
if (max_count <= 0 || initial_count > max_count || initial_count < 0)
|
||||||
{
|
{
|
||||||
|
sys_sem.Error("sys_semaphore_create(): invalid parameters (initial_count=%d, max_count=%d)", initial_count, max_count);
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->pshared.ToBE() != se32(0x200))
|
if (attr->pshared.ToBE() != se32(0x200))
|
||||||
{
|
{
|
||||||
sys_sem.Error("Invalid pshared attribute(0x%x)", (u32)attr->pshared);
|
sys_sem.Error("sys_semaphore_create(): invalid pshared value(0x%x)", (u32)attr->pshared);
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +97,7 @@ int sys_semaphore_wait(u32 sem_id, u64 timeout)
|
||||||
|
|
||||||
if (timeout && get_system_time() - start_time > timeout)
|
if (timeout && get_system_time() - start_time > timeout)
|
||||||
{
|
{
|
||||||
|
sem->m_queue.invalidate(tid);
|
||||||
return CELL_ETIMEDOUT;
|
return CELL_ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +105,10 @@ int sys_semaphore_wait(u32 sem_id, u64 timeout)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(sem->m_mutex);
|
std::lock_guard<std::mutex> lock(sem->m_mutex);
|
||||||
|
|
||||||
|
if (tid != sem->signal)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
sem->signal = 0;
|
sem->signal = 0;
|
||||||
// TODO: notify signaler
|
// TODO: notify signaler
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
@ -150,9 +156,9 @@ int sys_semaphore_post(u32 sem_id, int count)
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count + sem->m_value - sem->m_queue.count() > sem->max)
|
if (count + sem->m_value - (int)sem->m_queue.count() > sem->max)
|
||||||
{
|
{
|
||||||
return CELL_EINVAL;
|
return CELL_EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
|
@ -191,6 +197,11 @@ int sys_semaphore_get_value(u32 sem_id, mem32_t count)
|
||||||
{
|
{
|
||||||
sys_sem.Log("sys_semaphore_get_value(sem_id=%d, count_addr=0x%x)", sem_id, count.GetAddr());
|
sys_sem.Log("sys_semaphore_get_value(sem_id=%d, count_addr=0x%x)", sem_id, count.GetAddr());
|
||||||
|
|
||||||
|
if (!count.IsGood())
|
||||||
|
{
|
||||||
|
return CELL_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
Semaphore* sem;
|
Semaphore* sem;
|
||||||
if (!Emu.GetIdManager().GetIDData(sem_id, sem))
|
if (!Emu.GetIdManager().GetIDData(sem_id, sem))
|
||||||
{
|
{
|
||||||
|
|
|
@ -246,7 +246,6 @@
|
||||||
<ClInclude Include="Emu\Cell\PPCDisAsm.h" />
|
<ClInclude Include="Emu\Cell\PPCDisAsm.h" />
|
||||||
<ClInclude Include="Emu\Cell\PPCInstrTable.h" />
|
<ClInclude Include="Emu\Cell\PPCInstrTable.h" />
|
||||||
<ClInclude Include="Emu\Cell\PPCThread.h" />
|
<ClInclude Include="Emu\Cell\PPCThread.h" />
|
||||||
<ClInclude Include="Emu\Cell\PPCThreadManager.h" />
|
|
||||||
<ClInclude Include="Emu\Cell\PPUDecoder.h" />
|
<ClInclude Include="Emu\Cell\PPUDecoder.h" />
|
||||||
<ClInclude Include="Emu\Cell\PPUDisAsm.h" />
|
<ClInclude Include="Emu\Cell\PPUDisAsm.h" />
|
||||||
<ClInclude Include="Emu\Cell\PPUInstrTable.h" />
|
<ClInclude Include="Emu\Cell\PPUInstrTable.h" />
|
||||||
|
|
|
@ -850,9 +850,6 @@
|
||||||
<ClInclude Include="Emu\Cell\PPCThread.h">
|
<ClInclude Include="Emu\Cell\PPCThread.h">
|
||||||
<Filter>Emu\Cell</Filter>
|
<Filter>Emu\Cell</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Emu\Cell\PPCThreadManager.h">
|
|
||||||
<Filter>Emu\Cell</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Emu\Cell\PPUDecoder.h">
|
<ClInclude Include="Emu\Cell\PPUDecoder.h">
|
||||||
<Filter>Emu\Cell</Filter>
|
<Filter>Emu\Cell</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue