Merge pull request #70 from Nekotekina/rpcs3

and conflicts fixed.
This commit is contained in:
Alexandro Sánchez Bach 2014-02-13 12:13:05 +01:00
parent 5953781c13
commit 373d189edb
29 changed files with 1231 additions and 479 deletions

View File

@ -132,10 +132,12 @@ public:
bool HasID(const s64 id)
{
std::lock_guard<std::mutex> lock(m_mtx_main);
{
std::lock_guard<std::mutex> lock(m_mtx_main);
if(id == wxID_ANY)
return m_id_map.begin() != m_id_map.end();
if(id == wxID_ANY)
return m_id_map.begin() != m_id_map.end();
}
return CheckID(id);
}

View File

@ -1,5 +1,4 @@
#pragma once
#include <atomic>
extern void SM_Sleep();
extern DWORD SM_GetCurrentThreadId();
@ -49,6 +48,10 @@ public:
SMutexResult trylock(T tid)
{
if (Emu.IsStopped())
{
return SMR_ABORT;
}
T old = (T)free_value;
if (!owner.compare_exchange_strong(old, tid))
@ -57,15 +60,10 @@ public:
{
return SMR_DEADLOCK;
}
if (Emu.IsStopped())
{
return SMR_ABORT;
}
if (old == (T)dead_value)
{
return SMR_DESTROYED;
}
return SMR_FAILED;
}
@ -74,6 +72,10 @@ public:
SMutexResult unlock(T tid, T to = (T)free_value)
{
if (Emu.IsStopped())
{
return SMR_ABORT;
}
T old = tid;
if (!owner.compare_exchange_strong(old, to))

View File

@ -111,7 +111,7 @@ thread::thread()
}
void thread::start(std::function<void()> func)
{
{ // got a crash related with strings
m_thr = std::thread([this, func]() { NamedThreadBase info(m_name); g_tls_this_thread = &info; func(); });
}

View File

@ -93,6 +93,8 @@ CPUThread* CPUThreadManager::GetThread(u32 id)
{
CPUThread* res;
if (!id) return nullptr;
if (!Emu.GetIdManager().GetIDData(id, res)) return nullptr;
return res;

View File

@ -601,13 +601,16 @@ public:
u32 GetChannelCount(u32 ch)
{
u32 count;
switch(ch)
{
case SPU_WrOutMbox:
return SPU.Out_MBox.GetFreeCount();
case SPU_RdInMbox:
return SPU.In_MBox.GetCount();
count = SPU.In_MBox.GetCount();
ConLog.Warning("GetChannelCount(%s) -> %d", spu_ch_name[ch], count);
return count;
case SPU_WrOutIntrMbox:
ConLog.Warning("GetChannelCount(%s) = 0", spu_ch_name[ch]);
@ -688,6 +691,8 @@ public:
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
break;
}
if (Emu.IsStopped()) ConLog.Warning("%s: %s writing aborted", __FUNCTION__, spu_ch_name[ch]);
}
void ReadChannel(SPU_GPR_hdr& r, u32 ch)
@ -725,6 +730,8 @@ public:
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
break;
}
if (Emu.IsStopped()) ConLog.Warning("%s: %s aborted", __FUNCTION__, spu_ch_name[ch]);
}
bool IsGoodLSA(const u32 lsa) const { return Memory.IsGoodAddr(lsa + m_offset) && lsa < 0x40000; }

61
rpcs3/Emu/Event.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "stdafx.h"
#include "event.h"
void EventManager::Init()
{
}
void EventManager::Clear()
{
key_map.clear();
}
bool EventManager::CheckKey(u64 key)
{
if (!key) return true;
SMutexLocker lock(m_lock);
return key_map.find(key) != key_map.end();
}
bool EventManager::RegisterKey(EventQueue* data, u64 key)
{
if (!key) return true;
SMutexLocker lock(m_lock);
if (key_map.find(key) != key_map.end()) return false;
key_map[key] = data;
return true;
}
bool EventManager::GetEventQueue(u64 key, EventQueue*& data)
{
data = nullptr;
if (!key) return false;
SMutexLocker lock(m_lock);
auto f = key_map.find(key);
if (f != key_map.end())
{
data = f->second;
return true;
}
return false;
}
bool EventManager::UnregisterKey(u64 key)
{
if (!key) return false;
SMutexLocker lock(m_lock);
auto f = key_map.find(key);
if (f != key_map.end())
{
key_map.erase(f);
return true;
}
return false;
}

View File

