From 961fc272156890f66ca5cbfe235ebc1fea27bdc7 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 7 Mar 2015 16:39:07 +0300 Subject: [PATCH 1/6] Minor cleanup --- Utilities/Log.h | 2 +- Utilities/StrFmt.cpp | 86 ----- Utilities/StrFmt.h | 389 +--------------------- rpcs3/Emu/Cell/PPUThread.cpp | 1 - rpcs3/Emu/Cell/PPUThread.h | 1 - rpcs3/Emu/SysCalls/LogBase.h | 2 +- rpcs3/Emu/SysCalls/Modules/cellSail.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp | 8 - 8 files changed, 8 insertions(+), 483 deletions(-) diff --git a/Utilities/Log.h b/Utilities/Log.h index 04d1225f2d..2fbbee34de 100644 --- a/Utilities/Log.h +++ b/Utilities/Log.h @@ -132,5 +132,5 @@ void log_message(Log::LogType type, Log::LogSeverity sev, std::string text); template __noinline void log_message(Log::LogType type, Log::LogSeverity sev, const char* fmt, Targs... args) { - log_message(type, sev, fmt::detail::format(fmt, fmt::do_unveil(args)...)); + log_message(type, sev, fmt::Format(fmt, fmt::do_unveil(args)...)); } diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index f3f74a327d..b9eea87b95 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -70,92 +70,6 @@ std::string fmt::to_sdec(s64 svalue) return std::string(&res[first], sizeof(res) - first); } -size_t fmt::detail::get_fmt_start(const char* fmt, size_t len) -{ - for (size_t i = 0; i < len; i++) - { - if (fmt[i] == '%') - { - return i; - } - } - - return len; -} - -size_t fmt::detail::get_fmt_len(const char* fmt, size_t len) -{ - assert(len >= 2 && fmt[0] == '%'); - - size_t res = 2; - - if (fmt[1] == '.' || fmt[1] == '0') - { - assert(len >= 4 && fmt[2] - '1' < 9); - res += 2; - fmt += 2; - len -= 2; - - if (fmt[0] == '1') - { - assert(len >= 3 && fmt[1] - '0' < 7); - res++; - fmt++; - len--; - } - } - - if (fmt[1] == 'l') - { - assert(len >= 3); - res++; - fmt++; - len--; - } - - if (fmt[1] == 'l') - { - assert(len >= 3); - res++; - fmt++; - len--; - } - - return res; -} - -size_t fmt::detail::get_fmt_precision(const char* fmt, size_t len) -{ - assert(len >= 2); - - if (fmt[1] == '.' || fmt[1] == '0') - { - assert(len >= 4 && fmt[2] - '1' < 9); - - if (fmt[2] == '1') - { - assert(len >= 5 && fmt[3] - '0' < 7); - return 10 + fmt[3] - '0'; - } - - return fmt[2] - '0'; - } - - return 1; -} - -std::string fmt::detail::format(const char* fmt) -{ - const size_t len = strlen(fmt); - const size_t fmt_start = get_fmt_start(fmt, len); - if (fmt_start != len) - { - throw "Excessive formatting: " + std::string(fmt, len); - } - - return std::string(fmt, len); -} - extern const std::string fmt::placeholder = "???"; std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to) diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index 1272b68aa8..623555f70e 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -177,366 +177,6 @@ namespace fmt std::string to_udec(u64 value); std::string to_sdec(s64 value); - std::string toupper(std::string source); - - namespace detail - { - size_t get_fmt_start(const char* fmt, size_t len); - size_t get_fmt_len(const char* fmt, size_t len); - size_t get_fmt_precision(const char* fmt, size_t len); - - template - struct get_fmt - { - static_assert(!sizeof(T), "Unsupported fmt::format argument"); - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, u8 arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex(arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex(arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u') - { - return to_udec(arg); - } - else - { - throw "Invalid formatting (u8): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, u16 arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex(arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex(arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u') - { - return to_udec(arg); - } - else - { - throw "Invalid formatting (u16): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, u32 arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex(arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex(arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u') - { - return to_udec(arg); - } - else - { - throw "Invalid formatting (u32): " + std::string(fmt, len); - } - } - }; - -#ifdef __APPLE__ - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, unsigned long arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex(arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex(arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u') - { - return to_udec(arg); - } - else - { - throw "Invalid formatting (unsigned long): " + std::string(fmt, len); - } - } - }; -#endif - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, u64 arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex(arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex(arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u') - { - return to_udec(arg); - } - else - { - throw "Invalid formatting (u64): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, s8 arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex((u8)arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex((u8)arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd') - { - return to_sdec(arg); - } - else - { - throw "Invalid formatting (s8): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, s16 arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex((u16)arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex((u16)arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd') - { - return to_sdec(arg); - } - else - { - throw "Invalid formatting (s16): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, s32 arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex((u32)arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex((u32)arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd') - { - return to_sdec(arg); - } - else - { - throw "Invalid formatting (s32): " + std::string(fmt, len); - } - } - }; - -#ifdef __APPLE__ - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, long arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex((u64)arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex((u64)arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd') - { - return to_sdec(arg); - } - else - { - throw "Invalid formatting (long): " + std::string(fmt, len); - } - } - }; -#endif - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, s64 arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex((u64)arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex((u64)arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'd') - { - return to_sdec(arg); - } - else - { - throw "Invalid formatting (s64): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, float arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex((u32&)arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex((u32&)arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'f') - { - return std::to_string(arg); - } - else - { - throw "Invalid formatting (float): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, double arg) - { - if (fmt[len - 1] == 'x') - { - return to_hex((u64&)arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'X') - { - return fmt::toupper(to_hex((u64&)arg, get_fmt_precision(fmt, len))); - } - else if (fmt[len - 1] == 'f') - { - return std::to_string(arg); - } - else - { - throw "Invalid formatting (double): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, bool arg) - { - if (fmt[len - 1] == 'x' || fmt[len - 1] == 'X') - { - return to_hex(arg, get_fmt_precision(fmt, len)); - } - else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u') - { - return arg ? "1" : "0"; - } - else if (fmt[len - 1] == 's') - { - return arg ? "true" : "false"; - } - else - { - throw "Invalid formatting (bool): " + std::string(fmt, len); - } - } - }; - - template<> - struct get_fmt - { - static std::string text(const char* fmt, size_t len, const char* arg) - { - if (fmt[len - 1] == 's') - { - return arg; - } - else - { - throw "Invalid formatting (const char*): " + std::string(fmt, len); - } - } - }; - - std::string format(const char* fmt); // terminator - - template - std::string format(const char* fmt, const T& arg, Args... args) - { - const size_t len = strlen(fmt); - const size_t fmt_start = get_fmt_start(fmt, len); - const size_t fmt_len = get_fmt_len(fmt + fmt_start, len - fmt_start); - const size_t fmt_end = fmt_start + fmt_len; - - return std::string(fmt, fmt_start) + get_fmt::text(fmt + fmt_start, fmt_len, arg) + format(fmt + fmt_end, args...); - } - }; - template::value> struct unveil { @@ -612,24 +252,12 @@ namespace fmt /* fmt::format(const char* fmt, args...) - Formatting function with very limited functionality (compared to printf-like formatting) and be_t<> support + Formatting function with special functionality: - Supported types: + std::string forced to .c_str() + be_t<> forced to .value() (fmt::unveil reverts byte order automatically) - u8, s8 (%x, %d) - u16, s16 (%x, %d) - u32, s32 (%x, %d) - u64, s64 (%x, %d) - float (%x, %f) - double (%x, %f) - bool (%x, %d, %s) - char* (%s) - - std::string forced to .c_str() (fmt::unveil) - be_t<> of any appropriate type in this list (fmt::unveil) - enum of any appropriate type in this list (fmt::unveil) - - External specializations (can be found in another headers): + External specializations for fmt::unveil (can be found in another headers): vm::ps3::ptr (fmt::unveil) (vm_ptr.h) (with appropriate address type, using .addr() can be avoided) vm::ps3::bptr (fmt::unveil) (vm_ptr.h) vm::psv::ptr (fmt::unveil) (vm_ptr.h) @@ -637,18 +265,11 @@ namespace fmt vm::ps3::bref (fmt::unveil) (vm_ref.h) vm::psv::ref (fmt::unveil) (vm_ref.h) - Supported formatting: - %d - decimal; to_sdec() and to_udec() - %x - hexadecimal; to_hex(), %08x - hexadecimal with minimal length (from 02 to 016) - %s - string; generates "true" or "false" for bool - %f - floating point; only basic std::to_string() functionality - - Other features are not supported. */ template __forceinline __safebuffers std::string format(const char* fmt, Args... args) { - return detail::format(fmt, do_unveil(args)...); + return Format(fmt, do_unveil(args)...); } //convert a wxString to a std::string encoded in utf8 diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index b2a0410c4f..49a8727ea3 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -28,7 +28,6 @@ PPUThread& GetCurrentPPUThread() PPUThread::PPUThread() : CPUThread(CPU_THREAD_PPU) { - owned_mutexes = 0; Reset(); } diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index ee0254aa6a..53f3a2c412 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -536,7 +536,6 @@ public: //TBR : Time-Base Registers u64 TB; //TBR 0x10C - 0x10D - u32 owned_mutexes; std::function custom_task; public: diff --git a/rpcs3/Emu/SysCalls/LogBase.h b/rpcs3/Emu/SysCalls/LogBase.h index 880f5333c4..767594d8ec 100644 --- a/rpcs3/Emu/SysCalls/LogBase.h +++ b/rpcs3/Emu/SysCalls/LogBase.h @@ -20,7 +20,7 @@ class LogBase template __noinline void LogPrepare(LogType type, const char* fmt, Targs... args) const { - LogOutput(type, fmt::detail::format(fmt, args...)); + LogOutput(type, fmt::Format(fmt, args...)); } public: diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp index 8132afd92e..0ca3f285f6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp @@ -813,7 +813,7 @@ int cellSailPlayerCancel() int cellSailPlayerSetPaused(vm::ptr pSelf, bool paused) { - cellSail.Todo("cellSailPlayerSetPaused(pSelf_addr=0x%x, paused=)", pSelf.addr(), paused); + cellSail.Todo("cellSailPlayerSetPaused(pSelf_addr=0x%x, paused=%d)", pSelf.addr(), paused); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index f56fa14e2a..29c2dfbb00 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -10,16 +10,8 @@ SysCallBase sys_ppu_thread("sys_ppu_thread"); -static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU/*UUUUUUUUUUuuuuuuuuuu~~~~~~~~*/; - void ppu_thread_exit(PPUThread& CPU, u64 errorcode) { - if (CPU.owned_mutexes) - { - sys_ppu_thread.Error("Owned mutexes found (%d)", CPU.owned_mutexes); - CPU.owned_mutexes = 0; - } - CPU.SetExitStatus(errorcode); CPU.Stop(); From 4a6ef91eb31c96f3dcc4d8c33d158f924b0c98fd Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 7 Mar 2015 19:03:42 +0300 Subject: [PATCH 2/6] More cleanup --- Utilities/Thread.cpp | 53 +------------- Utilities/Thread.h | 71 ++++++++---------- rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp | 2 +- rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp | 26 +++---- rpcs3/Emu/ARMv7/Modules/sceLibc.cpp | 16 ++-- rpcs3/Emu/ARMv7/Modules/scePerf.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/cellFs.cpp | 93 ++++++++++++------------ rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 4 +- 8 files changed, 104 insertions(+), 163 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 5763b8e7d4..32a1bd9877 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1472,63 +1472,12 @@ bool waiter_map_t::is_stopped(u64 signal_id) { if (Emu.IsStopped()) { - LOG_WARNING(Log::HLE, "%s: waiter_op() aborted (signal_id=0x%llx)", m_name.c_str(), signal_id); + LOG_WARNING(Log::HLE, "%s: waiter_op() aborted (signal_id=0x%llx)", name.c_str(), signal_id); return true; } return false; } -void waiter_map_t::waiter_reg_t::init() -{ - if (!thread) - { - thread = GetCurrentNamedThread(); - - std::lock_guard lock(map.m_mutex); - - // add waiter - map.m_waiters.push_back({ signal_id, thread }); - } -} - -waiter_map_t::waiter_reg_t::~waiter_reg_t() -{ - if (thread) - { - std::lock_guard lock(map.m_mutex); - - // remove waiter - for (s64 i = map.m_waiters.size() - 1; i >= 0; i--) - { - if (map.m_waiters[i].signal_id == signal_id && map.m_waiters[i].thread == thread) - { - map.m_waiters.erase(map.m_waiters.begin() + i); - return; - } - } - - LOG_ERROR(HLE, "%s(): waiter not found (signal_id=0x%llx, map='%s')", __FUNCTION__, signal_id, map.m_name.c_str()); - Emu.Pause(); - } -} - -void waiter_map_t::notify(u64 signal_id) -{ - if (m_waiters.size()) - { - std::lock_guard lock(m_mutex); - - // find waiter and signal - for (auto& v : m_waiters) - { - if (v.signal_id == signal_id) - { - v.thread->Notify(); - } - } - } -} - const std::function SQUEUE_ALWAYS_EXIT = [](){ return true; }; const std::function SQUEUE_NEVER_EXIT = [](){ return false; }; diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 2bcf05b16c..eee78eac10 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -103,65 +103,54 @@ class slw_shared_mutex_t }; -class waiter_map_t +struct waiter_map_t { - // TODO: optimize (use custom lightweight readers-writer lock) - std::mutex m_mutex; + static const size_t size = 32; - struct waiter_t - { - u64 signal_id; - NamedThreadBase* thread; - }; + std::array mutex; + std::array cv; - std::vector m_waiters; + const std::string name; - std::string m_name; - - struct waiter_reg_t - { - NamedThreadBase* thread; - const u64 signal_id; - waiter_map_t& map; - - waiter_reg_t(waiter_map_t& map, u64 signal_id) - : thread(nullptr) - , signal_id(signal_id) - , map(map) - { - } - - ~waiter_reg_t(); - - void init(); - }; - - bool is_stopped(u64 signal_id); - -public: waiter_map_t(const char* name) - : m_name(name) + : name(name) { } + bool is_stopped(u64 signal_id); + // wait until waiter_func() returns true, signal_id is an arbitrary number - template __forceinline void wait_op(u64 signal_id, const WT waiter_func) + template __forceinline __safebuffers void wait_op(const S& signal_id, const WT waiter_func) { - // register waiter - waiter_reg_t waiter(*this, signal_id); + // generate hash + const auto hash = std::hash()(signal_id) % size; + + // set mutex locker + std::unique_lock locker(mutex[hash], std::defer_lock); // check the condition or if the emulator is stopped while (!waiter_func() && !is_stopped(signal_id)) { - // initialize waiter (only once) - waiter.init(); - // wait for 1 ms or until signal arrived - waiter.thread->WaitForAnySignal(1); + // lock the mutex and initialize waiter (only once) + if (!locker.owns_lock()) + { + locker.lock(); + } + + // wait on appropriate condition variable for 1 ms or until signal arrived + cv[hash].wait_for(locker, std::chrono::milliseconds(1)); } } // signal all threads waiting on waiter_op() with the same signal_id (signaling only hints those threads that corresponding conditions are *probably* met) - void notify(u64 signal_id); + template __forceinline void notify(const S& signal_id) + { + // generate hash + const auto hash = std::hash()(signal_id) % size; + + // signal appropriate condition variable + cv[hash].notify_all(); + } }; extern const std::function SQUEUE_ALWAYS_EXIT; diff --git a/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp b/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp index c03dbe24dd..c03c7622e5 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp @@ -110,4 +110,4 @@ psv_log_base sceDisplay("SceDisplay", []() REG_FUNC(0x3E796EF5, sceDisplayWaitSetFrameBufMultiCB); REG_FUNC(0x6BDF4C4D, sceDisplayRegisterVblankStartCallback); REG_FUNC(0x98436A80, sceDisplayUnregisterVblankStartCallback); -}); \ No newline at end of file +}); diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp index 8093a2b9dd..b619d5bb6b 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp @@ -44,7 +44,7 @@ s32 sceKernelCreateThread( s32 cpuAffinityMask, vm::psv::ptr pOptParam) { - sceLibKernel.Warning("sceKernelCreateThread(pName=0x%x, entry=0x%x, initPriority=%d, stackSize=0x%x, attr=0x%x, cpuAffinityMask=0x%x, pOptParam=0x%x)", + sceLibKernel.Warning("sceKernelCreateThread(pName=*0x%x, entry=*0x%x, initPriority=%d, stackSize=0x%x, attr=0x%x, cpuAffinityMask=0x%x, pOptParam=*0x%x)", pName, entry, initPriority, stackSize, attr, cpuAffinityMask, pOptParam); auto t = Emu.GetCPU().AddThread(CPU_THREAD_ARMv7); @@ -62,7 +62,7 @@ s32 sceKernelCreateThread( s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr pArgBlock) { - sceLibKernel.Warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=0x%x)", threadId, argSize, pArgBlock); + sceLibKernel.Warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=*0x%x)", threadId, argSize, pArgBlock); std::shared_ptr t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); @@ -185,7 +185,7 @@ s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr) s32 sceKernelGetThreadExitStatus(s32 threadId, vm::psv::ptr pExitStatus) { - sceLibKernel.Todo("sceKernelGetThreadExitStatus(threadId=0x%x, pExitStatus=0x%x)", threadId, pExitStatus); + sceLibKernel.Todo("sceKernelGetThreadExitStatus(threadId=0x%x, pExitStatus=*0x%x)", threadId, pExitStatus); throw __FUNCTION__; } @@ -206,21 +206,21 @@ s32 sceKernelCheckWaitableStatus() s32 sceKernelGetThreadInfo(s32 threadId, vm::psv::ptr pInfo) { - sceLibKernel.Todo("sceKernelGetThreadInfo(threadId=0x%x, pInfo=0x%x)", threadId, pInfo); + sceLibKernel.Todo("sceKernelGetThreadInfo(threadId=0x%x, pInfo=*0x%x)", threadId, pInfo); throw __FUNCTION__; } s32 sceKernelGetThreadRunStatus(vm::psv::ptr pStatus) { - sceLibKernel.Todo("sceKernelGetThreadRunStatus(pStatus=0x%x)", pStatus); + sceLibKernel.Todo("sceKernelGetThreadRunStatus(pStatus=*0x%x)", pStatus); throw __FUNCTION__; } s32 sceKernelGetSystemInfo(vm::psv::ptr pInfo) { - sceLibKernel.Todo("sceKernelGetSystemInfo(pInfo=0x%x)", pInfo); + sceLibKernel.Todo("sceKernelGetSystemInfo(pInfo=*0x%x)", pInfo); throw __FUNCTION__; } @@ -262,7 +262,7 @@ s32 sceKernelDelayThreadCB(u32 usec) s32 sceKernelWaitThreadEnd(s32 threadId, vm::psv::ptr pExitStatus, vm::psv::ptr pTimeout) { - sceLibKernel.Warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout); + sceLibKernel.Warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout); std::shared_ptr t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); @@ -297,7 +297,7 @@ s32 sceKernelWaitThreadEnd(s32 threadId, vm::psv::ptr pExitStatus, vm::psv: s32 sceKernelWaitThreadEndCB(s32 threadId, vm::psv::ptr pExitStatus, vm::psv::ptr pTimeout) { - sceLibKernel.Todo("sceKernelWaitThreadEndCB(threadId=0x%x, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout); + sceLibKernel.Todo("sceKernelWaitThreadEndCB(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout); throw __FUNCTION__; } @@ -395,7 +395,7 @@ s32 sceKernelWaitMultipleEventsCB(vm::psv::ptr pWaitEventLis s32 sceKernelCreateEventFlag(vm::psv::ptr pName, u32 attr, u32 initPattern, vm::psv::ptr pOptParam) { - sceLibKernel.Error("sceKernelCreateEventFlag(pName=0x%x, attr=0x%x, initPattern=0x%x, pOptParam=0x%x)", pName, attr, initPattern, pOptParam); + sceLibKernel.Error("sceKernelCreateEventFlag(pName=*0x%x, attr=0x%x, initPattern=0x%x, pOptParam=*0x%x)", pName, attr, initPattern, pOptParam); if (s32 id = g_psv_ef_list.add(new psv_event_flag_t(pName.get_ptr(), attr, initPattern), 0)) { @@ -459,7 +459,7 @@ s32 sceKernelGetEventFlagInfo(s32 evfId, vm::psv::ptr pI s32 sceKernelCreateSema(vm::psv::ptr pName, u32 attr, s32 initCount, s32 maxCount, vm::psv::ptr pOptParam) { - sceLibKernel.Error("sceKernelCreateSema(pName=0x%x, attr=0x%x, initCount=%d, maxCount=%d, pOptParam=0x%x)", pName, attr, initCount, maxCount, pOptParam); + sceLibKernel.Error("sceKernelCreateSema(pName=*0x%x, attr=0x%x, initCount=%d, maxCount=%d, pOptParam=*0x%x)", pName, attr, initCount, maxCount, pOptParam); if (s32 id = g_psv_sema_list.add(new psv_sema_t(pName.get_ptr(), attr, initCount, maxCount), 0)) { @@ -500,7 +500,7 @@ s32 sceKernelCloseSema(s32 semaId) s32 sceKernelWaitSema(s32 semaId, s32 needCount, vm::psv::ptr pTimeout) { - sceLibKernel.Error("sceKernelWaitSema(semaId=0x%x, needCount=%d, pTimeout=0x%x)", semaId, needCount, pTimeout); + sceLibKernel.Error("sceKernelWaitSema(semaId=0x%x, needCount=%d, pTimeout=*0x%x)", semaId, needCount, pTimeout); ref_t sema = g_psv_sema_list.get(semaId); @@ -543,7 +543,7 @@ s32 sceKernelGetSemaInfo(s32 semaId, vm::psv::ptr pInfo) s32 sceKernelCreateMutex(vm::psv::ptr pName, u32 attr, s32 initCount, vm::psv::ptr pOptParam) { - sceLibKernel.Error("sceKernelCreateMutex(pName=0x%x, attr=0x%x, initCount=%d, pOptParam=0x%x)", pName, attr, initCount, pOptParam); + sceLibKernel.Error("sceKernelCreateMutex(pName=*0x%x, attr=0x%x, initCount=%d, pOptParam=*0x%x)", pName, attr, initCount, pOptParam); if (s32 id = g_psv_mutex_list.add(new psv_mutex_t(pName.get_ptr(), attr, initCount), 0)) { @@ -644,7 +644,7 @@ s32 sceKernelGetLwMutexInfoById(s32 lwMutexId, vm::psv::ptr pName, u32 attr, s32 mutexId, vm::psv::ptr pOptParam) { - sceLibKernel.Error("sceKernelCreateCond(pName=0x%x, attr=0x%x, mutexId=0x%x, pOptParam=0x%x)", pName, attr, mutexId, pOptParam); + sceLibKernel.Error("sceKernelCreateCond(pName=*0x%x, attr=0x%x, mutexId=0x%x, pOptParam=*0x%x)", pName, attr, mutexId, pOptParam); if (s32 id = g_psv_cond_list.add(new psv_cond_t(pName.get_ptr(), attr, mutexId), 0)) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index 57eb484dcd..bd21c9405d 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -150,7 +150,7 @@ namespace sce_libc_func { void __cxa_atexit(vm::psv::ptr func, vm::psv::ptr arg, vm::psv::ptr dso) { - sceLibc.Warning("__cxa_atexit(func=0x%x, arg=0x%x, dso=0x%x)", func, arg, dso); + sceLibc.Warning("__cxa_atexit(func=*0x%x, arg=*0x%x, dso=*0x%x)", func, arg, dso); LV2_LOCK; @@ -162,7 +162,7 @@ namespace sce_libc_func void __aeabi_atexit(vm::psv::ptr arg, vm::psv::ptr func, vm::psv::ptr dso) { - sceLibc.Warning("__aeabi_atexit(arg=0x%x, func=0x%x, dso=0x%x)", arg, func, dso); + sceLibc.Warning("__aeabi_atexit(arg=*0x%x, func=*0x%x, dso=*0x%x)", arg, func, dso); LV2_LOCK; @@ -195,7 +195,7 @@ namespace sce_libc_func void printf(ARMv7Context& context, vm::psv::ptr fmt) // va_args... { - sceLibc.Warning("printf(fmt=0x%x)", fmt); + sceLibc.Warning("printf(fmt=*0x%x)", fmt); sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); const std::string& result = armv7_fmt(context, fmt, 1, 0, 0); @@ -206,7 +206,7 @@ namespace sce_libc_func void sprintf(ARMv7Context& context, vm::psv::ptr str, vm::psv::ptr fmt) // va_args... { - sceLibc.Warning("sprintf(str=0x%x, fmt=0x%x)", str, fmt); + sceLibc.Warning("sprintf(str=*0x%x, fmt=*0x%x)", str, fmt); sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); const std::string& result = armv7_fmt(context, fmt, 2, 0, 0); @@ -217,28 +217,28 @@ namespace sce_libc_func void __cxa_set_dso_handle_main(vm::psv::ptr dso) { - sceLibc.Warning("__cxa_set_dso_handle_main(dso=0x%x)", dso); + sceLibc.Warning("__cxa_set_dso_handle_main(dso=*0x%x)", dso); g_dso = dso; } void memcpy(vm::psv::ptr dst, vm::psv::ptr src, u32 size) { - sceLibc.Warning("memcpy(dst=0x%x, src=0x%x, size=0x%x)", dst, src, size); + sceLibc.Warning("memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size); ::memcpy(dst.get_ptr(), src.get_ptr(), size); } void memset(vm::psv::ptr dst, s32 value, u32 size) { - sceLibc.Warning("memset(dst=0x%x, value=%d, size=0x%x)", dst, value, size); + sceLibc.Warning("memset(dst=*0x%x, value=%d, size=0x%x)", dst, value, size); ::memset(dst.get_ptr(), value, size); } void _Assert(ARMv7Context& context, vm::psv::ptr text, vm::psv::ptr func) { - sceLibc.Error("_Assert(text=0x%x, func=0x%x)", text, func); + sceLibc.Error("_Assert(text=*0x%x, func=*0x%x)", text, func); LOG_ERROR(TTY, "%s : %s\n", func.get_ptr(), text.get_ptr()); LOG_NOTICE(ARMv7, context.thread.RegsToString()); diff --git a/rpcs3/Emu/ARMv7/Modules/scePerf.cpp b/rpcs3/Emu/ARMv7/Modules/scePerf.cpp index fabf63691a..a9ff8e8308 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePerf.cpp +++ b/rpcs3/Emu/ARMv7/Modules/scePerf.cpp @@ -187,7 +187,7 @@ s32 scePerfArmPmonStop(ARMv7Context& context, s32 threadId) s32 scePerfArmPmonGetCounterValue(ARMv7Context& context, s32 threadId, u32 counter, vm::psv::ptr pValue) { - scePerf.Warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=0x%x)", threadId, counter, pValue); + scePerf.Warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=*0x%x)", threadId, counter, pValue); if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF) { diff --git a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp index a6019aa7fb..b232a54048 100644 --- a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp @@ -42,8 +42,8 @@ struct FsRingBufferConfig s32 cellFsOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::ptr arg, u64 size) { - sys_fs.Log("cellFsOpen(path_addr=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx)", path.addr(), flags, fd, arg, size); - sys_fs.Log("cellFsOpen(path='%s')", path.get_ptr()); + sys_fs.Log("cellFsOpen(path=*0x%x, flags=0x%x, fd=*0x%x, arg=*0x%x, size=0x%llx)", path, flags, fd, arg, size); + sys_fs.Log("*** path = '%s'", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -145,7 +145,7 @@ s32 cellFsRead(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr> nread) s32 cellFsWrite(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite) { - sys_fs.Log("cellFsWrite(fd=0x%x, buf=0x%x, nbytes=0x%llx, nwrite=0x%x)", fd, buf, nbytes, nwrite); + sys_fs.Log("cellFsWrite(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -173,8 +173,8 @@ s32 cellFsClose(u32 fd) s32 cellFsOpendir(vm::ptr path, vm::ptr fd) { - sys_fs.Warning("cellFsOpendir(path_addr=0x%x, fd=0x%x)", path.addr(), fd); - sys_fs.Warning("cellFsOpendir(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsOpendir(path=*0x%x, fd=*0x%x)", path, fd); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); std::shared_ptr dir(Emu.GetVFS().OpenDir(path.get_ptr())); if (!dir || !dir->IsOpened()) @@ -188,7 +188,7 @@ s32 cellFsOpendir(vm::ptr path, vm::ptr fd) s32 cellFsReaddir(u32 fd, vm::ptr dir, vm::ptr nread) { - sys_fs.Warning("cellFsReaddir(fd=0x%x, dir=0x%x, nread=0x%x)", fd, dir, nread); + sys_fs.Warning("cellFsReaddir(fd=0x%x, dir=*0x%x, nread=*0x%x)", fd, dir, nread); std::shared_ptr directory; if (!Emu.GetIdManager().GetIDData(fd, directory)) @@ -222,8 +222,8 @@ s32 cellFsClosedir(u32 fd) s32 cellFsStat(vm::ptr path, vm::ptr sb) { - sys_fs.Warning("cellFsStat(path_addr=0x%x, sb=0x%x)", path.addr(), sb); - sys_fs.Warning("cellFsStat(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsStat(path=*0x%x, sb=*0x%x)", path, sb); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -305,7 +305,7 @@ s32 cellFsStat(vm::ptr path, vm::ptr sb) s32 cellFsFstat(u32 fd, vm::ptr sb) { - sys_fs.Warning("cellFsFstat(fd=0x%x, sb=0x%x)", fd, sb); + sys_fs.Warning("cellFsFstat(fd=0x%x, sb=*0x%x)", fd, sb); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -330,8 +330,8 @@ s32 cellFsFstat(u32 fd, vm::ptr sb) s32 cellFsMkdir(vm::ptr path, u32 mode) { - sys_fs.Warning("cellFsMkdir(path_addr=0x%x, mode=0x%x)", path.addr(), mode); - sys_fs.Warning("cellFsMkdir(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsMkdir(path=*0x%x, mode=0x%x)", path, mode); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -347,8 +347,9 @@ s32 cellFsMkdir(vm::ptr path, u32 mode) s32 cellFsRename(vm::ptr from, vm::ptr to) { - sys_fs.Warning("cellFsRename(from_addr=0x%x, to_addr=0x%x)", from.addr(), to.addr()); - sys_fs.Warning("cellFsRename(from='%s', to='%s')", from.get_ptr(), to.get_ptr()); + sys_fs.Warning("cellFsRename(from=*0x%x, to=*0x%x)", from, to); + sys_fs.Warning("*** from = '%s'", from.get_ptr()); + sys_fs.Warning("*** to = '%s'", to.get_ptr()); std::string _from = from.get_ptr(); std::string _to = to.get_ptr(); @@ -382,8 +383,8 @@ s32 cellFsRename(vm::ptr from, vm::ptr to) } s32 cellFsChmod(vm::ptr path, u32 mode) { - sys_fs.Todo("cellFsChmod(path_addr=0x%x, mode=0x%x)", path.addr(), mode); - sys_fs.Todo("cellFsChmod(path='%s')", path.get_ptr()); + sys_fs.Todo("cellFsChmod(path=*0x%x, mode=0x%x)", path, mode); + sys_fs.Todo("*** path = '%s'", path.get_ptr()); // TODO: @@ -401,8 +402,8 @@ s32 cellFsFsync(u32 fd) s32 cellFsRmdir(vm::ptr path) { - sys_fs.Warning("cellFsRmdir(path_addr=0x%x)", path.addr()); - sys_fs.Warning("cellFsRmdir(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsRmdir(path=*0x%x)", path); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); std::string _path = path.get_ptr(); @@ -419,8 +420,8 @@ s32 cellFsRmdir(vm::ptr path) s32 cellFsUnlink(vm::ptr path) { - sys_fs.Warning("cellFsUnlink(path_addr=0x%x)", path.addr()); - sys_fs.Warning("cellFsUnlink(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsUnlink(path=*0x%x)", path); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); std::string _path = path.get_ptr(); @@ -439,7 +440,7 @@ s32 cellFsUnlink(vm::ptr path) s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr> pos) { - sys_fs.Log("cellFsLseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=0x%x)", fd, offset, whence, pos); + sys_fs.Log("cellFsLseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos); vfsSeekMode seek_mode; switch(whence) @@ -490,8 +491,8 @@ s32 cellFsFtruncate(u32 fd, u64 size) s32 cellFsTruncate(vm::ptr path, u64 size) { - sys_fs.Warning("cellFsTruncate(path_addr=0x%x, size=0x%llx)", path.addr(), size); - sys_fs.Warning("cellFsTruncate(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsTruncate(path=*0x%x, size=0x%llx)", path, size); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); vfsFile f(path.get_ptr(), vfsReadWrite); if (!f.IsOpened()) @@ -521,7 +522,7 @@ s32 cellFsTruncate(vm::ptr path, u64 size) s32 cellFsFGetBlockSize(u32 fd, vm::ptr sector_size, vm::ptr block_size) { - sys_fs.Warning("cellFsFGetBlockSize(fd=0x%x, sector_size=0x%x, block_size=0x%x)", fd, sector_size, block_size); + sys_fs.Warning("cellFsFGetBlockSize(fd=0x%x, sector_size=*0x%x, block_size=*0x%x)", fd, sector_size, block_size); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -535,8 +536,8 @@ s32 cellFsFGetBlockSize(u32 fd, vm::ptr sector_size, vm::ptr block_siz s32 cellFsGetBlockSize(vm::ptr path, vm::ptr sector_size, vm::ptr block_size) { - sys_fs.Warning("cellFsGetBlockSize(path_addr=0x%x, sector_size=0x%x, block_size=0x%x)", path.addr(), sector_size, block_size); - sys_fs.Warning("cellFsGetBlockSize(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsGetBlockSize(path=*0x%x, sector_size=*0x%x, block_size=*0x%x)", path, sector_size, block_size); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); *sector_size = 4096; // ? *block_size = 4096; // ? @@ -546,8 +547,8 @@ s32 cellFsGetBlockSize(vm::ptr path, vm::ptr sector_size, vm::p s32 cellFsGetFreeSize(vm::ptr path, vm::ptr block_size, vm::ptr block_count) { - sys_fs.Warning("cellFsGetFreeSize(path_addr=0x%x, block_size=0x%x, block_count=0x%x)", path.addr(), block_size, block_count); - sys_fs.Warning("cellFsGetFreeSize(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsGetFreeSize(path=*0x%x, block_size=*0x%x, block_count=*0x%x)", path, block_size, block_count); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); // TODO: Get real values. Currently, it always returns 40 GB of free space divided in 4 KB blocks *block_size = 4096; // ? @@ -558,7 +559,7 @@ s32 cellFsGetFreeSize(vm::ptr path, vm::ptr block_size, vm::ptr s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 entries_size, vm::ptr data_count) { - sys_fs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=0x%x, entries_size=0x%x, data_count=0x%x)", fd, entries, entries_size, data_count); + sys_fs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count); std::shared_ptr directory; if (!Emu.GetIdManager().GetIDData(fd, directory)) @@ -594,7 +595,7 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) { - sys_fs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=0x%x)", fd, ringbuf); + sys_fs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -633,7 +634,7 @@ s32 cellFsStReadFinish(u32 fd) s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) { - sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=0x%x)", fd, ringbuf); + sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -648,7 +649,7 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) { - sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=0x%x)", fd, status); + sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=*0x%x)", fd, status); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -661,7 +662,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) { - sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=0x%x)", fd, regid); + sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=*0x%x)", fd, regid); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -701,7 +702,7 @@ s32 cellFsStReadStop(u32 fd) s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) { - sys_fs.Warning("cellFsStRead(fd=0x%x, buf=0x%x, size=0x%llx, rsize=0x%x)", fd, buf, size, rsize); + sys_fs.Warning("cellFsStRead(fd=0x%x, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -720,7 +721,7 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr> addr, vm::ptr size) { - sys_fs.Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=0x%x, size=0x%x)", fd, addr, size); + sys_fs.Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -731,7 +732,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr> addr, vm::ptr s s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) { - sys_fs.Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=0x%x, size=0x%llx)", fd, addr, size); + sys_fs.Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -753,7 +754,7 @@ s32 cellFsStReadWait(u32 fd, u64 size) s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr func) { - sys_fs.Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=0x%x)", fd, size, func); + sys_fs.Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func); std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) @@ -864,8 +865,8 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil s32 cellFsSdataOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::ptr arg, u64 size) { - sys_fs.Warning("cellFsSdataOpen(path_addr=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx) -> cellFsOpen()", path.addr(), flags, fd, arg, size); - sys_fs.Warning("cellFsSdataOpen(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsSdataOpen(path=*0x%x, flags=0x%x, fd=*0x%x, arg=*0x%x, size=0x%llx) -> cellFsOpen()", path, flags, fd, arg, size); + sys_fs.Warning("*** path = '%s'", path.get_ptr()); /*if (flags != CELL_O_RDONLY) return CELL_EINVAL; @@ -889,7 +890,7 @@ s32 cellFsSdataOpen(vm::ptr path, s32 flags, vm::ptr> fd, s32 cellFsSdataOpenByFd(u32 mself_fd, s32 flags, vm::ptr sdata_fd, u64 offset, vm::ptr arg, u64 size) { - sys_fs.Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=0x%x, sdata_fd=0x%x, offset=0x%llx, arg=0x%x, size=0x%llx)", mself_fd, flags, sdata_fd, offset, arg, size); + sys_fs.Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=0x%x, sdata_fd=*0x%x, offset=0x%llx, arg=*0x%x, size=0x%llx)", mself_fd, flags, sdata_fd, offset, arg, size); // TODO: @@ -957,7 +958,7 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptr aio, vm::ptr id, vm::ptr xaio, s32 error, s32 xid, u64 size)> func) { - sys_fs.Warning("cellFsAioRead(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func); + sys_fs.Warning("cellFsAioRead(aio=*0x%x, id=*0x%x, func=*0x%x)", aio, id, func); if (!aio_init) { @@ -982,7 +983,7 @@ s32 cellFsAioRead(vm::ptr aio, vm::ptr id, vm::ptr aio, vm::ptr id, vm::ptr xaio, s32 error, s32 xid, u64 size)> func) { - sys_fs.Todo("cellFsAioWrite(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func); + sys_fs.Todo("cellFsAioWrite(aio=*0x%x, id=*0x%x, func=*0x%x)", aio, id, func); // TODO: @@ -991,8 +992,8 @@ s32 cellFsAioWrite(vm::ptr aio, vm::ptr id, vm::ptr mount_point) { - sys_fs.Warning("cellFsAioInit(mount_point_addr=0x%x)", mount_point.addr()); - sys_fs.Warning("cellFsAioInit(mount_point='%s')", mount_point.get_ptr()); + sys_fs.Warning("cellFsAioInit(mount_point=*0x%x)", mount_point); + sys_fs.Warning("*** mount_point = '%s'", mount_point.get_ptr()); aio_init = true; return CELL_OK; @@ -1000,8 +1001,8 @@ s32 cellFsAioInit(vm::ptr mount_point) s32 cellFsAioFinish(vm::ptr mount_point) { - sys_fs.Warning("cellFsAioFinish(mount_point_addr=0x%x)", mount_point.addr()); - sys_fs.Warning("cellFsAioFinish(mount_point='%s')", mount_point.get_ptr()); + sys_fs.Warning("cellFsAioFinish(mount_point=*0x%x)", mount_point); + sys_fs.Warning("*** mount_point = '%s'", mount_point.get_ptr()); //aio_init = false; return CELL_OK; @@ -1009,7 +1010,7 @@ s32 cellFsAioFinish(vm::ptr mount_point) s32 cellFsReadWithOffset(PPUThread& CPU, u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr> nread) { - sys_fs.Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=0x%x, buffer_size=%lld, nread=0x%llx)", fd, offset, buf, buffer_size, nread); + sys_fs.Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=*0x%x, buffer_size=%lld, nread=*0x%llx)", fd, offset, buf, buffer_size, nread); int ret; vm::stackvar> oldPos(CPU), newPos(CPU); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 542ed346c8..66d8f1d0aa 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -266,12 +266,14 @@ s32 sys_spu_thread_group_destroy(u32 id) Memory.MainMem.Free(spu.offset); Emu.GetCPU().RemoveThread(spu.GetId()); + + t.reset(); } } - group->threads = {}; group->state = SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED; // hack Emu.GetIdManager().RemoveID(id); + return CELL_OK; } From cf335a5dc4bf13bad4d739c2b558ee3d33d7749a Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 7 Mar 2015 20:39:25 +0300 Subject: [PATCH 3/6] Video freezing fixed --- rpcs3/Emu/SysCalls/Modules/cellDmux.cpp | 41 ++++++++++++++++++------- rpcs3/Emu/SysCalls/Modules/cellDmux.h | 2 ++ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index e9a9b7c72c..f5fc056ef9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -347,12 +347,18 @@ u32 dmuxOpen(Demuxer* dmux_ptr) if (!stream.peek(code)) { // demuxing finished + dmux.is_running = false; + + // callback auto dmuxMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->supplementalInfo = stream.userdata; dmux.cbFunc(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); - dmux.is_running = false; + dmux.is_working = false; + + stream = {}; + continue; } @@ -634,16 +640,20 @@ u32 dmuxOpen(Demuxer* dmux_ptr) case dmuxResetStream: case dmuxResetStreamAndWaitDone: { - auto dmuxMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); - dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; - dmuxMsg->supplementalInfo = stream.userdata; - dmux.cbFunc(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); + // demuxing stopped + if (dmux.is_running.exchange(false)) + { + // callback + auto dmuxMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); + dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; + dmuxMsg->supplementalInfo = stream.userdata; + dmux.cbFunc(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); + + stream = {}; + + dmux.is_working = false; + } - stream = {}; - dmux.is_running = false; - //if (task.type == dmuxResetStreamAndWaitDone) - //{ - //} break; } @@ -926,8 +936,16 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) return CELL_DMUX_ERROR_ARG; } + if (!dmux->is_running) + { + return CELL_OK; + } + + dmux->is_working = true; + dmux->job.push(DemuxerTask(dmuxResetStreamAndWaitDone), &dmux->is_closed); - while (dmux->is_running && !dmux->is_closed) // TODO: ensure that it is safe + + while (dmux->is_running && dmux->is_working && !dmux->is_closed) // TODO: ensure that it is safe { if (Emu.IsStopped()) { @@ -936,6 +954,7 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.h b/rpcs3/Emu/SysCalls/Modules/cellDmux.h index edca677727..5456db607f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.h +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.h @@ -404,6 +404,7 @@ public: volatile bool is_finished; volatile bool is_closed; std::atomic is_running; + std::atomic is_working; PPUThread* dmuxCb; @@ -411,6 +412,7 @@ public: : is_finished(false) , is_closed(false) , is_running(false) + , is_working(false) , memAddr(addr) , memSize(size) , cbFunc(func) From 1d2351bf853175e18990d8ddfd086f247b934f2f Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 8 Mar 2015 00:20:38 +0300 Subject: [PATCH 4/6] Attempt to fix bug --- rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 24 ++- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 264 ++++++++++++++---------- 2 files changed, 173 insertions(+), 115 deletions(-) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index a75ea478ca..787b91d715 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -2004,7 +2004,29 @@ void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { } void Compiler::HACK(u32 index) { - Call("execute_ppu_func_by_index", &execute_ppu_func_by_index, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt32(index)); + if (index & EIF_SAVE_RTOC) { + auto addr_i64 = (Value *)m_ir_builder->getInt64(0x28); + auto ra_i64 = GetGpr(1); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(2, 64)); + } + Call("execute_ppu_func_by_index", &execute_ppu_func_by_index, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt32(index & ~EIF_FLAGS)); + if (index & EIF_PERFORM_BLR) { + auto lr_i64 = GetLr(); + lr_i64 = m_ir_builder->CreateAnd(lr_i64, ~0x3ULL); + auto lr_i32 = m_ir_builder->CreateTrunc(lr_i64, m_ir_builder->getInt32Ty()); + CreateBranch(nullptr, lr_i32, false, true); + } + // copied from Compiler::SC() + auto ret_i1 = Call("PollStatus", m_poll_status_function, m_state.args[CompileTaskState::Args::State]); + auto cmp_i1 = m_ir_builder->CreateICmpEQ(ret_i1, m_ir_builder->getInt1(true)); + auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then_true"); + auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge_true"); + m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); + m_ir_builder->SetInsertPoint(then_bb); + m_ir_builder->CreateRet(m_ir_builder->getInt32(0xFFFFFFFF)); + m_ir_builder->SetInsertPoint(merge_bb); } void Compiler::SC(u32 lev) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 354f70ade6..23cef8ccf4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -32,19 +32,20 @@ s32 syncMutexInitialize(vm::ptr mutex) // prx: set zero and sync mutex->data.exchange({}); + return CELL_OK; } s32 cellSyncMutexInitialize(vm::ptr mutex) { - cellSync.Log("cellSyncMutexInitialize(mutex_addr=0x%x)", mutex.addr()); + cellSync.Log("cellSyncMutexInitialize(mutex=*0x%x)", mutex); return syncMutexInitialize(mutex); } s32 cellSyncMutexLock(vm::ptr mutex) { - cellSync.Log("cellSyncMutexLock(mutex_addr=0x%x)", mutex.addr()); + cellSync.Log("cellSyncMutexLock(mutex=*0x%x)", mutex); if (!mutex) { @@ -70,12 +71,13 @@ s32 cellSyncMutexLock(vm::ptr mutex) // prx: sync mutex->data.read_sync(); + return CELL_OK; } s32 cellSyncMutexTryLock(vm::ptr mutex) { - cellSync.Log("cellSyncMutexTryLock(mutex_addr=0x%x)", mutex.addr()); + cellSync.Log("cellSyncMutexTryLock(mutex=*0x%x)", mutex); if (!mutex) { @@ -99,7 +101,7 @@ s32 cellSyncMutexTryLock(vm::ptr mutex) s32 cellSyncMutexUnlock(vm::ptr mutex) { - cellSync.Log("cellSyncMutexUnlock(mutex_addr=0x%x)", mutex.addr()); + cellSync.Log("cellSyncMutexUnlock(mutex=*0x%x)", mutex); if (!mutex) { @@ -116,6 +118,7 @@ s32 cellSyncMutexUnlock(vm::ptr mutex) }); g_sync_mutex_wm.notify(mutex.addr()); + return CELL_OK; } @@ -136,12 +139,13 @@ s32 syncBarrierInitialize(vm::ptr barrier, u16 total_count) // prx: zeroize first u16, write total_count in second u16 and sync barrier->data.exchange({ be_t::make(0), be_t::make(total_count) }); + return CELL_OK; } s32 cellSyncBarrierInitialize(vm::ptr barrier, u16 total_count) { - cellSync.Log("cellSyncBarrierInitialize(barrier_addr=0x%x, total_count=%d)", barrier.addr(), total_count); + cellSync.Log("cellSyncBarrierInitialize(barrier=*0x%x, total_count=%d)", barrier, total_count); return syncBarrierInitialize(barrier, total_count); } @@ -149,24 +153,26 @@ s32 cellSyncBarrierInitialize(vm::ptr barrier, u16 total_count) s32 syncBarrierTryNotifyOp(CellSyncBarrier::data_t& barrier) { // prx: extract m_value (repeat if < 0), increase, compare with second s16, set sign bit if equal, insert it back - s16 value = (s16)barrier.m_value; + s16 value = barrier.m_value; + if (value < 0) { return CELL_SYNC_ERROR_BUSY; } - value++; - if (value == (s16)barrier.m_count) + if (++value == barrier.m_count) { value |= 0x8000; } + barrier.m_value = value; + return CELL_OK; }; s32 cellSyncBarrierNotify(vm::ptr barrier) { - cellSync.Log("cellSyncBarrierNotify(barrier_addr=0x%x)", barrier.addr()); + cellSync.Log("cellSyncBarrierNotify(barrier=*0x%x)", barrier); if (!barrier) { @@ -183,12 +189,13 @@ s32 cellSyncBarrierNotify(vm::ptr barrier) }); g_sync_barrier_wait_wm.notify(barrier.addr()); + return CELL_OK; } s32 cellSyncBarrierTryNotify(vm::ptr barrier) { - cellSync.Log("cellSyncBarrierTryNotify(barrier_addr=0x%x)", barrier.addr()); + cellSync.Log("cellSyncBarrierTryNotify(barrier=*0x%x)", barrier); if (!barrier) { @@ -205,30 +212,33 @@ s32 cellSyncBarrierTryNotify(vm::ptr barrier) } g_sync_barrier_wait_wm.notify(barrier.addr()); + return CELL_OK; } s32 syncBarrierTryWaitOp(CellSyncBarrier::data_t& barrier) { // prx: extract m_value (repeat if >= 0), decrease it, set 0 if == 0x8000, insert it back - s16 value = (s16)barrier.m_value; + s16 value = barrier.m_value; + if (value >= 0) { return CELL_SYNC_ERROR_BUSY; } - value--; - if (value == (s16)0x8000) + if (--value == -0x8000) { value = 0; } + barrier.m_value = value; + return CELL_OK; } s32 cellSyncBarrierWait(vm::ptr barrier) { - cellSync.Log("cellSyncBarrierWait(barrier_addr=0x%x)", barrier.addr()); + cellSync.Log("cellSyncBarrierWait(barrier=*0x%x)", barrier); if (!barrier) { @@ -245,12 +255,13 @@ s32 cellSyncBarrierWait(vm::ptr barrier) }); g_sync_barrier_notify_wm.notify(barrier.addr()); + return CELL_OK; } s32 cellSyncBarrierTryWait(vm::ptr barrier) { - cellSync.Log("cellSyncBarrierTryWait(barrier_addr=0x%x)", barrier.addr()); + cellSync.Log("cellSyncBarrierTryWait(barrier=*0x%x)", barrier); if (!barrier) { @@ -267,6 +278,7 @@ s32 cellSyncBarrierTryWait(vm::ptr barrier) } g_sync_barrier_notify_wm.notify(barrier.addr()); + return CELL_OK; } @@ -289,12 +301,13 @@ s32 syncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer rwm->m_size = be_t::make(buffer_size); rwm->m_buffer = buffer; rwm->data.exchange({}); + return CELL_OK; } s32 cellSyncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer_size) { - cellSync.Log("cellSyncRwmInitialize(rwm_addr=0x%x, buffer_addr=0x%x, buffer_size=0x%x)", rwm.addr(), buffer.addr(), buffer_size); + cellSync.Log("cellSyncRwmInitialize(rwm=*0x%x, buffer=*0x%x, buffer_size=0x%x)", rwm, buffer, buffer_size); return syncRwmInitialize(rwm, buffer, buffer_size); } @@ -307,6 +320,7 @@ s32 syncRwmTryReadBeginOp(CellSyncRwm::data_t& rwm) } rwm.m_readers++; + return CELL_OK; } @@ -318,12 +332,13 @@ s32 syncRwmReadEndOp(CellSyncRwm::data_t& rwm) } rwm.m_readers--; + return CELL_OK; } s32 cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) { - cellSync.Log("cellSyncRwmRead(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); + cellSync.Log("cellSyncRwmRead(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); if (!rwm || !buffer) { @@ -341,7 +356,7 @@ s32 cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) }); // copy data to buffer_addr - memcpy(buffer.get_ptr(), rwm->m_buffer.get_ptr(), (u32)rwm->m_size); + memcpy(buffer.get_ptr(), rwm->m_buffer.get_ptr(), rwm->m_size); // prx: decrease m_readers (return 0x8041010C if already zero) if (s32 res = rwm->data.atomic_op(CELL_OK, syncRwmReadEndOp)) @@ -351,12 +366,13 @@ s32 cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) } g_sync_rwm_write_wm.notify(rwm.addr()); + return CELL_OK; } s32 cellSyncRwmTryRead(vm::ptr rwm, vm::ptr buffer) { - cellSync.Log("cellSyncRwmTryRead(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); + cellSync.Log("cellSyncRwmTryRead(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); if (!rwm || !buffer) { @@ -372,7 +388,7 @@ s32 cellSyncRwmTryRead(vm::ptr rwm, vm::ptr buffer) return res; } - memcpy(buffer.get_ptr(), rwm->m_buffer.get_ptr(), (u32)rwm->m_size); + memcpy(buffer.get_ptr(), rwm->m_buffer.get_ptr(), rwm->m_size); if (s32 res = rwm->data.atomic_op(CELL_OK, syncRwmReadEndOp)) { @@ -380,6 +396,7 @@ s32 cellSyncRwmTryRead(vm::ptr rwm, vm::ptr buffer) } g_sync_rwm_write_wm.notify(rwm.addr()); + return CELL_OK; } @@ -391,12 +408,13 @@ s32 syncRwmTryWriteBeginOp(CellSyncRwm::data_t& rwm) } rwm.m_writers = 1; + return CELL_OK; } s32 cellSyncRwmWrite(vm::ptr rwm, vm::ptr buffer) { - cellSync.Log("cellSyncRwmWrite(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); + cellSync.Log("cellSyncRwmWrite(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); if (!rwm || !buffer) { @@ -419,17 +437,19 @@ s32 cellSyncRwmWrite(vm::ptr rwm, vm::ptr buffer) }); // prx: copy data from buffer_addr - memcpy(rwm->m_buffer.get_ptr(), buffer.get_ptr(), (u32)rwm->m_size); + memcpy(rwm->m_buffer.get_ptr(), buffer.get_ptr(), rwm->m_size); // prx: sync and zeroize m_readers and m_writers rwm->data.exchange({}); + g_sync_rwm_read_wm.notify(rwm.addr()); + return CELL_OK; } s32 cellSyncRwmTryWrite(vm::ptr rwm, vm::ptr buffer) { - cellSync.Log("cellSyncRwmTryWrite(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); + cellSync.Log("cellSyncRwmTryWrite(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); if (!rwm || !buffer) { @@ -447,11 +467,13 @@ s32 cellSyncRwmTryWrite(vm::ptr rwm, vm::ptr buffer) } // prx: copy data from buffer_addr - memcpy(rwm->m_buffer.get_ptr(), buffer.get_ptr(), (u32)rwm->m_size); + memcpy(rwm->m_buffer.get_ptr(), buffer.get_ptr(), rwm->m_size); // prx: sync and zeroize m_readers and m_writers rwm->data.exchange({}); + g_sync_rwm_read_wm.notify(rwm.addr()); + return CELL_OK; } @@ -479,20 +501,22 @@ s32 syncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 si queue->m_depth = be_t::make(depth); queue->m_buffer.set(buffer.addr()); queue->data.exchange({}); + return CELL_OK; } s32 cellSyncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth) { - cellSync.Log("cellSyncQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x)", queue.addr(), buffer.addr(), size, depth); + cellSync.Log("cellSyncQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x)", queue, buffer, size, depth); return syncQueueInitialize(queue, buffer, size, depth); } s32 syncQueueTryPushOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) { - const u32 v1 = (u32)queue.m_v1; - const u32 v2 = (u32)queue.m_v2; + const u32 v1 = queue.m_v1; + const u32 v2 = queue.m_v2; + // prx: compare 5th u8 with zero (break if not zero) // prx: compare (second u32 (u24) + first u8) with depth (break if greater or equal) if ((v2 >> 24) || ((v2 & 0xffffff) + (v1 >> 24)) >= depth) @@ -506,12 +530,13 @@ s32 syncQueueTryPushOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) position = (v1 & 0xffffff); queue.m_v1 = (v1 & 0xff000000) | ((position + 1) % depth); queue.m_v2 = (1 << 24) | ((v2 & 0xffffff) + 1); + return CELL_OK; } s32 cellSyncQueuePush(vm::ptr queue, vm::ptr buffer) { - cellSync.Log("cellSyncQueuePush(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueuePush(queue=*0x%x, buffer=*0x%x)", queue, buffer); if (!queue || !buffer) { @@ -522,10 +547,10 @@ s32 cellSyncQueuePush(vm::ptr queue, vm::ptr buffer) return CELL_SYNC_ERROR_ALIGN; } - const u32 size = (u32)queue->m_size; - const u32 depth = (u32)queue->m_depth; + const u32 size = queue->m_size; + const u32 depth = queue->m_depth; const auto data = queue->data.read_relaxed(); - assert(((u32)data.m_v1 & 0xffffff) <= depth && ((u32)data.m_v2 & 0xffffff) <= depth); + assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); u32 position; g_sync_queue_wm.wait_op(queue.addr(), [queue, depth, &position]() @@ -541,13 +566,15 @@ s32 cellSyncQueuePush(vm::ptr queue, vm::ptr buffer) // prx: atomically insert 0 in 5th u8 queue->data &= { be_t::make(~0), be_t::make(0xffffff) }; + g_sync_queue_wm.notify(queue.addr()); + return CELL_OK; } s32 cellSyncQueueTryPush(vm::ptr queue, vm::ptr buffer) { - cellSync.Log("cellSyncQueueTryPush(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueueTryPush(queue=*0x%x, buffer=*0x%x)", queue, buffer); if (!queue || !buffer) { @@ -558,10 +585,10 @@ s32 cellSyncQueueTryPush(vm::ptr queue, vm::ptr buffe return CELL_SYNC_ERROR_ALIGN; } - const u32 size = (u32)queue->m_size; - const u32 depth = (u32)queue->m_depth; + const u32 size = queue->m_size; + const u32 depth = queue->m_depth; const auto data = queue->data.read_relaxed(); - assert(((u32)data.m_v1 & 0xffffff) <= depth && ((u32)data.m_v2 & 0xffffff) <= depth); + assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); u32 position; s32 res = queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 @@ -574,15 +601,19 @@ s32 cellSyncQueueTryPush(vm::ptr queue, vm::ptr buffe } memcpy(&queue->m_buffer[position * size], buffer.get_ptr(), size); + queue->data &= { be_t::make(~0), be_t::make(0xffffff) }; + g_sync_queue_wm.notify(queue.addr()); + return CELL_OK; } s32 syncQueueTryPopOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) { - const u32 v1 = (u32)queue.m_v1; - const u32 v2 = (u32)queue.m_v2; + const u32 v1 = queue.m_v1; + const u32 v2 = queue.m_v2; + // prx: extract first u8, repeat if not zero // prx: extract second u32 (u24), subtract 5th u8, compare with zero, repeat if less or equal if ((v1 >> 24) || ((v2 & 0xffffff) <= (v2 >> 24))) @@ -596,12 +627,13 @@ s32 syncQueueTryPopOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) queue.m_v1 = 0x1000000 | v1; position = ((v1 & 0xffffff) + depth - (v2 & 0xffffff)) % depth; queue.m_v2 = (v2 & 0xff000000) | ((v2 & 0xffffff) - 1); + return CELL_OK; } s32 cellSyncQueuePop(vm::ptr queue, vm::ptr buffer) { - cellSync.Log("cellSyncQueuePop(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueuePop(queue=*0x%x, buffer=*0x%x)", queue, buffer); if (!queue || !buffer) { @@ -612,10 +644,10 @@ s32 cellSyncQueuePop(vm::ptr queue, vm::ptr buffer) return CELL_SYNC_ERROR_ALIGN; } - const u32 size = (u32)queue->m_size; - const u32 depth = (u32)queue->m_depth; + const u32 size = queue->m_size; + const u32 depth = queue->m_depth; const auto data = queue->data.read_relaxed(); - assert(((u32)data.m_v1 & 0xffffff) <= depth && ((u32)data.m_v2 & 0xffffff) <= depth); + assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); u32 position; g_sync_queue_wm.wait_op(queue.addr(), [queue, depth, &position]() @@ -631,13 +663,15 @@ s32 cellSyncQueuePop(vm::ptr queue, vm::ptr buffer) // prx: atomically insert 0 in first u8 queue->data &= { be_t::make(0xffffff), be_t::make(~0) }; + g_sync_queue_wm.notify(queue.addr()); + return CELL_OK; } s32 cellSyncQueueTryPop(vm::ptr queue, vm::ptr buffer) { - cellSync.Log("cellSyncQueueTryPop(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueueTryPop(queue=*0x%x, buffer=*0x%x)", queue, buffer); if (!queue || !buffer) { @@ -648,10 +682,10 @@ s32 cellSyncQueueTryPop(vm::ptr queue, vm::ptr buffer) return CELL_SYNC_ERROR_ALIGN; } - const u32 size = (u32)queue->m_size; - const u32 depth = (u32)queue->m_depth; + const u32 size = queue->m_size; + const u32 depth = queue->m_depth; const auto data = queue->data.read_relaxed(); - assert(((u32)data.m_v1 & 0xffffff) <= depth && ((u32)data.m_v2 & 0xffffff) <= depth); + assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); u32 position; s32 res = queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 @@ -664,15 +698,19 @@ s32 cellSyncQueueTryPop(vm::ptr queue, vm::ptr buffer) } memcpy(buffer.get_ptr(), &queue->m_buffer[position * size], size); + queue->data &= { be_t::make(0xffffff), be_t::make(~0) }; + g_sync_queue_wm.notify(queue.addr()); + return CELL_OK; } s32 syncQueueTryPeekOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) { - const u32 v1 = (u32)queue.m_v1; - const u32 v2 = (u32)queue.m_v2; + const u32 v1 = queue.m_v1; + const u32 v2 = queue.m_v2; + if ((v1 >> 24) || ((v2 & 0xffffff) <= (v2 >> 24))) { return CELL_SYNC_ERROR_BUSY; @@ -680,12 +718,13 @@ s32 syncQueueTryPeekOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) queue.m_v1 = 0x1000000 | v1; position = ((v1 & 0xffffff) + depth - (v2 & 0xffffff)) % depth; + return CELL_OK; } s32 cellSyncQueuePeek(vm::ptr queue, vm::ptr buffer) { - cellSync.Log("cellSyncQueuePeek(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueuePeek(queue=*0x%x, buffer=*0x%x)", queue, buffer); if (!queue || !buffer) { @@ -696,10 +735,10 @@ s32 cellSyncQueuePeek(vm::ptr queue, vm::ptr buffer) return CELL_SYNC_ERROR_ALIGN; } - const u32 size = (u32)queue->m_size; - const u32 depth = (u32)queue->m_depth; + const u32 size = queue->m_size; + const u32 depth = queue->m_depth; const auto data = queue->data.read_relaxed(); - assert(((u32)data.m_v1 & 0xffffff) <= depth && ((u32)data.m_v2 & 0xffffff) <= depth); + assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); u32 position; g_sync_queue_wm.wait_op(queue.addr(), [queue, depth, &position]() @@ -711,14 +750,17 @@ s32 cellSyncQueuePeek(vm::ptr queue, vm::ptr buffer) }); memcpy(buffer.get_ptr(), &queue->m_buffer[position * size], size); + queue->data &= { be_t::make(0xffffff), be_t::make(~0) }; + g_sync_queue_wm.notify(queue.addr()); + return CELL_OK; } s32 cellSyncQueueTryPeek(vm::ptr queue, vm::ptr buffer) { - cellSync.Log("cellSyncQueueTryPeek(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueueTryPeek(queue=*0x%x, buffer=*0x%x)", queue, buffer); if (!queue || !buffer) { @@ -729,10 +771,10 @@ s32 cellSyncQueueTryPeek(vm::ptr queue, vm::ptr buffer) return CELL_SYNC_ERROR_ALIGN; } - const u32 size = (u32)queue->m_size; - const u32 depth = (u32)queue->m_depth; + const u32 size = queue->m_size; + const u32 depth = queue->m_depth; const auto data = queue->data.read_relaxed(); - assert(((u32)data.m_v1 & 0xffffff) <= depth && ((u32)data.m_v2 & 0xffffff) <= depth); + assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); u32 position; s32 res = queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 @@ -745,14 +787,17 @@ s32 cellSyncQueueTryPeek(vm::ptr queue, vm::ptr buffer) } memcpy(buffer.get_ptr(), &queue->m_buffer[position * size], size); + queue->data &= { be_t::make(0xffffff), be_t::make(~0) }; + g_sync_queue_wm.notify(queue.addr()); + return CELL_OK; } s32 cellSyncQueueSize(vm::ptr queue) { - cellSync.Log("cellSyncQueueSize(queue_addr=0x%x)", queue.addr()); + cellSync.Log("cellSyncQueueSize(queue=*0x%x)", queue); if (!queue) { @@ -764,16 +809,16 @@ s32 cellSyncQueueSize(vm::ptr queue) } const auto data = queue->data.read_relaxed(); - const u32 count = (u32)data.m_v2 & 0xffffff; - const u32 depth = (u32)queue->m_depth; - assert(((u32)data.m_v1 & 0xffffff) <= depth && count <= depth); + const u32 count = data.m_v2 & 0xffffff; + const u32 depth = queue->m_depth; + assert((data.m_v1 & 0xffffff) <= depth && count <= depth); return count; } s32 cellSyncQueueClear(vm::ptr queue) { - cellSync.Log("cellSyncQueueClear(queue_addr=0x%x)", queue.addr()); + cellSync.Log("cellSyncQueueClear(queue=*0x%x)", queue); if (!queue) { @@ -784,16 +829,17 @@ s32 cellSyncQueueClear(vm::ptr queue) return CELL_SYNC_ERROR_ALIGN; } - const u32 depth = (u32)queue->m_depth; + const u32 depth = queue->m_depth; const auto data = queue->data.read_relaxed(); - assert(((u32)data.m_v1 & 0xffffff) <= depth && ((u32)data.m_v2 & 0xffffff) <= depth); + assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); // TODO: optimize if possible g_sync_queue_wm.wait_op(queue.addr(), [queue, depth]() { return CELL_OK == queue->data.atomic_op(CELL_OK, [depth](CellSyncQueue::data_t& queue) -> s32 { - const u32 v1 = (u32)queue.m_v1; + const u32 v1 = queue.m_v1; + // prx: extract first u8, repeat if not zero, insert 1 if (v1 >> 24) { @@ -801,6 +847,7 @@ s32 cellSyncQueueClear(vm::ptr queue) } queue.m_v1 = v1 | 0x1000000; + return CELL_OK; }); }); @@ -809,7 +856,8 @@ s32 cellSyncQueueClear(vm::ptr queue) { return CELL_OK == queue->data.atomic_op(CELL_OK, [depth](CellSyncQueue::data_t& queue) -> s32 { - const u32 v2 = (u32)queue.m_v2; + const u32 v2 = queue.m_v2; + // prx: extract 5th u8, repeat if not zero, insert 1 if (v2 >> 24) { @@ -817,12 +865,15 @@ s32 cellSyncQueueClear(vm::ptr queue) } queue.m_v2 = v2 | 0x1000000; + return CELL_OK; }); }); queue->data.exchange({}); + g_sync_queue_wm.notify(queue.addr()); + return CELL_OK; } @@ -943,13 +994,13 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 if (old_value == 2) { - if ((u32)queue->m_size != size || (u32)queue->m_depth != depth || queue->m_buffer.addr() != buffer.addr()) + if (queue->m_size != size || queue->m_depth != depth || queue->m_buffer.addr().value() != buffer.addr()) { return CELL_SYNC_ERROR_INVAL; } if (sdk_ver > 0x17ffff) { - if (queue->m_eaSignal.addr() != eaSignal.addr() || (u32)queue->m_direction != direction) + if (queue->m_eaSignal.addr() != eaSignal.addr() || queue->m_direction != direction) { return CELL_SYNC_ERROR_INVAL; } @@ -971,8 +1022,7 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 s32 cellSyncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) { - cellSync.Warning("cellSyncLFQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal_addr=0x%x)", - queue.addr(), buffer.addr(), size, depth, direction, eaSignal.addr()); + cellSync.Warning("cellSyncLFQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal=*0x%x)", queue, buffer, size, depth, direction, eaSignal); return syncLFQueueInitialize(queue, buffer, size, depth, direction, eaSignal); } @@ -985,7 +1035,7 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 } u32 var1 = 0; - s32 depth = (u32)queue->m_depth; + s32 depth = queue->m_depth; while (true) { while (true) @@ -1007,7 +1057,7 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 return CELL_SYNC_ERROR_STAT; } - s32 var2 = (s32)(s16)push.m_h8; + s32 var2 = (s16)push.m_h8; s32 res; if (useEventQueue && ((s32)push.m_h5 != var2 || push.m_h7.data() != 0)) { @@ -1036,14 +1086,7 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 } else if (!isBlocking) { - res = CELL_SYNC_ERROR_AGAIN; - if (!push.m_h7.data() || res) - { - // TODO: This condition is always true - wrong implementation? - return res; - } - - break; + return CELL_SYNC_ERROR_AGAIN; } else if (!useEventQueue) { @@ -1080,12 +1123,13 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 s32 _cellSyncLFQueueGetPushPointer(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { - cellSync.Warning("_cellSyncLFQueueGetPushPointer(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", - queue.addr(), pointer.addr(), isBlocking, useEventQueue); + cellSync.Warning("_cellSyncLFQueueGetPushPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue); s32 pointer_value; s32 result = syncLFQueueGetPushPointer(queue, pointer_value, isBlocking, useEventQueue); + *pointer = pointer_value; + return result; } @@ -1097,12 +1141,13 @@ s32 syncLFQueueGetPushPointer2(vm::ptr queue, s32& pointer, u32 s32 _cellSyncLFQueueGetPushPointer2(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { // arguments copied from _cellSyncLFQueueGetPushPointer - cellSync.Todo("_cellSyncLFQueueGetPushPointer2(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", - queue.addr(), pointer.addr(), isBlocking, useEventQueue); + cellSync.Todo("_cellSyncLFQueueGetPushPointer2(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue); s32 pointer_value; s32 result = syncLFQueueGetPushPointer2(queue, pointer_value, isBlocking, useEventQueue); + *pointer = pointer_value; + return result; } @@ -1242,8 +1287,7 @@ s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, s32 _cellSyncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) { - cellSync.Warning("_cellSyncLFQueueCompletePushPointer(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x)", - queue.addr(), pointer, fpSendSignal.addr()); + cellSync.Warning("_cellSyncLFQueueCompletePushPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal); return syncLFQueueCompletePushPointer(queue, pointer, fpSendSignal); } @@ -1256,8 +1300,7 @@ s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, s32 _cellSyncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) { // arguments copied from _cellSyncLFQueueCompletePushPointer - cellSync.Todo("_cellSyncLFQueueCompletePushPointer2(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x)", - queue.addr(), pointer, fpSendSignal.addr()); + cellSync.Todo("_cellSyncLFQueueCompletePushPointer2(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal); return syncLFQueueCompletePushPointer2(queue, pointer, fpSendSignal); } @@ -1265,7 +1308,7 @@ s32 _cellSyncLFQueueCompletePushPointer2(vm::ptr queue, s32 poi s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm::ptr buffer, u32 isBlocking) { // cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 - cellSync.Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking); + cellSync.Warning("_cellSyncLFQueuePushBody(queue=*0x%x, buffer=*0x%x, isBlocking=%d)", queue, buffer, isBlocking); if (!queue || !buffer) { @@ -1304,7 +1347,7 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: if (Emu.IsStopped()) { - cellSync.Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x) aborted", queue.addr()); + cellSync.Warning("_cellSyncLFQueuePushBody(queue=*0x%x) aborted", queue); return CELL_OK; } } @@ -1387,14 +1430,7 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i } else if (!isBlocking) { - res = CELL_SYNC_ERROR_AGAIN; - if (!pop.m_h3.data() || res) - { - // TODO: This condition is always true - wrong implementation? - return res; - } - - break; + return CELL_SYNC_ERROR_AGAIN; } else if (!useEventQueue) { @@ -1431,12 +1467,13 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i s32 _cellSyncLFQueueGetPopPointer(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 arg4, u32 useEventQueue) { - cellSync.Warning("_cellSyncLFQueueGetPopPointer(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", - queue.addr(), pointer.addr(), isBlocking, arg4, useEventQueue); + cellSync.Warning("_cellSyncLFQueueGetPopPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", queue, pointer, isBlocking, arg4, useEventQueue); s32 pointer_value; s32 result = syncLFQueueGetPopPointer(queue, pointer_value, isBlocking, arg4, useEventQueue); + *pointer = pointer_value; + return result; } @@ -1448,12 +1485,13 @@ s32 syncLFQueueGetPopPointer2(vm::ptr queue, s32& pointer, u32 s32 _cellSyncLFQueueGetPopPointer2(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { // arguments copied from _cellSyncLFQueueGetPopPointer - cellSync.Todo("_cellSyncLFQueueGetPopPointer2(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", - queue.addr(), pointer.addr(), isBlocking, useEventQueue); + cellSync.Todo("_cellSyncLFQueueGetPopPointer2(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue); s32 pointer_value; s32 result = syncLFQueueGetPopPointer2(queue, pointer_value, isBlocking, useEventQueue); + *pointer = pointer_value; + return result; } @@ -1593,8 +1631,7 @@ s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, c s32 _cellSyncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) { // arguments copied from _cellSyncLFQueueCompletePushPointer + unknown argument (noQueueFull taken from LFQueue2CompletePopPointer) - cellSync.Warning("_cellSyncLFQueueCompletePopPointer(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x, noQueueFull=%d)", - queue.addr(), pointer, fpSendSignal.addr(), noQueueFull); + cellSync.Warning("_cellSyncLFQueueCompletePopPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull); return syncLFQueueCompletePopPointer(queue, pointer, fpSendSignal, noQueueFull); } @@ -1607,8 +1644,7 @@ s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, s32 _cellSyncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) { // arguments copied from _cellSyncLFQueueCompletePopPointer - cellSync.Todo("_cellSyncLFQueueCompletePopPointer2(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x, noQueueFull=%d)", - queue.addr(), pointer, fpSendSignal.addr(), noQueueFull); + cellSync.Todo("_cellSyncLFQueueCompletePopPointer2(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull); return syncLFQueueCompletePopPointer2(queue, pointer, fpSendSignal, noQueueFull); } @@ -1616,7 +1652,7 @@ s32 _cellSyncLFQueueCompletePopPointer2(vm::ptr queue, s32 poin s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm::ptr buffer, u32 isBlocking) { // cellSyncLFQueuePop has 1 in isBlocking param, cellSyncLFQueueTryPop has 0 - cellSync.Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking); + cellSync.Warning("_cellSyncLFQueuePopBody(queue=*0x%x, buffer=*0x%x, isBlocking=%d)", queue, buffer, isBlocking); if (!queue || !buffer) { @@ -1654,7 +1690,7 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: if (Emu.IsStopped()) { - cellSync.Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x) aborted", queue.addr()); + cellSync.Warning("_cellSyncLFQueuePopBody(queue=*0x%x) aborted", queue); return CELL_OK; } } @@ -1680,7 +1716,7 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: s32 cellSyncLFQueueClear(vm::ptr queue) { - cellSync.Warning("cellSyncLFQueueClear(queue_addr=0x%x)", queue.addr()); + cellSync.Warning("cellSyncLFQueueClear(queue=*0x%x)", queue); if (!queue) { @@ -1730,7 +1766,7 @@ s32 cellSyncLFQueueClear(vm::ptr queue) s32 cellSyncLFQueueSize(vm::ptr queue, vm::ptr size) { - cellSync.Warning("cellSyncLFQueueSize(queue_addr=0x%x, size_addr=0x%x)", queue.addr(), size.addr()); + cellSync.Warning("cellSyncLFQueueSize(queue=*0x%x, size=*0x%x)", queue, size); if (!queue || !size) { @@ -1765,7 +1801,7 @@ s32 cellSyncLFQueueSize(vm::ptr queue, vm::ptr size) s32 cellSyncLFQueueDepth(vm::ptr queue, vm::ptr depth) { - cellSync.Log("cellSyncLFQueueDepth(queue_addr=0x%x, depth_addr=0x%x)", queue.addr(), depth.addr()); + cellSync.Log("cellSyncLFQueueDepth(queue=*0x%x, depth=*0x%x)", queue, depth); if (!queue || !depth) { @@ -1782,7 +1818,7 @@ s32 cellSyncLFQueueDepth(vm::ptr queue, vm::ptr depth) s32 _cellSyncLFQueueGetSignalAddress(vm::ptr queue, vm::ptr ppSignal) { - cellSync.Log("_cellSyncLFQueueGetSignalAddress(queue_addr=0x%x, ppSignal_addr=0x%x)", queue.addr(), ppSignal.addr()); + cellSync.Log("_cellSyncLFQueueGetSignalAddress(queue=*0x%x, ppSignal=*0x%x)", queue, ppSignal); if (!queue || !ppSignal) { @@ -1799,7 +1835,7 @@ s32 _cellSyncLFQueueGetSignalAddress(vm::ptr queue, vm::p s32 cellSyncLFQueueGetDirection(vm::ptr queue, vm::ptr direction) { - cellSync.Log("cellSyncLFQueueGetDirection(queue_addr=0x%x, direction_addr=0x%x)", queue.addr(), direction.addr()); + cellSync.Log("cellSyncLFQueueGetDirection(queue=*0x%x, direction=*0x%x)", queue, direction); if (!queue || !direction) { @@ -1816,7 +1852,7 @@ s32 cellSyncLFQueueGetDirection(vm::ptr queue, vm::ptr queue, vm::ptr entry_size) { - cellSync.Log("cellSyncLFQueueGetEntrySize(queue_addr=0x%x, entry_size_addr=0x%x)", queue.addr(), entry_size.addr()); + cellSync.Log("cellSyncLFQueueGetEntrySize(queue=*0x%x, entry_size=*0x%x)", queue, entry_size); if (!queue || !entry_size) { @@ -1838,7 +1874,7 @@ s32 syncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr spus, u32 num, vm::ptr queue) { - cellSync.Todo("_cellSyncLFQueueAttachLv2EventQueue(spus_addr=0x%x, num=%d, queue_addr=0x%x)", spus.addr(), num, queue.addr()); + cellSync.Todo("_cellSyncLFQueueAttachLv2EventQueue(spus=*0x%x, num=%d, queue=*0x%x)", spus, num, queue); return syncLFQueueAttachLv2EventQueue(spus, num, queue); } @@ -1850,7 +1886,7 @@ s32 syncLFQueueDetachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr spus, u32 num, vm::ptr queue) { - cellSync.Todo("_cellSyncLFQueueDetachLv2EventQueue(spus_addr=0x%x, num=%d, queue_addr=0x%x)", spus.addr(), num, queue.addr()); + cellSync.Todo("_cellSyncLFQueueDetachLv2EventQueue(spus=*0x%x, num=%d, queue=*0x%x)", spus, num, queue); return syncLFQueueDetachLv2EventQueue(spus, num, queue); } From dba249554d6d570879a2f407df3f5df1a9b8551e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 8 Mar 2015 05:32:41 +0300 Subject: [PATCH 5/6] Lv2 Rwlock rewritten --- rpcs3/Emu/SysCalls/lv2/sys_event.cpp | 4 +- rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp | 6 +- rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp | 3 +- rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp | 211 +++++++++------------- rpcs3/Emu/SysCalls/lv2/sys_rwlock.h | 28 +-- rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp | 3 +- 6 files changed, 110 insertions(+), 145 deletions(-) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index 91ac0793a8..4dc1e73951 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -35,10 +35,8 @@ s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr switch (protocol) { - case SYS_SYNC_PRIORITY: break; - case SYS_SYNC_RETRY: sys_event.Error("sys_event_queue_create(): invalid protocol (SYS_SYNC_RETRY)"); return CELL_EINVAL; - case SYS_SYNC_PRIORITY_INHERIT: sys_event.Error("sys_event_queue_create(): invalid protocol (SYS_SYNC_PRIORITY_INHERIT)"); return CELL_EINVAL; case SYS_SYNC_FIFO: break; + case SYS_SYNC_PRIORITY: break; default: sys_event.Error("sys_event_queue_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp index fdb2dff704..194ccdfa1e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp @@ -27,10 +27,10 @@ s32 sys_event_flag_create(vm::ptr id, vm::ptr attr, u6 switch (protocol) { - case SYS_SYNC_PRIORITY: break; - case SYS_SYNC_RETRY: sys_event_flag.Todo("sys_event_flag_create(): SYS_SYNC_RETRY"); break; - case SYS_SYNC_PRIORITY_INHERIT: sys_event_flag.Todo("sys_event_flag_create(): SYS_SYNC_PRIORITY_INHERIT"); break; case SYS_SYNC_FIFO: break; + case SYS_SYNC_RETRY: break; + case SYS_SYNC_PRIORITY: break; + case SYS_SYNC_PRIORITY_INHERIT: break; default: sys_event_flag.Error("sys_event_flag_create(): unknown protocol (0x%x)", attr->protocol); return CELL_EINVAL; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index 3541c43783..be0e835658 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -29,8 +29,7 @@ s32 sys_mutex_create(vm::ptr mutex_id, vm::ptr attr) { case SYS_SYNC_FIFO: break; case SYS_SYNC_PRIORITY: break; - case SYS_SYNC_PRIORITY_INHERIT: sys_mutex.Todo("sys_mutex_create(): SYS_SYNC_PRIORITY_INHERIT"); break; - case SYS_SYNC_RETRY: sys_mutex.Error("sys_mutex_create(): invalid protocol (SYS_SYNC_RETRY)"); return CELL_EINVAL; + case SYS_SYNC_PRIORITY_INHERIT: break; default: sys_mutex.Error("sys_mutex_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp index d855e9164a..42fc1ff297 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp @@ -13,35 +13,33 @@ SysCallBase sys_rwlock("sys_rwlock"); s32 sys_rwlock_create(vm::ptr rw_lock_id, vm::ptr attr) { - sys_rwlock.Warning("sys_rwlock_create(rw_lock_id_addr=0x%x, attr_addr=0x%x)", rw_lock_id.addr(), attr.addr()); + sys_rwlock.Warning("sys_rwlock_create(rw_lock_id=*0x%x, attr=*0x%x)", rw_lock_id, attr); - if (!attr) + if (!rw_lock_id || !attr) { - sys_rwlock.Error("sys_rwlock_create(): null attr address"); return CELL_EFAULT; } - switch (attr->protocol.data()) + const u32 protocol = attr->protocol; + + switch (protocol) { - case se32(SYS_SYNC_PRIORITY): break; - case se32(SYS_SYNC_RETRY): sys_rwlock.Error("Invalid protocol (SYS_SYNC_RETRY)"); return CELL_EINVAL; - case se32(SYS_SYNC_PRIORITY_INHERIT): sys_rwlock.Todo("SYS_SYNC_PRIORITY_INHERIT"); break; - case se32(SYS_SYNC_FIFO): break; - default: sys_rwlock.Error("Unknown protocol (0x%x)", attr->protocol); return CELL_EINVAL; + case SYS_SYNC_FIFO: break; + case SYS_SYNC_PRIORITY: break; + case SYS_SYNC_PRIORITY_INHERIT: break; + default: sys_rwlock.Error("sys_rwlock_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL; } - if (attr->pshared.data() != se32(0x200)) + if (attr->pshared.data() != se32(0x200) || attr->ipc_key.data() || attr->flags.data()) { - sys_rwlock.Error("Unknown pshared attribute (0x%x)", attr->pshared); + sys_rwlock.Error("sys_rwlock_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags); return CELL_EINVAL; } - std::shared_ptr rw(new RWLock(attr->protocol, attr->name_u64)); - const u32 id = Emu.GetIdManager().GetNewID(rw, TYPE_RWLOCK); - *rw_lock_id = id; - rw->wqueue.set_full_name(fmt::Format("Rwlock(%d)", id)); + std::shared_ptr rwlock(new rwlock_t(attr->protocol, attr->name_u64)); + + *rw_lock_id = Emu.GetIdManager().GetNewID(rwlock, TYPE_RWLOCK); - sys_rwlock.Warning("*** rwlock created [%s] (protocol=0x%x): id = %d", std::string(attr->name, 8).c_str(), rw->protocol, id); return CELL_OK; } @@ -49,52 +47,40 @@ s32 sys_rwlock_destroy(u32 rw_lock_id) { sys_rwlock.Warning("sys_rwlock_destroy(rw_lock_id=%d)", rw_lock_id); - std::shared_ptr rw; - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw)) + LV2_LOCK; + + std::shared_ptr rwlock; + if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) { return CELL_ESRCH; } - if (!rw->sync.compare_and_swap_test({ 0, 0 }, { ~0u, ~0u })) // check if locked and make unusable + if (rwlock.use_count() > 2 || rwlock->readers || rwlock->writer || rwlock->waiters) { return CELL_EBUSY; } Emu.GetIdManager().RemoveID(rw_lock_id); + return CELL_OK; } s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout) { - sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=%d, timeout=%lld)", rw_lock_id, timeout); + sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=%d, timeout=0x%llx)", rw_lock_id, timeout); const u64 start_time = get_system_time(); - std::shared_ptr rw; - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw)) + LV2_LOCK; + + std::shared_ptr rwlock; + if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) { return CELL_ESRCH; } - while (true) + while (rwlock->writer || rwlock->waiters) { - bool succeeded; - rw->sync.atomic_op_sync([&succeeded](RWLock::sync_var_t& sync) - { - assert(~sync.readers); - if ((succeeded = !sync.writer)) - { - sync.readers++; - } - }); - - if (succeeded) - { - break; - } - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - if (timeout && get_system_time() - start_time > timeout) { return CELL_ETIMEDOUT; @@ -105,8 +91,12 @@ s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout) sys_rwlock.Warning("sys_rwlock_rlock(id=%d) aborted", rw_lock_id); return CELL_OK; } + + rwlock->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } + rwlock->readers++; + return CELL_OK; } @@ -114,100 +104,76 @@ s32 sys_rwlock_tryrlock(u32 rw_lock_id) { sys_rwlock.Log("sys_rwlock_tryrlock(rw_lock_id=%d)", rw_lock_id); - std::shared_ptr rw; - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw)) + LV2_LOCK; + + std::shared_ptr rwlock; + if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) { return CELL_ESRCH; } - bool succeeded; - rw->sync.atomic_op_sync([&succeeded](RWLock::sync_var_t& sync) + if (rwlock->writer || rwlock->waiters) { - assert(~sync.readers); - if ((succeeded = !sync.writer)) - { - sync.readers++; - } - }); - - if (succeeded) - { - return CELL_OK; + return CELL_EBUSY; } - return CELL_EBUSY; + rwlock->readers++; + + return CELL_OK; } s32 sys_rwlock_runlock(u32 rw_lock_id) { sys_rwlock.Log("sys_rwlock_runlock(rw_lock_id=%d)", rw_lock_id); - std::shared_ptr rw; - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw)) + LV2_LOCK; + + std::shared_ptr rwlock; + if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) { return CELL_ESRCH; } - bool succeeded; - rw->sync.atomic_op_sync([&succeeded](RWLock::sync_var_t& sync) + if (!rwlock->readers) { - if ((succeeded = sync.readers != 0)) - { - assert(!sync.writer); - sync.readers--; - } - }); - - if (succeeded) - { - return CELL_OK; + return CELL_EPERM; } - return CELL_EPERM; + if (!--rwlock->readers) + { + rwlock->cv.notify_one(); + } + + return CELL_OK; } s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout) { - sys_rwlock.Log("sys_rwlock_wlock(rw_lock_id=%d, timeout=%lld)", rw_lock_id, timeout); + sys_rwlock.Log("sys_rwlock_wlock(rw_lock_id=%d, timeout=0x%llx)", rw_lock_id, timeout); const u64 start_time = get_system_time(); - std::shared_ptr rw; - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw)) + LV2_LOCK; + + std::shared_ptr rwlock; + if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) { return CELL_ESRCH; } - const u32 tid = CPU.GetId(); - - if (rw->sync.compare_and_swap_test({ 0, 0 }, { 0, tid })) - { - return CELL_OK; - } - - if (rw->sync.read_relaxed().writer == tid) + if (rwlock->writer == CPU.GetId()) { return CELL_EDEADLK; } - rw->wqueue.push(tid, rw->protocol); + // protocol is ignored in current implementation + rwlock->waiters++; assert(rwlock->waiters > 0); - while (true) + while (rwlock->readers || rwlock->writer) { - auto old_sync = rw->sync.compare_and_swap({ 0, 0 }, { 0, tid }); - if (!old_sync.readers && (!old_sync.writer || old_sync.writer == tid)) - { - break; - } - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - if (timeout && get_system_time() - start_time > timeout) { - if (!rw->wqueue.invalidate(tid, rw->protocol)) - { - assert(!"sys_rwlock_wlock() failed (timeout)"); - } + rwlock->waiters--; assert(rwlock->waiters >= 0); return CELL_ETIMEDOUT; } @@ -216,12 +182,13 @@ s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout) sys_rwlock.Warning("sys_rwlock_wlock(id=%d) aborted", rw_lock_id); return CELL_OK; } + + rwlock->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } - if (!rw->wqueue.invalidate(tid, rw->protocol) && !rw->wqueue.pop(tid, rw->protocol)) - { - assert(!"sys_rwlock_wlock() failed (locking)"); - } + rwlock->writer = CPU.GetId(); + rwlock->waiters--; assert(rwlock->waiters >= 0); + return CELL_OK; } @@ -229,48 +196,48 @@ s32 sys_rwlock_trywlock(PPUThread& CPU, u32 rw_lock_id) { sys_rwlock.Log("sys_rwlock_trywlock(rw_lock_id=%d)", rw_lock_id); - std::shared_ptr rw; - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw)) + LV2_LOCK; + + std::shared_ptr rwlock; + if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) { return CELL_ESRCH; } - const u32 tid = CPU.GetId(); - - if (rw->sync.compare_and_swap_test({ 0, 0 }, { 0, tid })) - { - return CELL_OK; - } - - if (rw->sync.read_relaxed().writer == tid) + if (rwlock->writer == CPU.GetId()) { return CELL_EDEADLK; } - return CELL_EBUSY; + if (rwlock->readers || rwlock->writer || rwlock->waiters) + { + return CELL_EBUSY; + } + + rwlock->writer = CPU.GetId(); + + return CELL_OK; } s32 sys_rwlock_wunlock(PPUThread& CPU, u32 rw_lock_id) { sys_rwlock.Log("sys_rwlock_wunlock(rw_lock_id=%d)", rw_lock_id); - std::shared_ptr rw; - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rw)) + LV2_LOCK; + + std::shared_ptr rwlock; + if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) { return CELL_ESRCH; } - const u32 tid = CPU.GetId(); - const u32 target = rw->wqueue.signal(rw->protocol); - - if (rw->sync.compare_and_swap_test({ 0, tid }, { 0, target })) + if (rwlock->writer != CPU.GetId()) { - if (!target) - { - // TODO: signal readers - } - return CELL_OK; + return CELL_EPERM; } - return CELL_EPERM; + rwlock->writer = 0; + rwlock->cv.notify_all(); + + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h index 27ca2a72b6..495b94bac9 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h @@ -7,6 +7,7 @@ struct sys_rwlock_attribute_t be_t ipc_key; be_t flags; be_t pad; + union { char name[8]; @@ -14,24 +15,25 @@ struct sys_rwlock_attribute_t }; }; -struct RWLock +struct rwlock_t { - struct sync_var_t - { - u32 readers; // reader count - u32 writer; // writer thread id - }; - - sleep_queue_t wqueue; - atomic_le_t sync; - const u32 protocol; + const u64 name; - RWLock(u32 protocol, u64 name) + std::atomic readers; // reader count + std::atomic writer; // writer id + + // TODO: use sleep queue, possibly remove condition variable + std::condition_variable cv; + std::atomic waiters; + + rwlock_t(u32 protocol, u64 name) : protocol(protocol) - , wqueue(name) + , name(name) + , readers(0) + , writer(0) + , waiters(0) { - sync.write_relaxed({ 0, 0 }); } }; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index e4415dfa6c..bff274c574 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -50,8 +50,7 @@ s32 sys_semaphore_create(vm::ptr sem, vm::ptr attr { case se32(SYS_SYNC_FIFO): break; case se32(SYS_SYNC_PRIORITY): break; - case se32(SYS_SYNC_PRIORITY_INHERIT): sys_semaphore.Todo("SYS_SYNC_PRIORITY_INHERIT"); break; - case se32(SYS_SYNC_RETRY): sys_semaphore.Error("Invalid protocol (SYS_SYNC_RETRY)"); return CELL_EINVAL; + case se32(SYS_SYNC_PRIORITY_INHERIT): break; default: sys_semaphore.Error("Unknown protocol attribute (0x%x)", attr->protocol); return CELL_EINVAL; } From 0f233beff91330d1895d454a203307632ede5de4 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 8 Mar 2015 06:37:07 +0300 Subject: [PATCH 6/6] Lv2 Semaphore rewritten --- rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp | 4 +- rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp | 201 +++++++------------ rpcs3/Emu/SysCalls/lv2/sys_semaphore.h | 47 +++-- 3 files changed, 100 insertions(+), 152 deletions(-) diff --git a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp b/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp index 32994abd06..a71fa05f55 100644 --- a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp +++ b/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp @@ -14,13 +14,13 @@ SemaphoreAttributes SyncPrimManager::GetSemaphoreData(u32 id) { - std::shared_ptr sem; + std::shared_ptr sem; if (!Emu.GetIdManager().GetIDData(id, sem)) { return{}; } - return{ std::string((const char*)&sem->name, 8), sem->value.read_sync(), sem->max }; + return{ std::string((const char*)&sem->name, 8), sem->value, sem->max }; } LwMutexAttributes SyncPrimManager::GetLwMutexData(u32 id) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index bff274c574..5f2a8d3f3d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -12,181 +12,141 @@ SysCallBase sys_semaphore("sys_semaphore"); -u32 semaphore_create(s32 initial_count, s32 max_count, u32 protocol, u64 name_u64) +u32 semaphore_create(s32 initial_val, s32 max_val, u32 protocol, u64 name_u64) { - std::shared_ptr sem(new Semaphore(initial_count, max_count, protocol, name_u64)); + std::shared_ptr sem(new semaphore_t(protocol, max_val, name_u64, initial_val)); - const u32 id = Emu.GetIdManager().GetNewID(sem, TYPE_SEMAPHORE); - sem->queue.set_full_name(fmt::Format("Semaphore(%d)", id)); - - sys_semaphore.Notice("*** semaphore created [%s] (protocol=0x%x): id = %d", std::string((const char*)&name_u64, 8).c_str(), protocol, id); - return id; + return Emu.GetIdManager().GetNewID(sem, TYPE_SEMAPHORE); } -s32 sys_semaphore_create(vm::ptr sem, vm::ptr attr, s32 initial_count, s32 max_count) +s32 sys_semaphore_create(vm::ptr sem, vm::ptr attr, s32 initial_val, s32 max_val) { - sys_semaphore.Warning("sys_semaphore_create(sem_addr=0x%x, attr_addr=0x%x, initial_count=%d, max_count=%d)", - sem.addr(), attr.addr(), initial_count, max_count); + sys_semaphore.Warning("sys_semaphore_create(sem=*0x%x, attr=*0x%x, initial_val=%d, max_val=%d)", sem, attr, initial_val, max_val); - if (!sem) + if (!sem || !attr) { - sys_semaphore.Error("sys_semaphore_create(): invalid memory access (sem_addr=0x%x)", sem.addr()); return CELL_EFAULT; } - if (!attr) + if (max_val <= 0 || initial_val > max_val || initial_val < 0) { - sys_semaphore.Error("sys_semaphore_create(): An invalid argument value is specified (attr_addr=0x%x)", attr.addr()); - return CELL_EFAULT; - } - - if (max_count <= 0 || initial_count > max_count || initial_count < 0) - { - sys_semaphore.Error("sys_semaphore_create(): invalid parameters (initial_count=%d, max_count=%d)", initial_count, max_count); + sys_semaphore.Error("sys_semaphore_create(): invalid parameters (initial_val=%d, max_val=%d)", initial_val, max_val); return CELL_EINVAL; } - switch (attr->protocol.data()) + const u32 protocol = attr->protocol; + + switch (protocol) { - case se32(SYS_SYNC_FIFO): break; - case se32(SYS_SYNC_PRIORITY): break; - case se32(SYS_SYNC_PRIORITY_INHERIT): break; - default: sys_semaphore.Error("Unknown protocol attribute (0x%x)", attr->protocol); return CELL_EINVAL; + case SYS_SYNC_FIFO: break; + case SYS_SYNC_PRIORITY: break; + case SYS_SYNC_PRIORITY_INHERIT: break; + default: sys_semaphore.Error("sys_semaphore_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL; } - if (attr->pshared.data() != se32(0x200)) + if (attr->pshared.data() != se32(0x200) || attr->ipc_key.data() || attr->flags.data()) { - sys_semaphore.Error("Unknown pshared attribute (0x%x)", attr->pshared); + sys_semaphore.Error("sys_semaphore_create(): unknown attributes (pshared=0x%x, ipc_key=0x%x, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags); return CELL_EINVAL; } - *sem = semaphore_create(initial_count, max_count, attr->protocol, attr->name_u64); + *sem = semaphore_create(initial_val, max_val, protocol, attr->name_u64); + return CELL_OK; } -s32 sys_semaphore_destroy(u32 sem_id) +s32 sys_semaphore_destroy(u32 sem) { - sys_semaphore.Warning("sys_semaphore_destroy(sem_id=%d)", sem_id); + sys_semaphore.Warning("sys_semaphore_destroy(sem=%d)", sem); - std::shared_ptr sem; - if (!Emu.GetIdManager().GetIDData(sem_id, sem)) + LV2_LOCK; + + std::shared_ptr semaphore; + if (!Emu.GetIdManager().GetIDData(sem, semaphore)) { return CELL_ESRCH; } - if (sem->queue.count()) // TODO: safely make object unusable + if (semaphore->waiters) { return CELL_EBUSY; } - Emu.GetIdManager().RemoveID(sem_id); + Emu.GetIdManager().RemoveID(sem); + return CELL_OK; } -s32 sys_semaphore_wait(u32 sem_id, u64 timeout) +s32 sys_semaphore_wait(u32 sem, u64 timeout) { - sys_semaphore.Log("sys_semaphore_wait(sem_id=%d, timeout=%lld)", sem_id, timeout); + sys_semaphore.Log("sys_semaphore_wait(sem=%d, timeout=0x%llx)", sem, timeout); const u64 start_time = get_system_time(); - std::shared_ptr sem; - if (!Emu.GetIdManager().GetIDData(sem_id, sem)) + LV2_LOCK; + + std::shared_ptr semaphore; + if (!Emu.GetIdManager().GetIDData(sem, semaphore)) { return CELL_ESRCH; } - const u32 tid = GetCurrentPPUThread().GetId(); - s32 old_value; + // protocol is ignored in current implementation + semaphore->waiters++; assert(semaphore->waiters > 0); + while (semaphore->value <= 0) { - sem->value.atomic_op_sync([&old_value](s32& value) - { - old_value = value; - if (value > 0) - { - value--; - } - }); - - if (old_value > 0) - { - return CELL_OK; - } - - sem->queue.push(tid, sem->protocol); - } - - - while (true) - { - if (sem->queue.pop(tid, sem->protocol)) - { - break; - } - - assert(!sem->value.read_sync()); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - if (timeout && get_system_time() - start_time > timeout) { - if (!sem->queue.invalidate(tid, sem->protocol)) - { - if (sem->queue.pop(tid, sem->protocol)) - { - return CELL_OK; - } - assert(!"sys_semaphore_wait() failed (timeout)"); - } + semaphore->waiters--; assert(semaphore->waiters >= 0); return CELL_ETIMEDOUT; } if (Emu.IsStopped()) { - sys_semaphore.Warning("sys_semaphore_wait(%d) aborted", sem_id); + sys_semaphore.Warning("sys_semaphore_wait(%d) aborted", sem); return CELL_OK; } + + semaphore->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } + semaphore->value--; + semaphore->waiters--; assert(semaphore->waiters >= 0); + return CELL_OK; } -s32 sys_semaphore_trywait(u32 sem_id) +s32 sys_semaphore_trywait(u32 sem) { - sys_semaphore.Log("sys_semaphore_trywait(sem_id=%d)", sem_id); + sys_semaphore.Log("sys_semaphore_trywait(sem=%d)", sem); - std::shared_ptr sem; - if (!Emu.GetIdManager().GetIDData(sem_id, sem)) + LV2_LOCK; + + std::shared_ptr semaphore; + if (!Emu.GetIdManager().GetIDData(sem, semaphore)) { return CELL_ESRCH; } - s32 old_value; - - sem->value.atomic_op_sync([&old_value](s32& value) - { - old_value = value; - if (value > 0) - { - value--; - } - }); - - if (old_value > 0) - { - return CELL_OK; - } - else + if (semaphore->value <= 0 || semaphore->waiters) { return CELL_EBUSY; } + + semaphore->value--; + + return CELL_OK; } -s32 sys_semaphore_post(u32 sem_id, s32 count) +s32 sys_semaphore_post(u32 sem, s32 count) { - sys_semaphore.Log("sys_semaphore_post(sem_id=%d, count=%d)", sem_id, count); + sys_semaphore.Log("sys_semaphore_post(sem=%d, count=%d)", sem, count); - std::shared_ptr sem; - if (!Emu.GetIdManager().GetIDData(sem_id, sem)) + LV2_LOCK; + + std::shared_ptr semaphore; + if (!Emu.GetIdManager().GetIDData(sem, semaphore)) { return CELL_ESRCH; } @@ -196,52 +156,35 @@ s32 sys_semaphore_post(u32 sem_id, s32 count) return CELL_EINVAL; } - if (count + sem->value.read_sync() - (s32)sem->queue.count() > sem->max) + if (semaphore->value + count > semaphore->max + semaphore->waiters) { return CELL_EBUSY; } - while (count > 0) - { - if (Emu.IsStopped()) - { - sys_semaphore.Warning("sys_semaphore_post(%d) aborted", sem_id); - return CELL_OK; - } - - if (u32 target = sem->queue.signal(sem->protocol)) - { - count--; - } - else - { - sem->value.atomic_op([count](s32& value) - { - value += count; - }); - count = 0; - } - } + semaphore->value += count; assert(semaphore->value >= 0); + semaphore->cv.notify_all(); return CELL_OK; } -s32 sys_semaphore_get_value(u32 sem_id, vm::ptr count) +s32 sys_semaphore_get_value(u32 sem, vm::ptr count) { - sys_semaphore.Log("sys_semaphore_get_value(sem_id=%d, count_addr=0x%x)", sem_id, count.addr()); + sys_semaphore.Log("sys_semaphore_get_value(sem=%d, count=*0x%x)", sem, count); if (!count) { - sys_semaphore.Error("sys_semaphore_get_value(): invalid memory access (addr=0x%x)", count.addr()); return CELL_EFAULT; } - std::shared_ptr sem; - if (!Emu.GetIdManager().GetIDData(sem_id, sem)) + LV2_LOCK; + + std::shared_ptr semaphore; + if (!Emu.GetIdManager().GetIDData(sem, semaphore)) { return CELL_ESRCH; } - *count = sem->value.read_sync(); + *count = std::max(0, semaphore->value - semaphore->waiters); + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h index 7c3ac68c4e..674b2d94a8 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h @@ -1,12 +1,13 @@ #pragma once -struct sys_semaphore_attribute +struct sys_semaphore_attribute_t { be_t protocol; - be_t pshared; // undefined - be_t ipc_key; // undefined - be_t flags; // undefined - be_t pad; // not used + be_t pshared; + be_t ipc_key; + be_t flags; + be_t pad; + union { char name[8]; @@ -14,31 +15,35 @@ struct sys_semaphore_attribute }; }; -struct Semaphore +struct semaphore_t { - sleep_queue_t queue; - atomic_le_t value; - - const s32 max; const u32 protocol; + const s32 max; const u64 name; - Semaphore(s32 initial_count, s32 max_count, u32 protocol, u64 name) - : max(max_count) - , protocol(protocol) + std::atomic value; + + // TODO: use sleep queue, possibly remove condition variable + std::condition_variable cv; + std::atomic waiters; + + semaphore_t(u32 protocol, s32 max, u64 name, s32 value) + : protocol(protocol) + , max(max) , name(name) + , value(value) + , waiters(0) { - value.write_relaxed(initial_count); } }; // Aux -u32 semaphore_create(s32 initial_count, s32 max_count, u32 protocol, u64 name_u64); +u32 semaphore_create(s32 initial_val, s32 max_val, u32 protocol, u64 name_u64); // SysCalls -s32 sys_semaphore_create(vm::ptr sem, vm::ptr attr, s32 initial_count, s32 max_count); -s32 sys_semaphore_destroy(u32 sem_id); -s32 sys_semaphore_wait(u32 sem_id, u64 timeout); -s32 sys_semaphore_trywait(u32 sem_id); -s32 sys_semaphore_post(u32 sem_id, s32 count); -s32 sys_semaphore_get_value(u32 sem_id, vm::ptr count); +s32 sys_semaphore_create(vm::ptr sem, vm::ptr attr, s32 initial_val, s32 max_val); +s32 sys_semaphore_destroy(u32 sem); +s32 sys_semaphore_wait(u32 sem, u64 timeout); +s32 sys_semaphore_trywait(u32 sem); +s32 sys_semaphore_post(u32 sem, s32 count); +s32 sys_semaphore_get_value(u32 sem, vm::ptr count);