mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 03:32:55 +00:00
rCriticalSection & rSemaphore removed
SC_Semaphore errors fixed Room for interrupt threads
This commit is contained in:
parent
2fad8039f5
commit
30b8e51234
@ -1,68 +1,5 @@
|
||||
#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()
|
||||
{
|
||||
handle = reinterpret_cast<void*>(new wxTimer());
|
||||
@ -93,17 +30,6 @@ void rMicroSleep(u64 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()
|
||||
{
|
||||
return wxThread::IsMain();
|
||||
|
@ -1,34 +1,5 @@
|
||||
#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
|
||||
{
|
||||
rTimer();
|
||||
@ -43,14 +14,6 @@ private:
|
||||
void rSleep(u32 time);
|
||||
void rMicroSleep(u64 time);
|
||||
|
||||
struct rCriticalSectionLocker
|
||||
{
|
||||
rCriticalSectionLocker(const rCriticalSection& other);
|
||||
~rCriticalSectionLocker();
|
||||
private:
|
||||
void *handle;
|
||||
};
|
||||
|
||||
struct rThread
|
||||
{
|
||||
static bool IsMain();
|
||||
|
@ -85,13 +85,13 @@ void CPUThread::SetName(const std::string& name)
|
||||
|
||||
void CPUThread::Wait(bool wait)
|
||||
{
|
||||
rCriticalSectionLocker lock(m_cs_sync);
|
||||
std::lock_guard<std::mutex> lock(m_cs_sync);
|
||||
m_sync_wait = wait;
|
||||
}
|
||||
|
||||
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_sync_wait = true;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ public:
|
||||
|
||||
u32 m_wait_thread_id;
|
||||
|
||||
rCriticalSection m_cs_sync;
|
||||
std::mutex m_cs_sync;
|
||||
bool m_sync_wait;
|
||||
void Wait(bool wait);
|
||||
void Wait(const CPUThread& thr);
|
||||
|
@ -6,7 +6,6 @@ class CPUThreadManager
|
||||
{
|
||||
std::vector<CPUThread*> m_threads;
|
||||
std::mutex m_mtx_thread;
|
||||
rSemaphore m_sem_task;
|
||||
u32 m_raw_spu_num;
|
||||
|
||||
public:
|
||||
|
@ -900,6 +900,13 @@ public:
|
||||
switch(ch)
|
||||
{
|
||||
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;
|
||||
if (code < 64)
|
||||
@ -933,7 +940,9 @@ public:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
{
|
||||
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_FLIP: m_renderer.m_sem_flip.wait(); break;
|
||||
}
|
||||
@ -41,7 +41,7 @@ public:
|
||||
{
|
||||
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_FLIP: m_renderer.m_sem_flip.post(); break;
|
||||
}
|
||||
|
@ -1877,7 +1877,7 @@ void RSXThread::Task()
|
||||
ConLog.Warning("RSX thread aborted");
|
||||
return;
|
||||
}
|
||||
rCriticalSectionLocker lock(m_cs_main);
|
||||
std::lock_guard<std::mutex> lock(m_cs_main);
|
||||
|
||||
inc=1;
|
||||
|
||||
|
@ -148,7 +148,7 @@ public:
|
||||
u32 m_draw_array_first;
|
||||
|
||||
public:
|
||||
rCriticalSection m_cs_main;
|
||||
std::mutex m_cs_main;
|
||||
SSemaphore m_sem_flush;
|
||||
SSemaphore m_sem_flip;
|
||||
Callback m_flip_handler;
|
||||
|
@ -201,15 +201,15 @@ extern void sys_spinlock_unlock(mem_ptr_t<spinlock> lock);
|
||||
//ppu_thread
|
||||
extern void sys_ppu_thread_exit(u64 errorcode);
|
||||
extern int sys_ppu_thread_yield();
|
||||
extern int sys_ppu_thread_join(u32 thread_id, mem64_t vptr);
|
||||
extern int sys_ppu_thread_detach(u32 thread_id);
|
||||
extern int sys_ppu_thread_join(u64 thread_id, mem64_t vptr);
|
||||
extern int sys_ppu_thread_detach(u64 thread_id);
|
||||
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_get_priority(u32 thread_id, u32 prio_addr);
|
||||
extern int sys_ppu_thread_set_priority(u64 thread_id, int prio);
|
||||
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_stop(u32 thread_id);
|
||||
extern int sys_ppu_thread_restart(u32 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_stop(u64 thread_id);
|
||||
extern int sys_ppu_thread_restart(u64 thread_id);
|
||||
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 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);
|
||||
|
||||
return list.size();
|
||||
u32 result = 0;
|
||||
for (u32 i = 0; i < list.size(); i++)
|
||||
{
|
||||
if (list[i]) result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SleepQueue::finalize()
|
||||
|
@ -10,12 +10,19 @@
|
||||
extern Module *sysPrxForUser;
|
||||
|
||||
static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU;
|
||||
|
||||
enum
|
||||
{
|
||||
SYS_PPU_THREAD_ONCE_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)
|
||||
{
|
||||
sysPrxForUser->Log("sys_ppu_thread_exit(0x%llx)", errorcode);
|
||||
@ -40,7 +47,7 @@ int sys_ppu_thread_yield()
|
||||
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());
|
||||
|
||||
@ -61,7 +68,7 @@ int sys_ppu_thread_join(u32 thread_id, mem64_t vptr)
|
||||
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);
|
||||
|
||||
@ -81,7 +88,7 @@ void sys_ppu_thread_get_join_state(u32 isjoinable_addr)
|
||||
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);
|
||||
|
||||
@ -93,7 +100,7 @@ int sys_ppu_thread_set_priority(u32 thread_id, int prio)
|
||||
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);
|
||||
|
||||
@ -120,7 +127,7 @@ int sys_ppu_thread_get_stack_information(u32 info_addr)
|
||||
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);
|
||||
|
||||
@ -132,7 +139,7 @@ int sys_ppu_thread_stop(u32 thread_id)
|
||||
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);
|
||||
|
||||
@ -145,30 +152,50 @@ int sys_ppu_thread_restart(u32 thread_id)
|
||||
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 = "";
|
||||
if (Memory.IsGoodAddr(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'))",
|
||||
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
|
||||
{
|
||||
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(!Memory.IsGoodAddr(entry) || !Memory.IsGoodAddr(thread_id_addr))
|
||||
if (!Memory.IsGoodAddr(entry) || !thread_id.IsGood())
|
||||
{
|
||||
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);
|
||||
|
||||
Memory.Write64(thread_id_addr, new_thread.GetId());
|
||||
thread_id = new_thread.GetId();
|
||||
new_thread.SetEntry(entry);
|
||||
new_thread.SetArg(0, arg);
|
||||
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.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.Exec();
|
||||
|
@ -17,14 +17,15 @@ int sys_semaphore_create(mem32_t sem, mem_ptr_t<sys_semaphore_attribute> attr, i
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -96,6 +97,7 @@ int sys_semaphore_wait(u32 sem_id, u64 timeout)
|
||||
|
||||
if (timeout && get_system_time() - start_time > timeout)
|
||||
{
|
||||
sem->m_queue.invalidate(tid);
|
||||
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);
|
||||
|
||||
if (tid != sem->signal)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sem->signal = 0;
|
||||
// TODO: notify signaler
|
||||
return CELL_OK;
|
||||
@ -150,9 +156,9 @@ int sys_semaphore_post(u32 sem_id, int count)
|
||||
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)
|
||||
@ -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());
|
||||
|
||||
if (!count.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
Semaphore* sem;
|
||||
if (!Emu.GetIdManager().GetIDData(sem_id, sem))
|
||||
{
|
||||
|
@ -246,7 +246,6 @@
|
||||
<ClInclude Include="Emu\Cell\PPCDisAsm.h" />
|
||||
<ClInclude Include="Emu\Cell\PPCInstrTable.h" />
|
||||
<ClInclude Include="Emu\Cell\PPCThread.h" />
|
||||
<ClInclude Include="Emu\Cell\PPCThreadManager.h" />
|
||||
<ClInclude Include="Emu\Cell\PPUDecoder.h" />
|
||||
<ClInclude Include="Emu\Cell\PPUDisAsm.h" />
|
||||
<ClInclude Include="Emu\Cell\PPUInstrTable.h" />
|
||||
|
@ -850,9 +850,6 @@
|
||||
<ClInclude Include="Emu\Cell\PPCThread.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPCThreadManager.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPUDecoder.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
</ClInclude>
|
||||
|
Loading…
x
Reference in New Issue
Block a user