@ -4,8 +4,9 @@
#include "Emu/Audio/cellAudio.h"
void cellAudio_init();
void cellAudio_load();
void cellAudio_unload();
Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload);
Module cellAudio(0x0011, cellAudio_init, cellAudio_load, cellAudio_unload);
enum
{
@ -80,16 +81,66 @@ struct CellAudioPortConfig
be_t<u32> portAddr;
};
struct CellAudioConfig //custom structure
struct AudioPortConfig
{
bool m_is_audio_initialized;
bool m_is_audio_port_opened;
bool m_is_audio_port_started;
CellAudioPortParam m_param;
const u32 m_buffer; // 64 KB or 128 KB with 8x16 config
const u32 m_index;
AudioPortConfig();
~AudioPortConfig();
};
CellAudioPortParam* m_param = new CellAudioPortParam;
struct AudioConfig //custom structure
{
Array<AudioPortConfig*> m_ports;
bool m_is_audio_initialized;
u32 m_port_in_use;
u64 event_key;
CellAudioConfig* m_config = new CellAudioConfig;
AudioConfig()
: m_is_audio_initialized(false)
, m_port_in_use(0)
, event_key(0)
{
m_ports.SetCount(8);
for (u32 i = 0; i < m_ports.GetCount(); i++)
m_ports[i] = nullptr;
}
void Clear()
{
for (u32 i = 0; i < m_ports.GetCount(); i++)
{
if (m_ports[i])
{
delete m_ports[i];
m_ports[i] = nullptr;
}
}
m_port_in_use = 0;
}
} m_config;
AudioPortConfig::AudioPortConfig()
: m_is_audio_port_started(false)
, m_buffer(Memory.Alloc(1024 * 128, 1024))
, m_index(Memory.Alloc(16, 16))
{
m_config.m_port_in_use++;
mem64_t index(m_index);
index = 0;
}
AudioPortConfig::~AudioPortConfig()
{
m_config.m_port_in_use--;
Memory.Free(m_buffer);
Memory.Free(m_index);
}
//libmixer datatypes
typedef void * CellAANHandle;
@ -197,68 +248,94 @@ struct CellSoundSynth2EffectAttr
int cellAudioInit()
{
cellAudio.Warning("cellAudioInit()");
if(m_config->m_is_audio_initialized == true) return CELL_AUDIO_ERROR_ALREADY_INIT;
m_config->m_is_audio_initialized = true;
if (m_config.m_is_audio_initialized)
{
return CELL_AUDIO_ERROR_ALREADY_INIT;
}
m_config.m_is_audio_initialized = true;
return CELL_OK;
}
int cellAudioQuit()
{
cellAudio.Warning("cellAudioQuit()");
if (m_config->m_is_audio_initialized == false) return CELL_AUDIO_ERROR_NOT_INIT;
m_config->m_is_audio_initialized = false;
if (!m_config.m_is_audio_initialized)
{
return CELL_AUDIO_ERROR_NOT_INIT;
}
m_config.m_is_audio_initialized = false;
return CELL_OK;
}
int cellAudioPortOpen(mem_ptr_t<CellAudioPortParam> audioParam, mem32_t portNum)
{
cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x,portNum_addr=0x%x)",audioParam.GetAddr(),portNum.GetAddr());
cellAudio.Warning("cellAudioPortOpen(audioParam_addr=0x%x, portNum_addr=0x%x)", audioParam.GetAddr(), portNum.GetAddr());
if(!audioParam.IsGood() || !portNum.IsGood()) return CELL_AUDIO_ERROR_PORT_OPEN;
m_config->m_is_audio_port_opened = true;
m_param->nChannel = audioParam->nChannel;
m_param->nBlock = audioParam->nBlock;
m_param->attr = audioParam->attr;
m_param->level = audioParam->level;
//TODO: implementation of ring buffer
return CELL_OK;
}
int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfig)
{
cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x,portConfig_addr=0x%x)",portNum,portConfig.GetAddr());
if(!portConfig.IsGood())
if(!audioParam.IsGood() || !portNum.IsGood())
{
return CELL_AUDIO_ERROR_PARAM;
}
//if(portNum > 7) return CELL_AUDIO_ERROR_PORT_FULL;
if(!m_config->m_is_audio_port_opened)
if (m_config.m_port_in_use >= m_config.m_ports.GetCount())
{
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
return CELL_OK;
return CELL_AUDIO_ERROR_PORT_FULL;
}
if(m_config->m_is_audio_port_started)
for (u32 i = 0; i < m_config.m_ports.GetCount(); i++)
{
if (m_config.m_ports[i] == nullptr)
{
CellAudioPortParam& ref = (m_config.m_ports[i] = new AudioPortConfig)->m_param;
ref.nChannel = audioParam->nChannel;
ref.nBlock = audioParam->nBlock;
ref.attr = audioParam->attr;
ref.level = audioParam->level;
portNum = i;
cellAudio.Warning("*** audio port opened(nChannel=%lld, nBlock=0x%llx, attr=0x%llx, level=%f): port = %d",
(u64)ref.nChannel, (u64)ref.nBlock, (u64)ref.attr, (float)ref.level, portNum.GetValue());
//TODO: implementation of ring buffer
return CELL_OK;
}
}
return CELL_AUDIO_ERROR_PORT_FULL;
}
int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfig)
{
cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig_addr=0x%x)", portNum, portConfig.GetAddr());
if (!portConfig.IsGood() || portNum >= m_config.m_ports.GetCount())
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum])
{
portConfig->status = CELL_AUDIO_STATUS_CLOSE;
}
else if (m_config.m_ports[portNum]->m_is_audio_port_started)
{
portConfig->status = CELL_AUDIO_STATUS_RUN;
}
else
{
CellAudioPortParam& ref = m_config.m_ports[portNum]->m_param;
portConfig->status = CELL_AUDIO_STATUS_READY;
portConfig->nChannel = m_param->nChannel;
portConfig->nBlock = m_param->nBlock;
portConfig->portSize = sizeof(float)*256*(m_param->nChannel)*(m_param->nBlock);
portConfig->portAddr = Memory.Alloc(portConfig->portSize, 4); // 0x20020000 WARNING: Memory leak.
portConfig->readIndexAddr = Memory.Alloc(m_param->nBlock, 4); // 0x20010010 on ps3 WARNING: Memory leak.
portConfig->nChannel = ref.nChannel;
portConfig->nBlock = ref.nBlock;
portConfig->portSize = ref.nChannel * ref.nBlock * 256;
portConfig->portAddr = m_config.m_ports[portNum]->m_buffer; // 0x20020000
portConfig->readIndexAddr = m_config.m_ports[portNum]->m_index; // 0x20010010 on ps3
// portAddr - readIndexAddr == 0xFFF0 on ps3
Memory.Write64(portConfig->readIndexAddr, 1);
// Memory.Write64(portConfig->readIndexAddr, 1);
}
return CELL_OK;
@ -266,23 +343,43 @@ int cellAudioGetPortConfig(u32 portNum, mem_ptr_t<CellAudioPortConfig> portConfi
int cellAudioPortStart(u32 portNum)
{
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)",portNum);
cellAudio.Warning("cellAudioPortStart(portNum=0x%x)", portNum);
if (!m_config->m_is_audio_port_opened)
if (portNum >= m_config.m_ports.GetCount())
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum])
{
return CELL_AUDIO_ERROR_PORT_OPEN;
}
if (m_config.m_ports[portNum]->m_is_audio_port_started)
{
return CELL_AUDIO_ERROR_PORT_ALREADY_RUN;
}
m_config->m_is_audio_port_started = true;
m_config.m_ports[portNum]->m_is_audio_port_started = true;
return CELL_OK;
}
int cellAudioPortClose(u32 portNum)
{
cellAudio.Warning("cellAudioPortClose(portNum=0x%x)",portNum);
if (!m_config->m_is_audio_port_opened)
cellAudio.Warning("cellAudioPortClose(portNum=0x%x)", portNum);
if (portNum >= m_config.m_ports.GetCount())
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum])
{
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
m_config->m_is_audio_port_opened = false;
}
delete m_config.m_ports[portNum];
m_config.m_ports[portNum] = nullptr;
return CELL_OK;
}
@ -290,123 +387,131 @@ int cellAudioPortStop(u32 portNum)
{
cellAudio.Warning("cellAudioPortStop(portNum=0x%x)",portNum);
if (m_config->m_is_audio_port_started == false)
if (portNum >= m_config.m_ports.GetCount())
{
return CELL_AUDIO_ERROR_PARAM;
}
if (!m_config.m_ports[portNum])
{
return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
}
if (!m_config.m_ports[portNum]->m_is_audio_port_started)
{
return CELL_AUDIO_ERROR_PORT_NOT_RUN;
}
m_config->m_is_audio_port_started = false;
m_config.m_ports[portNum]->m_is_audio_port_started = false;
return CELL_OK;
}
int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp)
{
cellAudio.Warning("cellAudioGetPortTimestamp(portNum=0x%x,tag=0x%x,stamp=0x%x)",portNum,tag,stamp.GetAddr());
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp_addr=0x%x)", portNum, tag, stamp.GetAddr());
return CELL_OK;
}
int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, mem64_t tag)
{
cellAudio.Warning("cellAudioGetPortBlockTag(portNum=0x%x,blockNo=0x%x,tag=0x%x)",portNum,blockNo,tag.GetAddr());
UNIMPLEMENTED_FUNC (cellAudio);
cellAudio.Error("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag_addr=0x%x)", portNum, blockNo, tag.GetAddr());
return CELL_OK;
}
int cellAudioSetPortLevel(u32 portNum, float level)
{
cellAudio.Warning("cellAudioSetPortLevel(portNum=0x%x,level=0x%x)",portNum,level);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level);
return CELL_OK;
}
// Utility Functions
int cellAudioCreateNotifyEventQueue(mem32_t id, mem64_t key)
{
cellAudio.Warning("cellAudioCreateNotifyEventQueue(id=0x%x,key=0x%x)",id.GetAddr(),key.GetAddr());
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.GetAddr(), key.GetAddr());
return CELL_OK;
}
int cellAudioCreateNotifyEventQueueEx(mem32_t id, mem64_t key, u32 iFlags)
{
cellAudio.Warning("cellAudioCreateNotifyEventQueueEx(id=0x%x,key=0x%x,iFlags=0x%x)",id.GetAddr(),key.GetAddr(),iFlags);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioCreateNotifyEventQueueEx(id_addr=0x%x, key_addr=0x%x, iFlags=0x%x)", id.GetAddr(), key.GetAddr(), iFlags);
return CELL_OK;
}
int cellAudioSetNotifyEventQueue(u64 key)
{
cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%x)",key);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
m_config.event_key = key;
EventQueue* eq;
if (!Emu.GetEventManager().GetEventQueue(key, eq))
{
return CELL_AUDIO_ERROR_PARAM;
}
eq->events.push(0, 0, 0, 0);
eq->events.push(0, 0, 0, 0);
return CELL_OK;
}
int cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.Warning("cellAudioSetNotifyEventQueueEx(key=0x%x,iFlags=0x%x)",key,iFlags);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
return CELL_OK;
}
int cellAudioRemoveNotifyEventQueue(u64 key)
{
cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%x)",key);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
return CELL_OK;
}
int cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
{
cellAudio.Warning("cellAudioRemoveNotifyEventQueueEx(key=0x%x,iFlags=0x%x)",key,iFlags);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
return CELL_OK;
}
int cellAudioAddData(u32 portNum, mem32_t src, uint samples, float volume)
int cellAudioAddData(u32 portNum, mem32_t src, u32 samples, float volume)
{
cellAudio.Warning("cellAudioAddData(portNum=0x%x,src=0x%x,samples=0x%x,volume=0x%x)",portNum,src.GetAddr(),samples,volume);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioAddData(portNum=0x%x, src_addr=0x%x, samples=%d, volume=%f)", portNum, src.GetAddr(), samples, volume);
return CELL_OK;
}
int cellAudioAdd2chData(u32 portNum, mem32_t src, uint samples, float volume)
int cellAudioAdd2chData(u32 portNum, mem32_t src, u32 samples, float volume)
{
cellAudio.Warning("cellAudioAdd2chData(portNum=0x%x,src=0x%x,samples=0x%x,volume=0x%x)",portNum,src.GetAddr(),samples,volume);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioAdd2chData(portNum=0x%x, src_addr=0x%x, samples=%d, volume=%f)", portNum, src.GetAddr(), samples, volume);
return CELL_OK;
}
int cellAudioAdd6chData(u32 portNum, mem32_t src, float volume)
{
cellAudio.Warning("cellAudioAdd6chData(portNum=0x%x,src=0x%x,volume=0x%x)",portNum,src.GetAddr(),volume);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioAdd6chData(portNum=0x%x, src_addr=0x%x, volume=%f)", portNum, src.GetAddr(), volume);
return CELL_OK;
}
int cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
{
cellAudio.Warning("cellAudioMiscSetAccessoryVolume(devNum=0x%x,volume=0x%x)",devNum,volume);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioMiscSetAccessoryVolume(devNum=0x%x, volume=%f)", devNum, volume);
return CELL_OK;
}
int cellAudioSendAck(u64 data3)
{
cellAudio.Warning("cellAudioSendAck(data3=0x%x)",data3);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioSendAck(data3=0x%llx)", data3);
return CELL_OK;
}
int cellAudioSetPersonalDevice(int iPersonalStream, int iDevice)
{
cellAudio.Warning("cellAudioSetPersonalDevice(iPersonalStream=0x%x,iDevice=0x%x)",iPersonalStream,iDevice);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioSetPersonalDevice(iPersonalStream=0x%x, iDevice=0x%x)", iPersonalStream, iDevice);
return CELL_OK;
}
int cellAudioUnsetPersonalDevice(int iPersonalStream)
{
cellAudio.Warning("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)",iPersonalStream);
UNIMPLEMENTED_FUNC(cellAudio);
cellAudio.Error("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)", iPersonalStream);
return CELL_OK;
}
@ -1013,9 +1118,14 @@ void cellAudio_init()
//TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions
}
void cellAudio_load()
{
m_config.m_is_audio_initialized = false;
m_config.Clear();
}
void cellAudio_unload()
{
m_config->m_is_audio_initialized = false;
m_config->m_is_audio_port_opened = false;
m_config->m_is_audio_port_started = false;
m_config.m_is_audio_initialized = false;
m_config.Clear();
}

View File

@ -115,7 +115,7 @@ int sdata_unpack(wxString packed_file, wxString unpacked_file)
int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
{
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Warning("cellFsSdataOpen(path: %s, flags: 0x%x, fd_addr: 0x%x, arg_addr: 0x%x, size: 0x%llx)",
sys_fs.Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx)",
path.wx_str(), flags, fd.GetAddr(), arg.GetAddr(), size);
if (!fd.IsGood() || (!arg.IsGood() && size))
@ -179,7 +179,7 @@ void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*
if(func)
func.async(aio, error, xid, res);
ConLog.Warning("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=%d, res=%d, xid=%d [%s])",
ConLog.Warning("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, res=0x%x, xid=0x%x [%s])",
fd, (u64)aio->offset, buf_addr, (u64)aio->size, res, xid, path.wx_str());
}

View File

@ -86,9 +86,11 @@ static func_caller* sc_table[1024] =
bind_func(sys_rwlock_trywlock), //126 (0x07E)
bind_func(sys_rwlock_wunlock), //127 (0x07F)
bind_func(sys_event_queue_create), //128 (0x080)
null_func, //129 (0x081)
bind_func(sys_event_queue_receive), null_func, bind_func(sys_event_flag_cancel), bind_func(sys_event_queue_drain), bind_func(sys_event_port_create), //134
null_func, bind_func(sys_event_port_connect_local), null_func, bind_func(sys_event_port_send), bind_func(sys_event_flag_get), //139
bind_func(sys_event_queue_destroy), //129 (0x081)
bind_func(sys_event_queue_receive), bind_func(sys_event_queue_tryreceive), // 131
bind_func(sys_event_flag_cancel), bind_func(sys_event_queue_drain), bind_func(sys_event_port_create), //134
bind_func(sys_event_port_destroy), bind_func(sys_event_port_connect_local), //136
bind_func(sys_event_port_disconnect), bind_func(sys_event_port_send), bind_func(sys_event_flag_get), //139
null_func, bind_func(sys_timer_usleep), bind_func(sys_timer_sleep), null_func, bind_func(sys_time_get_timezone), //144
bind_func(sys_time_get_current_time), bind_func(sys_time_get_system_time), bind_func(sys_time_get_timebase_frequency), null_func, null_func, //149
null_func, null_func, null_func, null_func, null_func, //154
@ -99,8 +101,10 @@ static func_caller* sc_table[1024] =
bind_func(sys_spu_thread_group_start), bind_func(sys_spu_thread_group_suspend), //174
null_func, null_func, null_func, bind_func(sys_spu_thread_group_join), null_func, //179
null_func, bind_func(sys_spu_thread_write_ls), bind_func(sys_spu_thread_read_ls), null_func, bind_func(sys_spu_thread_write_snr), //184
null_func, null_func, bind_func(sys_spu_thread_set_spu_cfg), bind_func(sys_spu_thread_get_spu_cfg), null_func, //189
bind_func(sys_spu_thread_write_spu_mb), bind_func(sys_spu_thread_connect_event), null_func, bind_func(sys_spu_thread_bind_queue), null_func, //194
bind_func(sys_spu_thread_group_connect_event), bind_func(sys_spu_thread_group_disconnect_event), //186
bind_func(sys_spu_thread_set_spu_cfg), bind_func(sys_spu_thread_get_spu_cfg), null_func, //189
bind_func(sys_spu_thread_write_spu_mb), bind_func(sys_spu_thread_connect_event), bind_func(sys_spu_thread_disconnect_event), //192
bind_func(sys_spu_thread_bind_queue), bind_func(sys_spu_thread_unbind_queue), //194
null_func, null_func, null_func, null_func, null_func, //199
null_func, null_func, null_func, null_func, null_func, //204
null_func, null_func, null_func, null_func, null_func, //209
@ -112,7 +116,7 @@ static func_caller* sc_table[1024] =
null_func, null_func, null_func, null_func, null_func, //239
null_func, null_func, null_func, null_func, null_func, //244
null_func, null_func, null_func, null_func, null_func, //249
null_func, bind_func(sys_spu_thread_group_connect_event_all_threads), null_func, null_func, null_func, //254
null_func, bind_func(sys_spu_thread_group_connect_event_all_threads), bind_func(sys_spu_thread_group_disconnect_event_all_threads), null_func, null_func, //254
null_func, null_func, null_func, null_func, null_func, //259
null_func, null_func, null_func, null_func, null_func, //264
null_func, null_func, null_func, null_func, null_func, //269

