rCriticalSection & rSemaphore removed

SC_Semaphore errors fixed
Room for interrupt threads
This commit is contained in:
Nekotekina 2014-06-22 14:59:28 +04:00
parent 2fad8039f5
commit 30b8e51234
15 changed files with 84 additions and 148 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -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:

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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()

View File

@ -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();

View File

@ -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))
{

View File

@ -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" />

View File

@ -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>