rpcsx/rpcs3/Emu/SysCalls/lv2/SC_Semaphore.cpp

116 lines
2.8 KiB
C++
Raw Normal View History

#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
SysCallBase sys_sem("sys_semaphore");
struct semaphore_attr
{
u32 protocol;
u32 pshared;
u64 ipc_key;
int flags;
u32 pad;
char name[8];
};
struct semaphore
{
wxSemaphore sem;
semaphore_attr attr;
int sem_count;
semaphore(int initial_count, int max_count, semaphore_attr attr)
: sem(initial_count, max_count)
, attr(attr)
{
}
};
int sys_semaphore_create(u32 sem_addr, u32 attr_addr, int initial_count, int max_count)
{
2014-02-13 17:59:13 +01:00
sys_sem.Warning("sys_semaphore_create(sem_addr=0x%x, attr_addr=0x%x, initial_count=%d, max_count=%d)",
sem_addr, attr_addr, initial_count, max_count);
if(!Memory.IsGoodAddr(sem_addr) || !Memory.IsGoodAddr(attr_addr)) return CELL_EFAULT;
semaphore_attr attr = (semaphore_attr&)Memory[attr_addr];
attr.protocol = re(attr.protocol);
attr.pshared = re(attr.pshared);
attr.ipc_key = re(attr.ipc_key);
attr.flags = re(attr.flags);
sys_sem.Log("*** protocol = %d", attr.protocol);
sys_sem.Log("*** pshared = %d", attr.pshared);
sys_sem.Log("*** ipc_key = 0x%llx", attr.ipc_key);
sys_sem.Log("*** flags = 0x%x", attr.flags);
sys_sem.Log("*** name = %s", attr.name);
Memory.Write32(sem_addr, sys_sem.GetNewId(new semaphore(initial_count, max_count, attr)));
return CELL_OK;
}
int sys_semaphore_destroy(u32 sem)
{
sys_sem.Log("sys_semaphore_destroy(sem=%d)", sem);
if(!sys_sem.CheckId(sem)) return CELL_ESRCH;
Emu.GetIdManager().RemoveID(sem);
return CELL_OK;
}
int sys_semaphore_wait(u32 sem, u64 timeout)
{
sys_sem.Log("sys_semaphore_wait(sem=0x%x, timeout=0x%llx)", sem, timeout);
semaphore* sem_data = nullptr;
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
2013-11-26 01:28:08 +01:00
sem_data->sem_count = 0; // Reset internal counter for sys_semaphore_get_value.
sem_data->sem.WaitTimeout(timeout ? timeout : INFINITE);
return CELL_OK;
}
int sys_semaphore_trywait(u32 sem)
{
sys_sem.Log("sys_semaphore_trywait(sem=%d)", sem);
semaphore* sem_data = nullptr;
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
2013-11-26 01:28:08 +01:00
sem_data->sem_count = 0; // Reset internal counter for sys_semaphore_get_value.
if(sem_data->sem.TryWait()) return 1;
return CELL_OK;
}
int sys_semaphore_post(u32 sem, int count)
{
sys_sem.Log("sys_semaphore_post(sem=%d, count=%d)", sem, count);
semaphore* sem_data = nullptr;
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
while(count--)
{
sem_data->sem_count++; // Increment internal counter for sys_semaphore_get_value.
sem_data->sem.Post();
}
return CELL_OK;
}
int sys_semaphore_get_value(u32 sem, u32 count_addr)
{
sys_sem.Log("sys_semaphore_get_value(sem=%d, count_addr=0x%x)", sem, count_addr);
semaphore* sem_data = nullptr;
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
Memory.Write32(count_addr, sem_data->sem_count);
return CELL_OK;
}