View File

@ -128,16 +128,20 @@ extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_add
//sys_event
extern int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t<sys_event_queue_attr> attr, u64 event_queue_key, int size);
extern int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout);
extern int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name);
extern int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id);
extern int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);
extern int sys_event_queue_destroy(u32 equeue_id, int mode);
extern int sys_event_queue_receive(u32 equeue_id, mem_ptr_t<sys_event_data> _event, u64 timeout);
extern int sys_event_queue_tryreceive(u32 equeue_id, mem_ptr_t<sys_event_data> event_array, int size, mem32_t number);
extern int sys_event_queue_drain(u32 event_queue_id);
extern int sys_event_port_create(mem32_t eport_id, int port_type, u64 name);
extern int sys_event_port_destroy(u32 eport_id);
extern int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id);
extern int sys_event_port_disconnect(u32 eport_id);
extern int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);
//sys_event_flag
extern int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr, u64 init);
extern int sys_event_flag_destroy(u32 eflag_id);
extern int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u32 timeout);
extern int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 timeout);
extern int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result);
extern int sys_event_flag_set(u32 eflag_id, u64 bitptn);
extern int sys_event_flag_clear(u32 eflag_id, u64 bitptn);
@ -181,6 +185,16 @@ extern int sys_mutex_lock(u32 mutex_id, u64 timeout);
extern int sys_mutex_trylock(u32 mutex_id);
extern int sys_mutex_unlock(u32 mutex_id);
//sys_rwlock
extern int sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t<sys_rwlock_attribute_t> attr);
extern int sys_rwlock_destroy(u32 rw_lock_id);
extern int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout);
extern int sys_rwlock_tryrlock(u32 rw_lock_id);
extern int sys_rwlock_runlock(u32 rw_lock_id);
extern int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout);
extern int sys_rwlock_trywlock(u32 rw_lock_id);
extern int sys_rwlock_wunlock(u32 rw_lock_id);
//ppu_thread
extern void sys_ppu_thread_exit(int errorcode);
extern int sys_ppu_thread_yield();
@ -197,7 +211,7 @@ extern void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry);
extern int sys_ppu_thread_get_id(const u32 id_addr);
//memory
extern int sys_memory_container_create(u32 cid_addr, u32 yield_size);
extern int sys_memory_container_create(mem32_t cid, u32 yield_size);
extern int sys_memory_container_destroy(u32 cid);
extern int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr);
extern int sys_memory_free(u32 start_addr);
@ -290,13 +304,13 @@ extern int cellMouseGetRawData(u32 port_no, mem_class_t data);
extern int cellGcmCallback(u32 context_addr, u32 count);
//sys_tty
extern int sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr);
extern int sys_tty_write(u32 ch, u64 buf_addr, u32 len, u64 pwritelen_addr);
extern int sys_tty_read(s32 ch, u64 buf_addr, u32 len, u64 preadlen_addr);
extern int sys_tty_write(s32 ch, u64 buf_addr, u32 len, u64 pwritelen_addr);
//sys_heap
extern int sys_heap_create_heap(const u32 heap_addr, const u32 start_addr, const u32 size);
extern int sys_heap_malloc(const u32 heap_addr, const u32 size);
extern int _sys_heap_memalign(u32 heap_id, u32 align, u32 size, u64 p4);
extern int _sys_heap_memalign(u32 heap_id, u32 align, u32 size);
//sys_spu
extern int sys_spu_image_open(mem_ptr_t<sys_spu_image> img, u32 path_addr);
@ -307,9 +321,11 @@ extern int sys_spu_thread_group_start(u32 id);
extern int sys_spu_thread_group_suspend(u32 id);
extern int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu_thread_group_attribute> attr);
extern int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
extern int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup);
extern int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status);
extern int sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et);
extern int sys_spu_thread_group_disconnect_event(u32 id, u32 et);
extern int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr);
extern int sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup);
extern int sys_raw_spu_create(mem32_t id, u32 attr_addr);
extern int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu);
extern int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type);
@ -318,7 +334,10 @@ extern int sys_spu_thread_write_spu_mb(u32 id, u32 value);
extern int sys_spu_thread_set_spu_cfg(u32 id, u64 value);
extern int sys_spu_thread_get_spu_cfg(u32 id, mem64_t value);
extern int sys_spu_thread_write_snr(u32 id, u32 number, u32 value);
extern int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup);
extern int sys_spu_thread_disconnect_event(u32 id, u32 event_type, u8 spup);
extern int sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num);
extern int sys_spu_thread_unbind_queue(u32 id, u32 spuq_num);
extern int sys_spu_thread_get_exit_status(u32 id, mem32_t status);
//sys_time
@ -350,16 +369,6 @@ extern int sys_trace_allocate_buffer();
extern int sys_trace_free_buffer();
extern int sys_trace_create2();
//sys_rwlock
extern int sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t<sys_rwlock_attribute_t> attr);
extern int sys_rwlock_destroy(u32 rw_lock_id);
extern int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout);
extern int sys_rwlock_tryrlock(u32 rw_lock_id);
extern int sys_rwlock_runlock(u32 rw_lock_id);
extern int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout);
extern int sys_rwlock_trywlock(u32 rw_lock_id);
extern int sys_rwlock_wunlock(u32 rw_lock_id);
//sys_rsx
extern int sys_rsx_device_open();
extern int sys_rsx_device_close();

View File

