From 970b834f2e82ef7d379a25fe74063b3d5b6d7165 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 12 Jan 2014 14:27:59 +0400 Subject: [PATCH] CellSync review (mutexes, SPU). File descriptors temporarily detached from ID manager. Some logs disabled. --- rpcs3/Emu/Cell/SPUThread.h | 39 +++----------- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 69 ++++++++++++++++-------- rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 46 ++++++++++++---- rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 65 ++++++++++++++-------- rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp | 4 +- rpcs3/Loader/Loader.h | 2 +- 6 files changed, 138 insertions(+), 87 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 38788022f1..84618e74a1 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -524,50 +524,23 @@ public: case MFC_PUTLLC_CMD: case MFC_PUTLLUC_CMD: { - extern wxMutex g_SyncMutex; - const CPUThread& current = *GetCurrentPPCThread(); + extern std::mutex g_SyncMutex; + //can provide compatability for CellSyncMutex through SPU<>PPU and SPU<>SPU if (op == MFC_GETLLAR_CMD) { - g_SyncMutex.Lock(); - /* for (u32 i = 0; i < Emu.GetCPU().GetThreads().GetCount(); i++) - { - CPUThread& t = *Emu.GetCPU().GetThread(i); - if (&t != ¤t && &t) - { - while (!t.IsRunning()) Sleep(1); - t.Pause(); - } - } - for (u32 i = 0; i < Emu.GetCPU().GetThreads().GetCount(); i++) - { - CPUThread& t = *Emu.GetCPU().GetThread(i); - if (&t != ¤t && &t) - { - if (!t.IsPaused()) Sleep(1); - } - } */ + g_SyncMutex.lock(); } ConLog.Warning("DMA %s: lsa=0x%x, ea = 0x%llx, (tag) = 0x%x, (size) = 0x%x, cmd = 0x%x", op == MFC_GETLLAR_CMD ? "GETLLAR" : op == MFC_PUTLLC_CMD ? "PUTLLC" : "PUTLLUC", lsa, ea, tag, size, cmd); - //draft implementation - _mm_mfence(); + dmac.ProcessCmd(op == MFC_GETLLAR_CMD ? MFC_GET_CMD : MFC_PUT_CMD, tag, lsa, ea, 128); Prxy.AtomicStat.PushUncond(op == MFC_GETLLAR_CMD ? MFC_GETLLAR_SUCCESS : op == MFC_PUTLLC_CMD ? MFC_PUTLLC_SUCCESS : MFC_PUTLLUC_SUCCESS); - _mm_mfence(); - if (op != MFC_GETLLAR_CMD) + if (op == MFC_PUTLLC_CMD || op == MFC_PUTLLUC_CMD) { - /*for (u32 i = 0; i < Emu.GetCPU().GetThreads().GetCount(); i++) - { - CPUThread& t = *Emu.GetCPU().GetThread(i); - if (&t != ¤t && &t) - { - t.Resume(); //it's wrong (some threads shall not be resumed) - } - }*/ - g_SyncMutex.Unlock(); + g_SyncMutex.unlock(); } } break; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 987a1d1db1..ee0ae0d43e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1,10 +1,12 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +#include void cellSync_init(); -Module cellSync("cellSync", cellSync_init); -wxMutex g_SyncMutex; +void cellSync_unload(); +Module cellSync("cellSync", cellSync_init, nullptr, cellSync_unload); +std::mutex g_SyncMutex; // Return Codes enum @@ -27,6 +29,7 @@ struct CellSyncMutex { be_t m_freed; be_t m_order; /* + (???) Initialize: set zeros (???) Lock: increase m_order and wait until m_freed == old m_order (???) Unlock: increase m_freed (???) TryLock: ????? @@ -45,16 +48,19 @@ int cellSyncMutexInitialize(mem_ptr_t mutex) { return CELL_SYNC_ERROR_ALIGN; } - { - wxMutexLocker lock(g_SyncMutex); + + { /* global mutex */ + std::lock_guard lock(g_SyncMutex); //??? mutex->m_freed = 0; mutex->m_order = 0; + return CELL_OK; } - return CELL_OK; } int cellSyncMutexLock(mem_ptr_t mutex) { + cellSync.Log("cellSyncMutexLock(mutex=0x%x)", mutex.GetAddr()); + if (!mutex.IsGood()) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -65,18 +71,31 @@ int cellSyncMutexLock(mem_ptr_t mutex) } be_t old_order; - { - wxMutexLocker lock(g_SyncMutex); - cellSync.Log("cellSyncMutexLock(mutex=0x%x[order=%d,freed=%d])", mutex.GetAddr(), (u16)mutex->m_order, (u16)mutex->m_freed); + { /* global mutex */ + std::lock_guard lock(g_SyncMutex); old_order = mutex->m_order; mutex->m_order = mutex->m_order + 1; } - while (old_order != mutex->m_freed) Sleep(1); + + int counter = 0; + while (old_order != mutex->m_freed) + { + Sleep(1); + if (++counter >= 5000) + { + Emu.Pause(); + cellSync.Error("cellSyncMutexLock(mutex=0x%x, old_order=%d, order=%d, freed=%d): TIMEOUT", + mutex.GetAddr(), (u16)old_order, (u16)mutex->m_order, (u16)mutex->m_freed); + break; + } + } return CELL_OK; } int cellSyncMutexTryLock(mem_ptr_t mutex) { + cellSync.Log("cellSyncMutexTryLock(mutex=0x%x)", mutex.GetAddr()); + if (!mutex.IsGood()) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -85,19 +104,21 @@ int cellSyncMutexTryLock(mem_ptr_t mutex) { return CELL_SYNC_ERROR_ALIGN; } - - wxMutexLocker lock(g_SyncMutex); - cellSync.Log("cellSyncMutexTryLock(mutex=0x%x[order=%d,freed=%d])", mutex.GetAddr(), (u16)mutex->m_order, (u16)mutex->m_freed); - if (mutex->m_order != mutex->m_freed) - { - return CELL_SYNC_ERROR_BUSY; + { /* global mutex */ + std::lock_guard lock(g_SyncMutex); + if (mutex->m_order != mutex->m_freed) + { + return CELL_SYNC_ERROR_BUSY; + } + mutex->m_order = mutex->m_order + 1; + return CELL_OK; } - mutex->m_order = mutex->m_order + 1; - return CELL_OK; } int cellSyncMutexUnlock(mem_ptr_t mutex) { + cellSync.Log("cellSyncMutexUnlock(mutex=0x%x)", mutex.GetAddr()); + if (!mutex.IsGood()) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -107,10 +128,11 @@ int cellSyncMutexUnlock(mem_ptr_t mutex) return CELL_SYNC_ERROR_ALIGN; } - wxMutexLocker lock(g_SyncMutex); - cellSync.Log("cellSyncMutexUnlock(mutex=0x%x[order=%d,freed=%d])", mutex.GetAddr(), (u16)mutex->m_order, (u16)mutex->m_freed); - mutex->m_freed = mutex->m_freed + 1; - return CELL_OK; + { /* global mutex */ + std::lock_guard lock(g_SyncMutex); + mutex->m_freed = mutex->m_freed + 1; + return CELL_OK; + } } void cellSync_init() @@ -119,4 +141,9 @@ void cellSync_init() cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock); cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock); cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock); +} + +void cellSync_unload() +{ + g_SyncMutex.unlock(); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 9bfc0ef639..ca291901f1 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -3,7 +3,9 @@ #include "Emu/SysCalls/SC_FUNC.h" void sys_fs_init(); -Module sys_fs(0x000e, sys_fs_init); +void sys_fs_unload(); +Module sys_fs(0x000e, sys_fs_init, nullptr, sys_fs_unload); +Array FDs; bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) { @@ -137,12 +139,9 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) std::atomic g_FsAioReadID = 0; -int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) +void fsAioRead(u32 fd, mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) { - ID id; - u32 fd = (u32)aio->fd; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsFileBase& orig_file = *(vfsFileBase*)id.m_data; + vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd]; u64 nbytes = (u64)aio->size; const u32 buf_addr = (u32)aio->buf_addr; @@ -175,10 +174,26 @@ int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_tbuf_addr); + //start callback thread + if(func) + func.async(aio.GetAddr(), error, xid, res); +} - //if(func) func.async(aio, error, xid, res); +int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) +{ + //ID id; + u32 fd = (u32)aio->fd; + //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + if (fd >= FDs.GetCount()) return CELL_ESRCH; + if (FDs[fd] == nullptr) return CELL_ESRCH; + //vfsFileBase& orig_file = *(vfsFileBase*)id.m_data; + vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd]; + + std::thread t(fsAioRead, fd, aio, aio_id, func); + t.detach(); + + sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x[%s, addr=0x%x], id_addr: 0x%x, func_addr: 0x%x)", aio.GetAddr(), + orig_file.GetPath().c_str(), (u32)aio->buf_addr, aio_id.GetAddr(), func.GetAddr()); return CELL_OK; } @@ -205,3 +220,16 @@ void sys_fs_init() sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize); sys_fs.AddFunc(0xc1c507e7, cellFsAioRead); } + +void sys_fs_unload() +{ + for (u32 i = 0; i < FDs.GetCount(); i++) + { + if (FDs[i]) + { + FDs[i]->Close(); + delete FDs[i]; + } + } + FDs.Clear(); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index d7bf58f94b..fb4ad1ddf5 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -3,6 +3,7 @@ #include "Emu/SysCalls/SysCalls.h" extern Module sys_fs; +extern Array FDs; int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) { @@ -94,7 +95,8 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_ENOENT; } - fd = sys_fs.GetNewId(stream, flags); + fd = FDs.AddCpy(stream); + //fd = sys_fs.GetNewId(stream, flags); sys_fs.Warning("cellFsOpen(path: %s): fd == %d", path.mb_str(), fd.GetValue()); return CELL_OK; @@ -104,9 +106,12 @@ 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)", fd, buf_addr, nbytes, nread.GetAddr()); - ID id; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsStream& file = *(vfsStream*)id.m_data; + //ID id; + //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + if (fd >= FDs.GetCount()) return CELL_ESRCH; + if (FDs[fd] == nullptr) return CELL_ESRCH; + //vfsStream& file = *(vfsStream*)id.m_data; + vfsStream& file = *(vfsStream*)FDs[fd]; if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) { @@ -126,9 +131,13 @@ 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)", fd, buf_addr, nbytes, nwrite.GetAddr()); - ID id; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsStream& file = *(vfsStream*)id.m_data; + //ID id; + //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + if (fd >= FDs.GetCount()) return CELL_ESRCH; + if (FDs[fd] == nullptr) return CELL_ESRCH; + //vfsStream& file = *(vfsStream*)id.m_data; + vfsStream& file = *(vfsStream*)FDs[fd]; + if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) { MemoryBlock& block = Memory.GetMemByAddr(buf_addr); @@ -145,12 +154,17 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite) int cellFsClose(u32 fd) { - sys_fs.Log("cellFsClose(fd: %d)", fd); - ID id; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsStream& file = *(vfsStream*)id.m_data; + sys_fs.Warning("cellFsClose(fd: %d)", fd); + //ID id; + //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + if (fd >= FDs.GetCount()) return CELL_ESRCH; + if (FDs[fd] == nullptr) return CELL_ESRCH; + //vfsStream& file = *(vfsStream*)id.m_data; + vfsStream& file = *(vfsStream*)FDs[fd]; file.Close(); - Emu.GetIdManager().RemoveID(fd); + delete FDs[fd]; + //Emu.GetIdManager().RemoveID(fd); + FDs[fd] = nullptr; return CELL_OK; } @@ -232,9 +246,12 @@ int cellFsStat(const u32 path_addr, mem_ptr_t sb) int cellFsFstat(u32 fd, mem_ptr_t sb) { sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr()); - ID id; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsStream& file = *(vfsStream*)id.m_data; + //ID id; + //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + if (fd >= FDs.GetCount()) return CELL_ESRCH; + if (FDs[fd] == nullptr) return CELL_ESRCH; + //vfsStream& file = *(vfsStream*)id.m_data; + vfsStream& file = *(vfsStream*)FDs[fd]; sb->st_mode = CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | @@ -313,9 +330,12 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos) sys_fs.Error(fd, "Unknown seek whence! (%d)", whence); return CELL_EINVAL; } - ID id; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsStream& file = *(vfsStream*)id.m_data; + //ID id; + //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + if (fd >= FDs.GetCount()) return CELL_ESRCH; + if (FDs[fd] == nullptr) return CELL_ESRCH; + //vfsStream& file = *(vfsStream*)id.m_data; + vfsStream& file = *(vfsStream*)FDs[fd]; pos = file.Seek(offset, seek_mode); return CELL_OK; } @@ -323,9 +343,12 @@ 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); - ID id; - if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - vfsStream& file = *(vfsStream*)id.m_data; + //ID id; + //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; + if (fd >= FDs.GetCount()) return CELL_ESRCH; + if (FDs[fd] == nullptr) return CELL_ESRCH; + //vfsStream& file = *(vfsStream*)id.m_data; + vfsStream& file = *(vfsStream*)FDs[fd]; u64 initialSize = file.GetSize(); if (initialSize < size) diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index 2f1c27f98c..543e72d975 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -138,7 +138,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< group_info.threads[spu_num] = &new_thread; - ConLog.Write("New SPU Thread:"); + /*ConLog.Write("New SPU Thread:"); ConLog.Write("SPU img offset = 0x%x", (u32)img->segs_addr); ConLog.Write("entry_point = 0x%x", spu_ep); ConLog.Write("name = %s", name.c_str()); @@ -147,7 +147,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< ConLog.Write("a3 = 0x%x", a3); ConLog.Write("a4 = 0x%x", a4); ConLog.Write("ls_offset = 0x%x", ((SPUThread&)new_thread).dmac.ls_offset); - ConLog.SkipLn(); + ConLog.SkipLn();*/ return CELL_OK; } diff --git a/rpcs3/Loader/Loader.h b/rpcs3/Loader/Loader.h index ab5c974c20..8e5ec023bd 100644 --- a/rpcs3/Loader/Loader.h +++ b/rpcs3/Loader/Loader.h @@ -2,7 +2,7 @@ #include "Emu/FS/vfsFileBase.h" #ifdef _DEBUG - #define LOADER_DEBUG + //#define LOADER_DEBUG #endif enum Elf_Machine