@ -72,7 +72,11 @@ int sys_cond_wait(u32 cond_id, u64 timeout)
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
do
{
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
if (Emu.IsStopped())
{
ConLog.Warning("sys_cond_wait(cond_id=%d, ...) aborted", cond_id);
return CELL_ETIMEDOUT;
}
switch (cond_data->cond.WaitTimeout(1))
{
@ -85,7 +89,6 @@ int sys_cond_wait(u32 cond_id, u64 timeout)
{
if (!timeout)
{
sys_cond.Warning("sys_cond_wait(cond_id=0x%x, timeout=0x%llx): TIMEOUT", cond_id, timeout);
counter = 0;
}
else

View File

@ -21,25 +21,201 @@ int sys_event_queue_create(mem32_t equeue_id, mem_ptr_t<sys_event_queue_attr> at
return CELL_EFAULT;
}
equeue_id = sys_event.GetNewId(new EventQueue((u32)attr->protocol, (int)attr->type, attr->name_u64, event_queue_key, size));
sys_event.Warning("*** event_queue created[%s] (protocol=0x%x, type=0x%x): id = %d",
switch (attr->protocol.ToBE())
{
case se32(SYS_SYNC_PRIORITY): break;
case se32(SYS_SYNC_RETRY): sys_event.Error("Invalid SYS_SYNC_RETRY protocol attr"); return CELL_EINVAL;
case se32(SYS_SYNC_PRIORITY_INHERIT): sys_event.Error("Invalid SYS_SYNC_PRIORITY_INHERIT protocol attr"); return CELL_EINVAL;
case se32(SYS_SYNC_FIFO): break;
default: sys_event.Error("Unknown 0x%x protocol attr", (u32)attr->protocol); return CELL_EINVAL;
}
switch (attr->type.ToBE())
{
case se32(SYS_PPU_QUEUE): break;
case se32(SYS_SPU_QUEUE): break;
default: sys_event.Error("Unknown 0x%x type attr", (u32)attr->type); return CELL_EINVAL;
}
if (event_queue_key && Emu.GetEventManager().CheckKey(event_queue_key))
{
return CELL_EEXIST;
}
EventQueue* eq = new EventQueue((u32)attr->protocol, (int)attr->type, attr->name_u64, event_queue_key, size);
if (event_queue_key && !Emu.GetEventManager().RegisterKey(eq, event_queue_key))
{
delete eq;
return CELL_EAGAIN;
}
equeue_id = sys_event.GetNewId(eq);
sys_event.Warning("*** event_queue created [%s] (protocol=0x%x, type=0x%x): id = %d",
attr->name, (u32)attr->protocol, (int)attr->type, equeue_id.GetValue());
return CELL_OK;
}
int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
int sys_event_queue_destroy(u32 equeue_id, int mode)
{
sys_event.Warning("sys_event_queue_receive(equeue_id=0x%x, event_addr=0x%x, timeout=0x%x)",
equeue_id, event_addr, timeout);
sys_event.Warning("sys_event_queue_destroy(equeue_id=%d, mode=0x%x)", equeue_id, mode);
if(!sys_event.CheckId(equeue_id))
EventQueue* eq;
if (!Emu.GetIdManager().GetIDData(equeue_id, eq))
{
return CELL_ESRCH;
}
int result;
auto queue_receive = [&](int status) -> bool
if (mode && mode != SYS_EVENT_QUEUE_DESTROY_FORCE)
{
return CELL_EINVAL;
}
u32 tid = GetCurrentPPUThread().GetId();
eq->m_mutex.lock(tid);
eq->owner.lock(tid);
// check if some threads are waiting for an event
if (!mode && eq->list.GetCount())
{
eq->owner.unlock(tid);
eq->m_mutex.unlock(tid);
return CELL_EBUSY;
}
eq->owner.unlock(tid, ~0);
eq->m_mutex.unlock(tid);
while (eq->list.GetCount())
{
Sleep(1);
if (Emu.IsStopped())
{
ConLog.Warning("sys_event_queue_destroy(equeue=%d, ...) aborted", equeue_id);
break;
}
}
Emu.GetEventManager().UnregisterKey(eq->key);
eq->ports.clear();
Emu.GetIdManager().RemoveID(equeue_id);
return CELL_OK;
}
int sys_event_queue_tryreceive(u32 equeue_id, mem_ptr_t<sys_event_data> event_array, int size, mem32_t number)
{
sys_event.Error("sys_event_queue_tryreceive(equeue_id=%d, event_array_addr=0x%x, size=%d, number_addr=0x%x)",
equeue_id, event_array.GetAddr(), size, number.GetAddr());
if (size < 0 || !number.IsGood())
{
return CELL_EFAULT;
}
if (size && !Memory.IsGoodAddr(event_array.GetAddr(), sizeof(sys_event_data) * size))
{
return CELL_EFAULT;
}
EventQueue* eq;
if (!Emu.GetIdManager().GetIDData(equeue_id, eq))
{
return CELL_ESRCH;
}
if (eq->type != SYS_PPU_QUEUE)
{
return CELL_EINVAL;
}
if (size == 0)
{
number = 0;
return CELL_OK;
}
u32 tid = GetCurrentPPUThread().GetId();
eq->m_mutex.lock(tid);
eq->owner.lock(tid);
if (eq->list.GetCount())
{
number = 0;
eq->owner.unlock(tid);
eq->m_mutex.unlock(tid);
return CELL_OK;
}
number = eq->events.pop_all((sys_event_data*)(Memory + event_array.GetAddr()), size);
eq->owner.unlock(tid);
eq->m_mutex.unlock(tid);
return CELL_OK;
}
int sys_event_queue_receive(u32 equeue_id, mem_ptr_t<sys_event_data> event, u64 timeout)
{
sys_event.Warning("sys_event_queue_receive(equeue_id=%d, event_addr=0x%x, timeout=%lld)",
equeue_id, event.GetAddr(), timeout);
if (!event.IsGood())
{
return CELL_EFAULT;
}
EventQueue* eq;
if (!Emu.GetIdManager().GetIDData(equeue_id, eq))
{
return CELL_ESRCH;
}
if (eq->type != SYS_PPU_QUEUE)
{
return CELL_EINVAL;
}
u32 tid = GetCurrentPPUThread().GetId();
eq->push(tid); // add thread to sleep queue
timeout = timeout ? (timeout / 1000) : ~0;
u64 counter = 0;
while (true)
{
switch (eq->owner.trylock(tid))
{
case SMR_OK:
if (!eq->events.count())
{
eq->owner.unlock(tid);
break;
}
else
{
u32 next = (eq->protocol == SYS_SYNC_FIFO) ? eq->pop() : eq->pop_prio();
if (next != tid)
{
eq->owner.unlock(tid, next);
break;
}
}
case SMR_SIGNAL:
{
eq->events.pop(*(sys_event_data*)(Memory + event));
eq->owner.unlock(tid);
return CELL_OK;
}
case SMR_FAILED: break;
default: eq->invalidate(tid); return CELL_ECANCELED;
}
Sleep(1);
if (counter++ > timeout || Emu.IsStopped())
{
if (Emu.IsStopped()) ConLog.Warning("sys_event_queue_receive(equeue=%d, ...) aborted", equeue_id);
eq->invalidate(tid);
return CELL_ETIMEDOUT;
}
}
/* auto queue_receive = [&](int status) -> bool
{
if(status == CPUThread_Stopped)
{
@ -48,7 +224,12 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
}
EventQueue* equeue;
Emu.GetIdManager().GetIDData(equeue_id, equeue);
if (!Emu.GetIdManager().GetIDData(equeue_id, equeue))
{
result = CELL_ESRCH;
return false;
}
for(int i=0; i<equeue->pos; ++i)
{
if(!equeue->ports[i]->has_data && equeue->ports[i]->thread)
@ -71,12 +252,10 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
{
if(equeue->ports[i]->has_data)
{
auto dst = (sys_event_data&)Memory[event_addr];
dst.source = equeue->ports[i]->name;
dst.data1 = equeue->ports[i]->data1;
dst.data2 = equeue->ports[i]->data2;
dst.data3 = equeue->ports[i]->data3;
event->source = equeue->ports[i]->name;
event->data1 = equeue->ports[i]->data1;
event->data2 = equeue->ports[i]->data2;
event->data3 = equeue->ports[i]->data3;
equeue->ports[i]->has_data = false;
@ -88,85 +267,167 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
return true;
};
GetCurrentPPUThread().WaitFor(queue_receive);
return result;
GetCurrentPPUThread().WaitFor(queue_receive);*/
}
int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name)
int sys_event_queue_drain(u32 equeue_id)
{
sys_event.Warning("sys_event_queue_drain(equeue_id=%d)", equeue_id);
EventQueue* eq;
if (!Emu.GetIdManager().GetIDData(equeue_id, eq))
{
return CELL_ESRCH;
}
eq->events.clear();
return CELL_OK;
}
int sys_event_port_create(mem32_t eport_id, int port_type, u64 name)
{
sys_event.Warning("sys_event_port_create(eport_id_addr=0x%x, port_type=0x%x, name=0x%llx)",
eport_id_addr, port_type, name);
eport_id.GetAddr(), port_type, name);
if(!Memory.IsGoodAddr(eport_id_addr, 4))
if (!eport_id.IsGood())
{
return CELL_EFAULT;
}
if (port_type != SYS_EVENT_PORT_LOCAL)
{
sys_event.Error("sys_event_port_create: invalid port_type(0x%x)", port_type);
return CELL_EINVAL;
}
EventPort* eport = new EventPort();
u32 id = sys_event.GetNewId(eport);
eport->pos = 0;
eport->has_data = false;
eport->name = name ? name : id;
Memory.Write32(eport_id_addr, id);
eport->name = name ? name : ((u64)sys_process_getpid() << 32) | (u64)id;
eport_id = id;
sys_event.Warning("*** sys_event_port created: id = %d", id);
return CELL_OK;
}
int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id)
int sys_event_port_destroy(u32 eport_id)
{
sys_event.Warning("sys_event_port_connect_local(event_port_id=0x%x, event_queue_id=0x%x)",
event_port_id, event_queue_id);
sys_event.Warning("sys_event_port_destroy(eport_id=%d)", eport_id);
if(!sys_event.CheckId(event_port_id) || !sys_event.CheckId(event_queue_id))
EventPort* eport;
if (!Emu.GetIdManager().GetIDData(eport_id, eport))
{
return CELL_ESRCH;
}
u32 tid = GetCurrentPPUThread().GetId();
if (eport->mutex.trylock(tid) != SMR_OK)
{
return CELL_EISCONN;
}
if (eport->eq)
{
eport->mutex.unlock(tid);
return CELL_EISCONN;
}
eport->mutex.unlock(tid, ~0);
Emu.GetIdManager().RemoveID(eport_id);
return CELL_OK;
}
int sys_event_port_connect_local(u32 eport_id, u32 equeue_id)
{
sys_event.Warning("sys_event_port_connect_local(eport_id=%d, equeue_id=%d)", eport_id, equeue_id);
EventPort* eport;
if (!Emu.GetIdManager().GetIDData(eport_id, eport))
{
return CELL_ESRCH;
}
u32 tid = GetCurrentPPUThread().GetId();
if (eport->mutex.trylock(tid) != SMR_OK)
{
return CELL_EISCONN;
}
if (eport->eq)
{
eport->mutex.unlock(tid);
return CELL_EISCONN;
}
EventQueue* equeue;
Emu.GetIdManager().GetIDData(event_port_id, eport);
Emu.GetIdManager().GetIDData(event_queue_id, equeue);
equeue->ports[equeue->pos++] = eport;
eport->queue[eport->pos++] = equeue;
if (!Emu.GetIdManager().GetIDData(equeue_id, equeue))
{
sys_event.Error("sys_event_port_connect_local: event_queue(%d) not found!", equeue_id);
eport->mutex.unlock(tid);
return CELL_ESRCH;
}
else
{
equeue->ports.add(eport);
}
eport->eq = equeue;
eport->mutex.unlock(tid);
return CELL_OK;
}
int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3)
int sys_event_port_disconnect(u32 eport_id)
{
sys_event.Warning("sys_event_port_send(event_port_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)",
event_port_id, data1, data2, data3);
sys_event.Warning("sys_event_port_disconnect(eport_id=%d)", eport_id);
if(!sys_event.CheckId(event_port_id))
EventPort* eport;
if (!Emu.GetIdManager().GetIDData(eport_id, eport))
{
return CELL_ESRCH;
}
EventPort* eport;
Emu.GetIdManager().GetIDData(event_port_id, eport);
if(!eport->pos)
if (!eport->eq)
{
return CELL_ENOTCONN;
}
if(eport->has_data)
u32 tid = GetCurrentPPUThread().GetId();
if (eport->mutex.trylock(tid) != SMR_OK)
{
return CELL_EBUSY;
}
eport->has_data = true;
eport->data1 = data1;
eport->data2 = data2;
eport->data3 = data3;
eport->eq->ports.remove(eport);
eport->eq = 0;
eport->mutex.unlock(tid);
return CELL_OK;
}
int sys_event_queue_drain(u32 event_queue_id)
int sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3)
{
sys_event.Error("sys_event_queue_drain(event_queue_id=0x%x)", event_queue_id);
sys_event.Warning("sys_event_port_send(eport_id=%d, data1=0x%llx, data2=0x%llx, data3=0x%llx)",
eport_id, data1, data2, data3);
EventPort* eport;
if (!Emu.GetIdManager().GetIDData(eport_id, eport))
{
return CELL_ESRCH;
}
SMutexLocker lock(eport->mutex);
if (!eport->eq)
{
return CELL_ENOTCONN;
}
if (!eport->eq->events.push(eport->name, data1, data2, data3))
{
return CELL_EBUSY;
}
return CELL_OK;
}

View File

@ -6,7 +6,8 @@ SysCallBase sys_event_flag("sys_event_flag");
int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr, u64 init)
{
sys_event_flag.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)", eflag_id.GetAddr(), attr.GetAddr(), init);
sys_event_flag.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)",
eflag_id.GetAddr(), attr.GetAddr(), init);
if(!eflag_id.IsGood() || !attr.IsGood())
{
@ -16,7 +17,7 @@ int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr,
switch (attr->protocol.ToBE())
{
case se32(SYS_SYNC_PRIORITY): sys_event_flag.Warning("TODO: SYS_SYNC_PRIORITY attr"); break;
case se32(SYS_SYNC_RETRY): break;
case se32(SYS_SYNC_RETRY): sys_event_flag.Warning("TODO: SYS_SYNC_RETRY attr"); break;
case se32(SYS_SYNC_PRIORITY_INHERIT): sys_event_flag.Warning("TODO: SYS_SYNC_PRIORITY_INHERIT attr"); break;
case se32(SYS_SYNC_FIFO): sys_event_flag.Warning("TODO: SYS_SYNC_FIFO attr"); break;
default: return CELL_EINVAL;
@ -36,14 +37,15 @@ int sys_event_flag_create(mem32_t eflag_id, mem_ptr_t<sys_event_flag_attr> attr,
eflag_id = sys_event_flag.GetNewId(new event_flag(init, (u32)attr->protocol, (int)attr->type));
sys_event_flag.Warning("*** event_flag created[%s] (protocol=%d, type=%d): id = %d", attr->name, (u32)attr->protocol, (int)attr->type, eflag_id.GetValue());
sys_event_flag.Warning("*** event_flag created [%s] (protocol=0x%x, type=0x%x): id = %d",
attr->name, (u32)attr->protocol, (int)attr->type, eflag_id.GetValue());
return CELL_OK;
}
int sys_event_flag_destroy(u32 eflag_id)
{
sys_event_flag.Warning("sys_event_flag_destroy(eflag_id=0x%x)", eflag_id);
sys_event_flag.Warning("sys_event_flag_destroy(eflag_id=%d)", eflag_id);
event_flag* ef;
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
@ -53,23 +55,23 @@ int sys_event_flag_destroy(u32 eflag_id)
return CELL_OK;
}
int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u32 timeout)
int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 timeout)
{
sys_event_flag.Error("sys_event_flag_wait(eflag_id=0x%x, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=0x%x)",
sys_event_flag.Error("sys_event_flag_wait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=%lld)",
eflag_id, bitptn, mode, result.GetAddr(), timeout);
return CELL_OK;
}
int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result)
{
sys_event_flag.Error("sys_event_flag_trywait(eflag_id=0x%x, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)",
sys_event_flag.Error("sys_event_flag_trywait(eflag_id=%d, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)",
eflag_id, bitptn, mode, result.GetAddr());
return CELL_OK;
}
int sys_event_flag_set(u32 eflag_id, u64 bitptn)
{
sys_event_flag.Warning("sys_event_flag_set(eflag_id=0x%x, bitptn=0x%llx)", eflag_id, bitptn);
sys_event_flag.Warning("sys_event_flag_set(eflag_id=%d, bitptn=0x%llx)", eflag_id, bitptn);
event_flag* ef;
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
@ -81,7 +83,7 @@ int sys_event_flag_set(u32 eflag_id, u64 bitptn)
int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
{
sys_event_flag.Warning("sys_event_flag_clear(eflag_id=0x%x, bitptn=0x%llx)", eflag_id, bitptn);
sys_event_flag.Warning("sys_event_flag_clear(eflag_id=%d, bitptn=0x%llx)", eflag_id, bitptn);
event_flag* ef;
if(!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
@ -93,13 +95,13 @@ int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
int sys_event_flag_cancel(u32 eflag_id, mem32_t num)
{
sys_event_flag.Error("sys_event_flag_cancel(eflag_id=0x%x, num_addr=0x%x)", eflag_id, num.GetAddr());
sys_event_flag.Error("sys_event_flag_cancel(eflag_id=%d, num_addr=0x%x)", eflag_id, num.GetAddr());
return CELL_OK;
}
int sys_event_flag_get(u32 eflag_id, mem64_t flags)
{
sys_event_flag.Warning("sys_event_flag_get(eflag_id=0x%x, flags_addr=0x%x)", eflag_id, flags.GetAddr());
sys_event_flag.Warning("sys_event_flag_get(eflag_id=%d, flags_addr=0x%x)", eflag_id, flags.GetAddr());
if (!flags.IsGood())
{

View File

@ -7,7 +7,7 @@ extern Module sys_fs;
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
{
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Log("cellFsOpen(path: %s, flags: 0x%x, fd_addr: 0x%x, arg_addr: 0x%x, size: 0x%llx)",
sys_fs.Log("cellFsOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx)",
path.wx_str(), flags, fd.GetAddr(), arg.GetAddr(), size);
const wxString& ppath = path;
@ -57,7 +57,7 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
if(_oflags != 0)
{
sys_fs.Error("'%s' has unknown flags! flags: 0x%08x", ppath.wx_str(), flags);
sys_fs.Error("\"%s\" has unknown flags! flags: 0x%08x", ppath.wx_str(), flags);
return CELL_EINVAL;
}
@ -65,21 +65,21 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
if(!stream || !stream->IsOpened())
{
sys_fs.Error("'%s' not found! flags: 0x%08x", ppath.wx_str(), flags);
sys_fs.Error("\"%s\" not found! flags: 0x%08x", ppath.wx_str(), flags);
delete stream;
return CELL_ENOENT;
}
fd = sys_fs.GetNewId(stream, flags);
ConLog.Warning("*** cellFsOpen(path: %s): fd=%d", path.wx_str(), fd.GetValue());
ConLog.Warning("*** cellFsOpen(path=\"%s\"): fd = %d", path.wx_str(), fd.GetValue());
return CELL_OK;
}
int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
{
sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)",
sys_fs.Log("cellFsRead(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nread_addr=0x%x)",
fd, buf_addr, nbytes, nread.GetAddr());
vfsStream* file;
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
@ -100,7 +100,7 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
{
sys_fs.Log("cellFsWrite(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nwrite_addr: 0x%x)",
sys_fs.Log("cellFsWrite(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nwrite_addr=0x%x)",
fd, buf_addr, nbytes, nwrite.GetAddr());
vfsStream* file;
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
@ -121,7 +121,7 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
int cellFsClose(u32 fd)
{
sys_fs.Warning("cellFsClose(fd: %d)", fd);
sys_fs.Warning("cellFsClose(fd=%d)", fd);
if(!Emu.GetIdManager().RemoveID(fd))
return CELL_ESRCH;
@ -186,7 +186,7 @@ int cellFsClosedir(u32 fd)
int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
{
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Log("cellFsStat(path: %s, sb_addr: 0x%x)", path.wx_str(), sb.GetAddr());
sys_fs.Log("cellFsStat(path=\"%s\", sb_addr: 0x%x)", path.wx_str(), sb.GetAddr());
sb->st_mode =
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
@ -205,7 +205,7 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
{
if(path.CmpNoCase(Emu.GetVFS().m_devices[i].GetPs3Path().RemoveLast(1)) == 0)
{
sys_fs.Log("cellFsStat: '%s' is a mount point.", path.wx_str());
sys_fs.Log("cellFsStat: \"%s\" is a mount point.", path.wx_str());
sb->st_mode |= CELL_FS_S_IFDIR;
return CELL_OK;
}
@ -230,7 +230,7 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
}
else
{
sys_fs.Warning("cellFsStat: '%s' not found.", path.wx_str());
sys_fs.Warning("cellFsStat: \"%s\" not found.", path.wx_str());
return CELL_ENOENT;
}
@ -239,7 +239,7 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
int cellFsFstat(u32 fd, mem_ptr_t<CellFsStat> sb)
{
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr());
sys_fs.Log("cellFsFstat(fd=%d, sb_addr: 0x%x)", fd, sb.GetAddr());
vfsStream* file;
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
@ -315,14 +315,14 @@ int cellFsUnlink(u32 path_addr)
int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
{
vfsSeekMode seek_mode;
sys_fs.Log("cellFsLseek(fd: %d, offset: 0x%llx, whence: %d, pos_addr: 0x%x)", fd, offset, whence, pos.GetAddr());
sys_fs.Log("cellFsLseek(fd=%d, offset=0x%llx, whence=0x%x, pos_addr=0x%x)", fd, offset, whence, pos.GetAddr());
switch(whence)
{
case CELL_SEEK_SET: seek_mode = vfsSeekSet; break;
case CELL_SEEK_CUR: seek_mode = vfsSeekCur; break;
case CELL_SEEK_END: seek_mode = vfsSeekEnd; break;
default:
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
sys_fs.Error(fd, "Unknown seek whence! (0x%x)", whence);
return CELL_EINVAL;
}
@ -334,7 +334,7 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
int cellFsFtruncate(u32 fd, u64 size)
{
sys_fs.Log("cellFsFtruncate(fd: %d, size: %lld)", fd, size);
sys_fs.Log("cellFsFtruncate(fd=%d, size=%lld)", fd, size);
vfsStream* file;
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
u64 initialSize = file->GetSize();
@ -360,12 +360,12 @@ int cellFsFtruncate(u32 fd, u64 size)
int cellFsTruncate(u32 path_addr, u64 size)
{
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Log("cellFsTruncate(path: %s, size: %lld)", path.wx_str(), size);
sys_fs.Log("cellFsTruncate(path=\"%s\", size=%lld)", path.wx_str(), size);
vfsFile f(path, vfsReadWrite);
if(!f.IsOpened())
{
sys_fs.Warning("cellFsTruncate: '%s' not found.", path.wx_str());
sys_fs.Warning("cellFsTruncate: \"%s\" not found.", path.wx_str());
return CELL_ENOENT;
}
u64 initialSize = f.GetSize();
@ -390,7 +390,7 @@ int cellFsTruncate(u32 path_addr, u64 size)
int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size)
{
sys_fs.Log("cellFsFGetBlockSize(fd: %d, sector_size_addr: 0x%x, block_size_addr: 0x%x)", fd, sector_size.GetAddr(), block_size.GetAddr());
sys_fs.Log("cellFsFGetBlockSize(fd=%d, sector_size_addr: 0x%x, block_size_addr: 0x%x)", fd, sector_size.GetAddr(), block_size.GetAddr());
sector_size = 4096; // ?
block_size = 4096; // ?

View File

@ -22,13 +22,13 @@ int sys_heap_create_heap(const u32 heap_addr, const u32 align, const u32 size)
sc_heap.Warning("sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size);
u32 heap_id = sc_heap.GetNewId(new HeapInfo(heap_addr, align, size));
sc_heap.Warning("*** sys_heap created(): id=0x%x", heap_id);
sc_heap.Warning("*** sys_heap created: id = %d", heap_id);
return heap_id;
}
int sys_heap_malloc(const u32 heap_id, const u32 size)
{
sc_heap.Warning("sys_heap_malloc(heap_id=0x%x, size=0x%x)", heap_id, size);
sc_heap.Warning("sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size);
HeapInfo* heap;
if(!sc_heap.CheckId(heap_id, heap)) return CELL_ESRCH;
@ -36,9 +36,9 @@ int sys_heap_malloc(const u32 heap_id, const u32 size)
return Memory.Alloc(size, 1);
}
int _sys_heap_memalign(u32 heap_id, u32 align, u32 size, u64 p4)
int _sys_heap_memalign(u32 heap_id, u32 align, u32 size)
{
sc_heap.Warning("_sys_heap_memalign(heap_id=0x%x, align=0x%x, size=0x%x, p4=0x%llx, ... ???)", heap_id, align, size, p4);
sc_heap.Warning("_sys_heap_memalign(heap_id=%d, align=0x%x, size=0x%x)", heap_id, align, size);
HeapInfo* heap;
if(!sc_heap.CheckId(heap_id, heap)) return CELL_ESRCH;

View File

@ -7,7 +7,7 @@ SysCallBase sys_lwcond("sys_lwcond");
int sys_lwcond_create(mem_ptr_t<sys_lwcond_t> lwcond, mem_ptr_t<sys_lwmutex_t> lwmutex, mem_ptr_t<sys_lwcond_attribute_t> attr)
{
sys_lwcond.Log("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)",
sys_lwcond.Warning("sys_lwcond_create(lwcond_addr=0x%x, lwmutex_addr=0x%x, attr_addr=0x%x)",
lwcond.GetAddr(), lwmutex.GetAddr(), attr.GetAddr());
if (!lwcond.IsGood() || !lwmutex.IsGood() || !attr.IsGood()) return CELL_EFAULT;
@ -15,7 +15,7 @@ int sys_lwcond_create(mem_ptr_t<sys_lwcond_t> lwcond, mem_ptr_t<sys_lwmutex_t> l
lwcond->lwmutex = lwmutex.GetAddr();
lwcond->lwcond_queue = sys_lwcond.GetNewId(new LWCond(attr->name_u64));
sys_lwcond.Warning("*** lwcond created [%s] (attr=0x%x, lwmutex.sq=0x%x): id=0x%x",
sys_lwcond.Warning("*** lwcond created [%s] (attr=0x%x, lwmutex.sq=0x%x): id = %d",
attr->name, (u32)lwmutex->attribute, (u32)lwmutex->sleep_queue, (u32)lwcond->lwcond_queue);
return CELL_OK;
}
@ -77,7 +77,7 @@ int sys_lwcond_signal_to(mem_ptr_t<sys_lwcond_t> lwcond, u32 ppu_thread_id)
int sys_lwcond_wait(mem_ptr_t<sys_lwcond_t> lwcond, u64 timeout)
{
sys_lwcond.Log("sys_lwcond_wait(lwcond_addr=0x%x, timeout=%llu)", lwcond.GetAddr(), timeout);
sys_lwcond.Log("sys_lwcond_wait(lwcond_addr=0x%x, timeout=%lld)", lwcond.GetAddr(), timeout);
if (!lwcond.IsGood()) return CELL_EFAULT;
LWCond* lwc;
@ -95,7 +95,11 @@ int sys_lwcond_wait(mem_ptr_t<sys_lwcond_t> lwcond, u64 timeout)
bool was_locked = true;
do
{
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
if (Emu.IsStopped())
{
ConLog.Warning("sys_lwcond_wait(sq id=%d, ...) aborted", id);
return CELL_ETIMEDOUT;
}
if (was_locked) lwmutex->unlock(tid);
Sleep(1);
if (was_locked = (lwmutex->trylock(tid) == CELL_OK))

View File

@ -1,7 +1,6 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/lv2/SC_Lwmutex.h"
#include <mutex>
SysCallBase sc_lwmutex("sys_lwmutex");
@ -36,7 +35,7 @@ int sys_lwmutex_create(mem_ptr_t<sys_lwmutex_t> lwmutex, mem_ptr_t<sys_lwmutex_a
u32 sq_id = sc_lwmutex.GetNewId(new SleepQueue(attr->name_u64));
lwmutex->sleep_queue = sq_id;
sc_lwmutex.Log("*** lwmutex created [%s] (attribute=0x%x): sleep_queue=0x%x",
sc_lwmutex.Log("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d",
attr->name, (u32)lwmutex->attribute, sq_id);
return CELL_OK;
@ -89,3 +88,174 @@ int sys_lwmutex_unlock(mem_ptr_t<sys_lwmutex_t> lwmutex)
return lwmutex->unlock(GetCurrentPPUThread().GetId());
}
void SleepQueue::push(u32 tid)
{
SMutexLocker lock(m_mutex);
list.AddCpy(tid);
}
u32 SleepQueue::pop() // SYS_SYNC_FIFO
{
SMutexLocker lock(m_mutex);
while (true)
{
if (list.GetCount())
{
u32 res = list[0];
list.RemoveAt(0);
if (res && Emu.GetIdManager().CheckID(res))
// check thread
{
return res;
}
}
return 0;
};
}
u32 SleepQueue::pop_prio() // SYS_SYNC_PRIORITY
{
SMutexLocker lock(m_mutex);
while (true)
{
if (list.GetCount())
{
u64 max_prio = 0;
u32 sel = 0;
for (u32 i = 0; i < list.GetCount(); i++)
{
CPUThread* t = Emu.GetCPU().GetThread(list[i]);
if (!t)
{
list[i] = 0;
sel = i;
break;
}
u64 prio = t->GetPrio();
if (prio > max_prio)
{
max_prio = prio;
sel = i;
}
}
u32 res = list[sel];
list.RemoveAt(sel);
/* if (Emu.GetIdManager().CheckID(res)) */
if (res)
// check thread
{
return res;
}
}
return 0;
}
}
u32 SleepQueue::pop_prio_inherit() // (TODO)
{
ConLog.Error("TODO: SleepQueue::pop_prio_inherit()");
Emu.Pause();
return 0;
}
void SleepQueue::invalidate(u32 tid)
{
SMutexLocker lock(m_mutex);
for (u32 i = 0; i < list.GetCount(); i++)
{
if (list[i] = tid)
{
list[i] = 0;
return;
}
}
}
int sys_lwmutex_t::trylock(be_t<u32> tid)
{
if (!attribute.ToBE()) return CELL_EINVAL;
if (tid == owner.GetOwner())
{
if (attribute.ToBE() & se32(SYS_SYNC_RECURSIVE))
{
recursive_count += 1;
if (!recursive_count.ToBE()) return CELL_EKRESOURCE;
return CELL_OK;
}
else
{
return CELL_EDEADLK;
}
}
switch (owner.trylock(tid))
{
case SMR_OK: recursive_count = 1; return CELL_OK;
case SMR_FAILED: return CELL_EBUSY;
default: return CELL_EINVAL;
}
}
int sys_lwmutex_t::unlock(be_t<u32> tid)
{
if (tid != owner.GetOwner())
{
return CELL_EPERM;
}
else
{
recursive_count -= 1;
if (!recursive_count.ToBE())
{
be_t<u32> target = 0;
switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK))
{
case se32(SYS_SYNC_FIFO):
case se32(SYS_SYNC_PRIORITY):
SleepQueue* sq;
if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH;
target = attribute.ToBE() & se32(SYS_SYNC_FIFO) ? sq->pop() : sq->pop_prio();
case se32(SYS_SYNC_RETRY): default: owner.unlock(tid, target); break;
}
}
return CELL_OK;
}
}
int sys_lwmutex_t::lock(be_t<u32> tid, u64 timeout)
{
switch (int res = trylock(tid))
{
case CELL_EBUSY: break;
default: return res;
}
SleepQueue* sq;
if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH;
switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK))
{
case se32(SYS_SYNC_PRIORITY):
case se32(SYS_SYNC_FIFO):
sq->push(tid);
default: break;
}
switch (owner.lock(tid, timeout))
{
case SMR_OK:
sq->invalidate(tid);
case SMR_SIGNAL:
recursive_count = 1; return CELL_OK;
case SMR_TIMEOUT:
sq->invalidate(tid); return CELL_ETIMEDOUT;
case SMR_ABORT:
if (Emu.IsStopped()) ConLog.Warning("sys_lwmutex_t::lock(sq=%d, ...) aborted", (u32)sleep_queue);
default:
sq->invalidate(tid); return CELL_EINVAL;
}
}

View File

@ -38,7 +38,7 @@ struct sys_lwmutex_attribute_t
};
};
class SleepQueue
struct SleepQueue
{
/* struct q_rec
{
@ -46,88 +46,20 @@ class SleepQueue
u64 prio;
q_rec(u32 tid, u64 prio): tid(tid), prio(prio) {}
}; */
SMutex m_mutex;
Array<u32> list;
SMutex m_mutex;
u64 m_name;
public:
SleepQueue(u64 name)
SleepQueue(u64 name = 0)
: m_name(name)
{
}
void push(u32 tid)
{
SMutexLocker lock(m_mutex);
list.AddCpy(tid);
}
u32 pop() // SYS_SYNC_FIFO
{
SMutexLocker lock(m_mutex);
while (true)
{
if (list.GetCount())
{
u32 res = list[0];
list.RemoveAt(0);
if (Emu.GetIdManager().CheckID(res))
// check thread
{
return res;
}
}
return 0;
};
}
u32 pop_prio() // SYS_SYNC_PRIORITY
{
SMutexLocker lock(m_mutex);
while (true)
{
if (list.GetCount())
{
u64 max_prio = 0;
u32 sel = 0;
for (u32 i = 0; i < list.GetCount(); i++)
{
CPUThread* t = Emu.GetCPU().GetThread(list[i]);
if (!t)
{
list[i] = 0;
sel = i;
break;
}
u64 prio = t->GetPrio();
if (prio > max_prio)
{
max_prio = prio;
sel = i;
}
}
u32 res = list[sel];
list.RemoveAt(sel);
/* if (Emu.GetIdManager().CheckID(res)) */
if (res)
// check thread
{
return res;
}
}
return 0;
}
}
u32 pop_prio_inherit() // (TODO)
{
ConLog.Error("TODO: SleepQueue::pop_prio_inherit()");
Emu.Pause();
}
void push(u32 tid);
u32 pop(); // SYS_SYNC_FIFO
u32 pop_prio(); // SYS_SYNC_PRIORITY
u32 pop_prio_inherit(); // (TODO)
void invalidate(u32 tid);
};
struct sys_lwmutex_t
@ -149,85 +81,11 @@ struct sys_lwmutex_t
be_t<u32> sleep_queue;
be_t<u32> pad;
int trylock(be_t<u32> tid)
{
if (!attribute.ToBE()) return CELL_EINVAL;
if (tid == owner.GetOwner())
{
if (attribute.ToBE() & se32(SYS_SYNC_RECURSIVE))
{
recursive_count += 1;
if (!recursive_count.ToBE()) return CELL_EKRESOURCE;
return CELL_OK;
}
else
{
return CELL_EDEADLK;
}
}
switch (owner.trylock(tid))
{
case SMR_OK: recursive_count = 1; return CELL_OK;
case SMR_FAILED: return CELL_EBUSY;
default: return CELL_EINVAL;
}
}
int unlock(be_t<u32> tid)
{
if (tid != owner.GetOwner())
{
return CELL_EPERM;
}
else
{
recursive_count -= 1;
if (!recursive_count.ToBE())
{
be_t<u32> target = 0;
switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK))
{
case se32(SYS_SYNC_FIFO):
case se32(SYS_SYNC_PRIORITY):
SleepQueue* sq;
if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH;
target = attribute.ToBE() & se32(SYS_SYNC_FIFO) ? sq->pop() : sq->pop_prio();
case se32(SYS_SYNC_RETRY): default: owner.unlock(tid, target); break;
}
}
return CELL_OK;
}
}
int lock(be_t<u32> tid, u64 timeout)
{
switch (int res = trylock(tid))
{
case CELL_EBUSY: break;
default: return res;
}
switch (attribute.ToBE() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK))
{
case se32(SYS_SYNC_PRIORITY):
case se32(SYS_SYNC_FIFO):
SleepQueue* sq;
if (!Emu.GetIdManager().GetIDData(sleep_queue, sq)) return CELL_ESRCH;
sq->push(tid);
default: break;
}
switch (owner.lock(tid, timeout))
{
case SMR_OK: case SMR_SIGNAL: recursive_count = 1; return CELL_OK;
case SMR_TIMEOUT: return CELL_ETIMEDOUT;
default: return CELL_EINVAL;
}
}
int trylock(be_t<u32> tid);
int unlock(be_t<u32> tid);
int lock(be_t<u32> tid, u64 timeout);
};
/*
class lwmutex_locker
{
mem_ptr_t<sys_lwmutex_t> m_mutex;
@ -248,4 +106,4 @@ class lwmutex_locker
{
m_mutex->unlock(m_id);
}
};
};*/

View File

@ -4,11 +4,11 @@
SysCallBase sc_mem("memory");
int sys_memory_container_create(u32 cid_addr, u32 yield_size)
int sys_memory_container_create(mem32_t cid, u32 yield_size)
{
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x, yield_size=0x%x)", cid.GetAddr(), yield_size);
if(!Memory.IsGoodAddr(cid_addr, 4))
if (!cid.IsGood())
{
return CELL_EFAULT;
}
@ -22,13 +22,14 @@ int sys_memory_container_create(u32 cid_addr, u32 yield_size)
return CELL_ENOMEM;
}
Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size)));
cid = sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size));
sc_mem.Warning("*** memory_container created(addr=0x%llx): id = %d", addr, cid.GetValue());
return CELL_OK;
}
int sys_memory_container_destroy(u32 cid)
{
sc_mem.Warning("sys_memory_container_destroy(cid=0x%x)", cid);
sc_mem.Warning("sys_memory_container_destroy(cid=%d)", cid);
MemoryContainerInfo* ct;

View File

@ -53,7 +53,11 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout)
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
do
{
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
if (Emu.IsStopped())
{
ConLog.Warning("sys_mutex_lock(mutex_id=%d, ...) aborted", mutex_id);
return CELL_ETIMEDOUT;
}
if (mtx_data->mtx.TryLock() == wxMUTEX_NO_ERROR) return CELL_OK;
Sleep(1);
@ -62,7 +66,6 @@ int sys_mutex_lock(u32 mutex_id, u64 timeout)
{
if (!timeout)
{
sys_mtx.Warning("sys_mutex_lock(mutex_id=0x%x, timeout=0x%llx): TIMEOUT", mutex_id, timeout);
counter = 0;
}
else

View File

@ -27,7 +27,7 @@ int sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t<sys_rwlock_attribute_t> attr
rw_lock_id = sys_rwlock.GetNewId(new RWLock((u32)attr->attr_protocol, attr->name_u64));
sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id=%d",
sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id = %d",
attr->name, (u32)attr->attr_protocol, rw_lock_id.GetValue());
return CELL_OK;
@ -51,7 +51,7 @@ int sys_rwlock_destroy(u32 rw_lock_id)
int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout)
{
sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=%d, timeout=%llu)", rw_lock_id, timeout);
sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=%d, timeout=%lld)", rw_lock_id, timeout);
RWLock* rw;
if (!sys_rwlock.CheckId(rw_lock_id, rw)) return CELL_ESRCH;
@ -63,7 +63,11 @@ int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout)
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
do
{
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
if (Emu.IsStopped())
{
ConLog.Warning("sys_rwlock_rlock(rw_lock_id=%d, ...) aborted", rw_lock_id);
return CELL_ETIMEDOUT;
}
Sleep(1);
if (rw->rlock_trylock(tid)) return CELL_OK;
@ -72,7 +76,6 @@ int sys_rwlock_rlock(u32 rw_lock_id, u64 timeout)
{
if (!timeout)
{
sys_rwlock.Warning("sys_rwlock_rlock(rw_lock_id=%d): TIMEOUT", rw_lock_id);
counter = 0;
}
else
@ -109,7 +112,7 @@ int sys_rwlock_runlock(u32 rw_lock_id)
int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout)
{
sys_rwlock.Log("sys_rwlock_wlock(rw_lock_id=%d, timeout=%llu)", rw_lock_id, timeout);
sys_rwlock.Log("sys_rwlock_wlock(rw_lock_id=%d, timeout=%lld)", rw_lock_id, timeout);
RWLock* rw;
if (!sys_rwlock.CheckId(rw_lock_id, rw)) return CELL_ESRCH;
@ -123,7 +126,11 @@ int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout)
const u32 max_counter = timeout ? (timeout / 1000) : 20000;
do
{
if (Emu.IsStopped()) return CELL_ETIMEDOUT;
if (Emu.IsStopped())
{
ConLog.Warning("sys_rwlock_wlock(rw_lock_id=%d, ...) aborted", rw_lock_id);
return CELL_ETIMEDOUT;
}
Sleep(1);
if (rw->wlock_trylock(tid, true)) return CELL_OK;
@ -132,7 +139,6 @@ int sys_rwlock_wlock(u32 rw_lock_id, u64 timeout)
{
if (!timeout)
{
sys_rwlock.Warning("sys_rwlock_wlock(rw_lock_id=%d): TIMEOUT", rw_lock_id);
counter = 0;
}
else

View File

@ -156,7 +156,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
//166
int sys_spu_thread_set_argument(u32 id, mem_ptr_t<sys_spu_thread_argument> arg)
{
sc_spu.Warning("sys_spu_thread_set_argument(id=0x%x, arg_addr=0x%x)", id, arg.GetAddr());
sc_spu.Warning("sys_spu_thread_set_argument(id=%d, arg_addr=0x%x)", id, arg.GetAddr());
CPUThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
@ -180,7 +180,7 @@ int sys_spu_thread_set_argument(u32 id, mem_ptr_t<sys_spu_thread_argument> arg)
//165
int sys_spu_thread_get_exit_status(u32 id, mem32_t status)
{
sc_spu.Warning("sys_spu_thread_get_exit_status(id=0x%x, status_addr=0x%x)", id, status.GetAddr());
sc_spu.Warning("sys_spu_thread_get_exit_status(id=%d, status_addr=0x%x)", id, status.GetAddr());
if (!status.IsGood())
{
@ -207,7 +207,7 @@ int sys_spu_thread_get_exit_status(u32 id, mem32_t status)
//171
int sys_spu_thread_group_destroy(u32 id)
{
sc_spu.Warning("sys_spu_thread_group_destroy(id=0x%x)", id);
sc_spu.Warning("sys_spu_thread_group_destroy(id=%d)", id);
SpuGroupInfo* group_info;
if(!Emu.GetIdManager().GetIDData(id, group_info))
@ -232,7 +232,7 @@ int sys_spu_thread_group_destroy(u32 id)
//173
int sys_spu_thread_group_start(u32 id)
{
sc_spu.Warning("sys_spu_thread_group_start(id=0x%x)", id);
sc_spu.Warning("sys_spu_thread_group_start(id=%d)", id);
SpuGroupInfo* group_info;
if(!Emu.GetIdManager().GetIDData(id, group_info))
@ -255,7 +255,7 @@ int sys_spu_thread_group_start(u32 id)
//174
int sys_spu_thread_group_suspend(u32 id)
{
sc_spu.Warning("sys_spu_thread_group_suspend(id=0x%x)", id);
sc_spu.Warning("sys_spu_thread_group_suspend(id=%d)", id);
SpuGroupInfo* group_info;
if(!Emu.GetIdManager().GetIDData(id, group_info))
@ -293,7 +293,7 @@ int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu
id = sc_spu.GetNewId(new SpuGroupInfo(name, num, prio, attr->type, attr->ct));
sc_spu.Warning("*** SPU Thread Group created [%s] (type=%d, option.ct=%d): id=%d",
sc_spu.Warning("*** SPU Thread Group created [%s] (type=0x%x, option.ct=0x%x): id=%d",
name.wx_str(), (int)attr->type, (u32)attr->ct, id.GetValue());
return CELL_OK;
@ -302,7 +302,7 @@ int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t<sys_spu
//178
int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
{
sc_spu.Warning("sys_spu_thread_group_join(id=0x%x, cause_addr=0x%x, status_addr=0x%x)", id, cause.GetAddr(), status.GetAddr());
sc_spu.Warning("sys_spu_thread_group_join(id=%d, cause_addr=0x%x, status_addr=0x%x)", id, cause.GetAddr(), status.GetAddr());
SpuGroupInfo* group_info;
if(!Emu.GetIdManager().GetIDData(id, group_info))
@ -326,7 +326,11 @@ int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
{
break;
}
if (Emu.IsStopped()) return CELL_OK;
if (Emu.IsStopped())
{
ConLog.Warning("sys_spu_thread_group_join(id=%d, ...) aborted", id);
return CELL_OK;
}
Sleep(1);
}
}
@ -342,40 +346,6 @@ int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u
return CELL_OK;
}
int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup)
{
sc_spu.Warning("sys_spu_thread_connect_event(id=0x%x,eq=0x%x,et=0x%x,spup=0x%x)", id, eq, et, spup);
EventQueue* equeue;
if(!sys_event.CheckId(eq, equeue))
{
return CELL_ESRCH;
}
if(spup > 63)
{
return CELL_EINVAL;
}
CPUThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
{
return CELL_ESRCH;
}
for(int j=0; j<equeue->pos; ++j)
{
if(!equeue->ports[j]->thread)
{
equeue->ports[j]->thread = thr;
return CELL_OK;
}
}
return CELL_EISCONN;
}
//160
int sys_raw_spu_create(mem32_t id, u32 attr_addr)
{
@ -414,7 +384,7 @@ int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)
//181
int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
{
sc_spu.Warning("sys_spu_thread_write_ls(id=0x%x, address=0x%x, value=0x%llx, type=0x%x)",
sc_spu.Warning("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=0x%x)",
id, address, value, type);
CPUThread* thr = Emu.GetCPU().GetThread(id);
@ -424,15 +394,30 @@ int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
return CELL_ESRCH;
}
(*(SPUThread*)thr).WriteLS64(address, value);
if (!thr->IsRunning())
{
return CELL_ESTAT;
}
return CELL_OK;
if (!(*(SPUThread*)thr).IsGoodLSA(address) || (address % type)) // +check alignment
{
return CELL_EINVAL;
}
switch (type)
{
case 1: (*(SPUThread*)thr).WriteLS8(address, value); return CELL_OK;
case 2: (*(SPUThread*)thr).WriteLS16(address, value); return CELL_OK;
case 4: (*(SPUThread*)thr).WriteLS32(address, value); return CELL_OK;
case 8: (*(SPUThread*)thr).WriteLS64(address, value); return CELL_OK;
default: return CELL_EINVAL;
}
}
//182
int sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type)
{
sc_spu.Warning("sys_spu_thread_read_ls(id=0x%x, address=0x%x, value_addr=0x%x, type=0x%x)",
sc_spu.Warning("sys_spu_thread_read_ls(id=%d, address=0x%x, value_addr=0x%x, type=0x%x)",
id, address, value.GetAddr(), type);
CPUThread* thr = Emu.GetCPU().GetThread(id);
@ -442,20 +427,35 @@ int sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type)
return CELL_ESRCH;
}
if(!value.IsGood() || !(*(SPUThread*)thr).IsGoodLSA(address))
if (!thr->IsRunning())
{
return CELL_ESTAT;
}
if(!value.IsGood())
{
return CELL_EFAULT;
}
value = (*(SPUThread*)thr).ReadLS64(address);
if (!(*(SPUThread*)thr).IsGoodLSA(address) || (address % type)) // +check alignment
{
return CELL_EINVAL;
}
return CELL_OK;
switch (type)
{
case 1: value = (*(SPUThread*)thr).ReadLS8(address); return CELL_OK;
case 2: value = (*(SPUThread*)thr).ReadLS16(address); return CELL_OK;
case 4: value = (*(SPUThread*)thr).ReadLS32(address); return CELL_OK;
case 8: value = (*(SPUThread*)thr).ReadLS64(address); return CELL_OK;
default: return CELL_EINVAL;
}
}
//190
int sys_spu_thread_write_spu_mb(u32 id, u32 value)
{
sc_spu.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x)", id, value);
sc_spu.Warning("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value);
CPUThread* thr = Emu.GetCPU().GetThread(id);
@ -464,11 +464,7 @@ int sys_spu_thread_write_spu_mb(u32 id, u32 value)
return CELL_ESRCH;
}
if(!(*(SPUThread*)thr).SPU.In_MBox.Push(value))
{
ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items.");
return CELL_EBUSY; //?
}
(*(SPUThread*)thr).SPU.In_MBox.PushUncond(value);
return CELL_OK;
}
@ -476,7 +472,7 @@ int sys_spu_thread_write_spu_mb(u32 id, u32 value)
//187
int sys_spu_thread_set_spu_cfg(u32 id, u64 value)
{
sc_spu.Warning("sys_spu_thread_set_spu_cfg(id=0x%x, value=0x%x)", id, value);
sc_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value);
CPUThread* thr = Emu.GetCPU().GetThread(id);
@ -498,7 +494,7 @@ int sys_spu_thread_set_spu_cfg(u32 id, u64 value)
//188
int sys_spu_thread_get_spu_cfg(u32 id, mem64_t value)
{
sc_spu.Warning("sys_spu_thread_get_spu_cfg(id=0x%x, value_addr=0x%x)", id, value.GetAddr());
sc_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value_addr=0x%x)", id, value.GetAddr());
CPUThread* thr = Emu.GetCPU().GetThread(id);
@ -515,7 +511,7 @@ int sys_spu_thread_get_spu_cfg(u32 id, mem64_t value)
//184
int sys_spu_thread_write_snr(u32 id, u32 number, u32 value)
{
sc_spu.Log("sys_spu_thread_write_snr(id=0x%x, number=%d, value=0x%x)", id, number, value);
sc_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value);
CPUThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
@ -540,9 +536,23 @@ int sys_spu_thread_write_snr(u32 id, u32 number, u32 value)
return CELL_OK;
}
int sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et)
{
sc_spu.Error("sys_spu_thread_group_connect_event(id=%d, eq=%d, et=0x%x)", id, eq, et);
return CELL_OK;
}
int sys_spu_thread_group_disconnect_event(u32 id, u32 et)
{
sc_spu.Error("sys_spu_thread_group_disconnect_event(id=%d, et=0x%x)", id, et);
return CELL_OK;
}
int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr)
{
sc_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=0x%x, eq=0x%x, req=0x%llx, spup_addr=0x%x)",
sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(id=%d, eq=%d, req=0x%llx, spup_addr=0x%x)",
id, eq, req, spup_addr);
EventQueue* equeue;
@ -562,6 +572,7 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32
return CELL_ESRCH;
}
/*
for(u32 i=0; i<group->list.GetCount(); ++i)
{
CPUThread* t;
@ -582,13 +593,79 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32
return CELL_EISCONN;
}
}
}
}*/
return CELL_OK;
}
int sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num)
int sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup)
{
sc_spu.Error("sys_spu_thread_bind_queue(id=0x%x, spuq=0x%x, spuq_num=0x%x)", id, spuq, spuq_num);
sc_spu.Error("sys_spu_thread_group_disconnect_event_all_threads(id=%d, spup=%d)", id, spup);
return CELL_OK;
}
int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup)
{
sc_spu.Error("sys_spu_thread_connect_event(id=%d, eq=%d, et=0x%x, spup=%d)", id, eq, et, spup);
EventQueue* equeue;
if(!sys_event.CheckId(eq, equeue))
{
return CELL_ESRCH;
}
if(spup > 63)
{
return CELL_EINVAL;
}
CPUThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || (thr->GetType() != CPU_THREAD_SPU && thr->GetType() != CPU_THREAD_RAW_SPU))
{
return CELL_ESRCH;
}
/*
for(int j=0; j<equeue->pos; ++j)
{
if(!equeue->ports[j]->thread)
{
equeue->ports[j]->thread = thr;
return CELL_OK;
}
}
*/
return CELL_EISCONN;
}
//
int sys_spu_thread_disconnect_event(u32 id, u32 event_type, u8 spup)
{
sc_spu.Error("sys_spu_thread_disconnect_event(id=%d, event_type=0x%x, spup=%d", id, event_type, spup);
return CELL_OK;
}
/*
SPU-Side functions:
int sys_spu_thread_receive_event(u32 spuq_num, mem32_t d1, mem32_t d2, mem32_t d3);
int sys_spu_thread_send_event(u8 spup, u24 data0, u32 data1);
int sys_spu_thread_throw_event(u8 spup, u24 data0, u32 data1);
int sys_spu_thread_tryreceive_event(u32 spuq_num, mem32_t d1, mem32_t d2, mem32_t d3);
*/
int sys_spu_thread_bind_queue(u32 id, u32 equeue_id, u32 spuq_num)
{
sc_spu.Error("sys_spu_thread_bind_queue(id=%d, equeue_id=%d, spuq_num=%d)", id, equeue_id, spuq_num);
return CELL_OK;
}
int sys_spu_thread_unbind_queue(u32 id, u32 spuq_num)
{
sc_spu.Error("sys_spu_thread_unbind_queue(id=0x%x, spuq_num=%d)", id, spuq_num);
return CELL_OK;
}

View File

@ -52,7 +52,7 @@ int sys_semaphore_create(u32 sem_addr, u32 attr_addr, int initial_count, int max
int sys_semaphore_destroy(u32 sem)
{
sys_sem.Log("sys_semaphore_destroy(sem=0x%x)", sem);
sys_sem.Log("sys_semaphore_destroy(sem=%d)", sem);
if(!sys_sem.CheckId(sem)) return CELL_ESRCH;
@ -75,7 +75,7 @@ int sys_semaphore_wait(u32 sem, u64 timeout)
int sys_semaphore_trywait(u32 sem)
{
sys_sem.Log("sys_semaphore_trywait(sem=0x%x)", sem);
sys_sem.Log("sys_semaphore_trywait(sem=%d)", sem);
semaphore* sem_data = nullptr;
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
@ -88,7 +88,7 @@ int sys_semaphore_trywait(u32 sem)
int sys_semaphore_post(u32 sem, int count)
{
sys_sem.Log("sys_semaphore_post(sem=0x%x, count=%d)", sem, 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;
@ -104,7 +104,7 @@ int sys_semaphore_post(u32 sem, int count)
int sys_semaphore_get_value(u32 sem, u32 count_addr)
{
sys_sem.Log("sys_semaphore_get_value(sem=0x%x, count_addr=0x%x)", sem, 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;

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
int sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr)
int sys_tty_read(s32 ch, u64 buf_addr, u32 len, u64 preadlen_addr)
{
ConLog.Warning("sys_tty_read: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len);
Memory.Write32NN(preadlen_addr, len);

View File

@ -355,6 +355,7 @@ void Emulator::Load()
GetGSManager().Init();
GetCallbackManager().Init();
GetAudioManager().Init();
GetEventManager().Init();
thread.Run();
@ -448,6 +449,7 @@ void Emulator::Stop()
GetGSManager().Close();
GetAudioManager().Close();
GetEventManager().Clear();
GetCPU().Close();
//SysCallsManager.Close();
GetIdManager().Clear();

View File

@ -13,6 +13,7 @@
#include "Loader/Loader.h"
#include "SysCalls/Callback.h"
#include "SysCalls/Modules.h"
#include "event.h"
struct EmuInfo
{
@ -89,6 +90,7 @@ class Emulator
AudioManager m_audio_manager;
CallbackManager m_callback_manager;
CPUThread* m_ppu_callback_thr;
EventManager m_event_manager;
VFS m_vfs;
@ -128,6 +130,7 @@ public:
Array<u64>& GetBreakPoints() { return m_break_points; }
Array<u64>& GetMarkedPoints() { return m_marked_points; }
CPUThread& GetCallbackThread() { return *m_ppu_callback_thr; }
EventManager& GetEventManager() { return m_event_manager; }
void AddModuleInit(ModuleInitializer* m)
{

View File

@ -1,4 +1,5 @@
#pragma once
#include "Emu/SysCalls/lv2/SC_Lwmutex.h"
enum EventQueueType
{
@ -6,10 +7,33 @@ enum EventQueueType
SYS_SPU_QUEUE = 2,
};
enum EventQueueDestroyMode
{
// DEFAULT = 0,
SYS_EVENT_QUEUE_DESTROY_FORCE = 1,
};
enum EventPortType
{
SYS_EVENT_PORT_LOCAL = 1,
};
enum EventSourceType
{
SYS_SPU_THREAD_EVENT_USER = 1,
/* SYS_SPU_THREAD_EVENT_DMA = 2, */ // not supported
};
enum EventSourceKey : u64
{
SYS_SPU_THREAD_EVENT_USER_KEY = 0xFFFFFFFF53505501,
/* SYS_SPU_THREAD_EVENT_DMA_KEY = 0xFFFFFFFF53505502, */
};
struct sys_event_queue_attr
{
be_t<u32> protocol; // SYS_SYNC_PRIORITY or SYS_SYNC_FIFO
be_t<int> type;
be_t<int> type; // SYS_PPU_QUEUE or SYS_SPU_QUEUE
union
{
char name[8];
@ -29,34 +53,171 @@ struct EventQueue;
struct EventPort
{
u64 name;
u64 data1;
u64 data2;
u64 data3;
bool has_data;
CPUThread* thread;
EventQueue* queue[127];
int pos;
};
u64 name; // generated or user-specified code that is passed to sys_event_data struct
EventQueue* eq; // event queue this port has been connected to
SMutex mutex; // may be locked until the event sending is finished
struct EventQueue
{
EventPort* ports[127];
int size;
int pos;
u32 m_protocol;
int m_type;
u64 m_name;
u64 m_key;
EventQueue(u32 protocol, int type, u64 name, u64 key, int size)
: m_type(type)
, m_protocol(protocol)
, m_name(name)
, m_key(key)
, size(size)
, pos(0)
EventPort(u64 name = 0)
: eq(nullptr)
, name(name)
{
}
};
class EventRingBuffer
{
Array<sys_event_data> data;
SMutex m_lock;
u32 buf_pos;
u32 buf_count;
public:
const u32 size;
EventRingBuffer(u32 size)
: size(size)
, buf_pos(0)
, buf_count(0)
{
data.SetCount(size);
}
void clear()
{
SMutexLocker lock(m_lock);
buf_count = 0;
buf_pos = 0;
}
bool push(u64 name, u64 d1, u64 d2, u64 d3)
{
SMutexLocker lock(m_lock);
if (buf_count >= size) return false;
sys_event_data& ref = data[(buf_pos + buf_count++) % size];
ref.source = name;
ref.data1 = d1;
ref.data2 = d2;
ref.data3 = d3;
return true;
}
bool pop(sys_event_data& ref)
{
SMutexLocker lock(m_lock);
if (!buf_count) return false;
sys_event_data& from = data[buf_pos];
buf_pos = (buf_pos + 1) % size;
buf_count--;
ref.source = from.source;
ref.data1 = from.data1;
ref.data2 = from.data2;
ref.data3 = from.data3;
return true;
}
u32 pop_all(sys_event_data* ptr, u32 max)
{
SMutexLocker lock(m_lock);
u32 res = 0;
while (buf_count && max)
{
sys_event_data& from = data[buf_pos];
ptr->source = from.source;
ptr->data1 = from.data1;
ptr->data2 = from.data2;
ptr->data3 = from.data3;
buf_pos = (buf_pos + 1) % size;
buf_count--;
max--;
ptr++;
res++;
}
return res;
}
u32 count()
{
return buf_count;
}
};
class EventPortList
{
Array<EventPort*> data;
SMutex m_lock;
public:
void clear()
{
SMutexLocker lock(m_lock);
for (u32 i = 0; i < data.GetCount(); i++)
{
data[i]->eq = nullptr; // force all ports to disconnect
}
data.Clear();
}
void add(EventPort* port)
{
SMutexLocker lock(m_lock);
data.AddCpy(port);
}
void remove(EventPort* port)
{
SMutexLocker lock(m_lock);
for (u32 i = 0; i < data.GetCount(); i++)
{
if (data[i] == port)
{
data.RemoveAt(i);
return;
}
}
}
};
struct EventQueue : SleepQueue
{
EventPortList ports;
EventRingBuffer events;
SMutex owner;
const union
{
u64 name_u64;
char name[8];
};
const u32 protocol;
const int type;
const u64 key;
EventQueue(u32 protocol, int type, u64 name, u64 key, int size)
: type(type)
, protocol(protocol)
, name_u64(name)
, key(key)
, events(size) // size: max event count this queue can hold
{
}
};
class EventManager
{
SMutex m_lock;
std::unordered_map<u64, EventQueue*> key_map;
public:
void Init();
void Clear();
bool CheckKey(u64 key);
bool RegisterKey(EventQueue* data, u64 key);
bool GetEventQueue(u64 key, EventQueue*& data);
bool UnregisterKey(u64 key);
};

View File

@ -224,6 +224,7 @@
<ClCompile Include="Emu\CPU\CPUThread.cpp" />
<ClCompile Include="Emu\CPU\CPUThreadManager.cpp" />
<ClCompile Include="Emu\DbgConsole.cpp" />
<ClCompile Include="Emu\Event.cpp" />
<ClCompile Include="Emu\FS\VFS.cpp" />
<ClCompile Include="Emu\FS\vfsDevice.cpp" />
<ClCompile Include="Emu\FS\vfsDirBase.cpp" />

View File

@ -388,6 +388,9 @@
<ClCompile Include="Emu\SysCalls\Modules\cellSysutilAp.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\Event.cpp">
<Filter>Emu\SysCalls</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />