diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 6e9b2935ca..0d9d91ffa3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -42,27 +42,27 @@ bool spursIsLibProfLoaded(); // // SPURS core functions // -s32 spursCreateLv2EventQueue(PPUThread& CPU, vm::ptr spurs, vm::ptr queueId, vm::ptr port, s32 size, vm::cptr name); -s32 spursAttachLv2EventQueue(PPUThread& CPU, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool spursCreated); +s32 spursCreateLv2EventQueue(PPUThread& ppu, vm::ptr spurs, vm::ptr queueId, vm::ptr port, s32 size, vm::cptr name); +s32 spursAttachLv2EventQueue(PPUThread& ppu, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool spursCreated); s32 spursDetachLv2EventQueue(vm::ptr spurs, u8 spuPort, bool spursCreated); -void spursHandlerWaitReady(PPUThread& CPU, vm::ptr spurs); -void spursHandlerEntry(PPUThread& CPU); +void spursHandlerWaitReady(PPUThread& ppu, vm::ptr spurs); +void spursHandlerEntry(PPUThread& ppu); s32 spursCreateHandler(vm::ptr spurs, u32 ppuPriority); -s32 spursInvokeEventHandlers(PPUThread& CPU, vm::ptr eventPortMux); -s32 spursWakeUpShutdownCompletionWaiter(PPUThread& CPU, vm::ptr spurs, u32 wid); -void spursEventHelperEntry(PPUThread& CPU); -s32 spursCreateSpursEventHelper(PPUThread& CPU, vm::ptr spurs, u32 ppuPriority); +s32 spursInvokeEventHandlers(PPUThread& ppu, vm::ptr eventPortMux); +s32 spursWakeUpShutdownCompletionWaiter(PPUThread& ppu, vm::ptr spurs, u32 wid); +void spursEventHelperEntry(PPUThread& ppu); +s32 spursCreateSpursEventHelper(PPUThread& ppu, vm::ptr spurs, u32 ppuPriority); void spursInitialiseEventPortMux(vm::ptr eventPortMux, u8 spuPort, u32 eventPort, u32 unknown); s32 spursAddDefaultSystemWorkload(vm::ptr spurs, vm::cptr swlPriority, u32 swlMaxSpu, u32 swlIsPreem); s32 spursFinalizeSpu(vm::ptr spurs); -s32 spursStopEventHelper(PPUThread& CPU, vm::ptr spurs); -s32 spursSignalToHandlerThread(PPUThread& CPU, vm::ptr spurs); -s32 spursJoinHandlerThread(PPUThread& CPU, vm::ptr spurs); -s32 spursInit(PPUThread& CPU, vm::ptr spurs, u32 revision, u32 sdkVersion, s32 nSpus, s32 spuPriority, s32 ppuPriority, u32 flags, +s32 spursStopEventHelper(PPUThread& ppu, vm::ptr spurs); +s32 spursSignalToHandlerThread(PPUThread& ppu, vm::ptr spurs); +s32 spursJoinHandlerThread(PPUThread& ppu, vm::ptr spurs); +s32 spursInit(PPUThread& ppu, vm::ptr spurs, u32 revision, u32 sdkVersion, s32 nSpus, s32 spuPriority, s32 ppuPriority, u32 flags, vm::cptr prefix, u32 prefixSize, u32 container, vm::cptr swlPriority, u32 swlMaxSpu, u32 swlIsPreem); -s32 cellSpursInitialize(PPUThread& CPU, vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork); -s32 cellSpursInitializeWithAttribute(PPUThread& CPU, vm::ptr spurs, vm::cptr attr); -s32 cellSpursInitializeWithAttribute2(PPUThread& CPU, vm::ptr spurs, vm::cptr attr); +s32 cellSpursInitialize(PPUThread& ppu, vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork); +s32 cellSpursInitializeWithAttribute(PPUThread& ppu, vm::ptr spurs, vm::cptr attr); +s32 cellSpursInitializeWithAttribute2(PPUThread& ppu, vm::ptr spurs, vm::cptr attr); s32 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork); s32 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr attr, u32 container); s32 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::cptr prefix, u32 size); @@ -76,7 +76,7 @@ s32 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::p s32 cellSpursSetMaxContention(vm::ptr spurs, u32 wid, u32 maxContention); s32 cellSpursSetPriorities(vm::ptr spurs, u32 wid, vm::cptr priorities); s32 cellSpursSetPreemptionVictimHints(vm::ptr spurs, vm::cptr isPreemptible); -s32 cellSpursAttachLv2EventQueue(PPUThread& CPU, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic); +s32 cellSpursAttachLv2EventQueue(PPUThread& ppu, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic); s32 cellSpursDetachLv2EventQueue(vm::ptr spurs, u8 port); s32 cellSpursEnableExceptionEventHandler(vm::ptr spurs, bool flag); s32 cellSpursSetGlobalExceptionEventHandler(vm::ptr spurs, vm::ptr eaHandler, vm::ptr arg); @@ -91,14 +91,14 @@ s32 cellSpursGetSpuGuid(); // // SPURS trace functions // -void spursTraceStatusUpdate(vm::ptr spurs); -s32 spursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus); -s32 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode); -s32 cellSpursTraceFinalize(vm::ptr spurs); -s32 spursTraceStart(vm::ptr spurs, u32 updateStatus); -s32 cellSpursTraceStart(vm::ptr spurs); -s32 spursTraceStop(vm::ptr spurs, u32 updateStatus); -s32 cellSpursTraceStop(vm::ptr spurs); +void spursTraceStatusUpdate(PPUThread& ppu, vm::ptr spurs); +s32 spursTraceInitialize(PPUThread& ppu, vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus); +s32 cellSpursTraceInitialize(PPUThread& ppu, vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode); +s32 cellSpursTraceFinalize(PPUThread& ppu, vm::ptr spurs); +s32 spursTraceStart(PPUThread& ppu, vm::ptr spurs, u32 updateStatus); +s32 cellSpursTraceStart(PPUThread& ppu, vm::ptr spurs); +s32 spursTraceStop(PPUThread& ppu, vm::ptr spurs, u32 updateStatus); +s32 cellSpursTraceStop(PPUThread& ppu, vm::ptr spurs); // // SPURS policy module functions @@ -113,7 +113,7 @@ s32 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, vm::ptr wid s32 cellSpursShutdownWorkload(); s32 cellSpursWaitForWorkloadShutdown(); s32 cellSpursRemoveWorkload(); -s32 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs); +s32 cellSpursWakeUp(PPUThread& ppu, vm::ptr spurs); s32 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 wid); s32 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::pptr flag); s32 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value); @@ -131,9 +131,9 @@ s32 cellSpursRequestIdleSpu(); // // SPURS taskset functions // -s32 spursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 max_contention, vm::cptr name, u32 size, s32 enable_clear_ls); -s32 cellSpursCreateTasksetWithAttribute(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, vm::ptr attr); -s32 cellSpursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 maxContention); +s32 spursCreateTaskset(PPUThread& ppu, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 max_contention, vm::cptr name, u32 size, s32 enable_clear_ls); +s32 cellSpursCreateTasksetWithAttribute(PPUThread& ppu, vm::ptr spurs, vm::ptr taskset, vm::ptr attr); +s32 cellSpursCreateTaskset(PPUThread& ppu, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 maxContention); s32 cellSpursJoinTaskset(vm::ptr taskset); s32 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid); s32 cellSpursShutdownTaskset(vm::ptr taskset); @@ -141,11 +141,11 @@ s32 cellSpursTasksetAttributeSetName(vm::ptr attr, vm s32 cellSpursTasksetAttributeSetTasksetSize(vm::ptr attr, u32 size); s32 cellSpursTasksetAttributeEnableClearLS(vm::ptr attr, s32 enable); s32 _cellSpursTasksetAttribute2Initialize(vm::ptr attribute, u32 revision); -s32 cellSpursCreateTaskset2(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, vm::ptr attr); +s32 cellSpursCreateTaskset2(PPUThread& ppu, vm::ptr spurs, vm::ptr taskset, vm::ptr attr); s32 cellSpursDestroyTaskset2(); s32 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, vm::ptr handler, vm::ptr arg); s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset); -s32 cellSpursLookUpTasksetAddress(PPUThread& CPU, vm::ptr spurs, vm::pptr taskset, u32 id); +s32 cellSpursLookUpTasksetAddress(PPUThread& ppu, vm::ptr spurs, vm::pptr taskset, u32 id); s32 cellSpursTasksetGetSpursAddress(vm::cptr taskset, vm::ptr spurs); s32 cellSpursGetTasksetInfo(); s32 _cellSpursTasksetAttributeInitialize(vm::ptr attribute, u32 revision, u32 sdk_version, u64 args, vm::cptr priority, u32 max_contention); @@ -154,9 +154,9 @@ s32 _cellSpursTasksetAttributeInitialize(vm::ptr attr // SPURS task functions // s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm::cptr elf, vm::cptr context, u32 size, vm::ptr ls_pattern, vm::ptr arg); -s32 spursTaskStart(PPUThread& CPU, vm::ptr taskset, u32 taskId); -s32 cellSpursCreateTask(PPUThread& CPU, vm::ptr taskset, vm::ptr taskId, vm::cptr elf, vm::cptr context, u32 size, vm::ptr lsPattern, vm::ptr argument); -s32 _cellSpursSendSignal(PPUThread& CPU, vm::ptr taskset, u32 taskId); +s32 spursTaskStart(PPUThread& ppu, vm::ptr taskset, u32 taskId); +s32 cellSpursCreateTask(PPUThread& ppu, vm::ptr taskset, vm::ptr taskId, vm::cptr elf, vm::cptr context, u32 size, vm::ptr lsPattern, vm::ptr argument); +s32 _cellSpursSendSignal(PPUThread& ppu, vm::ptr taskset, u32 taskId); s32 cellSpursCreateTaskWithAttribute(); s32 cellSpursTaskExitCodeGet(); s32 cellSpursTaskExitCodeInitialize(); @@ -178,11 +178,11 @@ s32 cellSpursCreateTask2WithBinInfo(); // s32 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptr taskset, vm::ptr eventFlag, u32 flagClearMode, u32 flagDirection); s32 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits); -s32 cellSpursEventFlagSet(PPUThread& CPU, vm::ptr eventFlag, u16 bits); -s32 spursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block); -s32 cellSpursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode); -s32 cellSpursEventFlagTryWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode); -s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& CPU, vm::ptr eventFlag); +s32 cellSpursEventFlagSet(PPUThread& ppu, vm::ptr eventFlag, u16 bits); +s32 spursEventFlagWait(PPUThread& ppu, vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block); +s32 cellSpursEventFlagWait(PPUThread& ppu, vm::ptr eventFlag, vm::ptr mask, u32 mode); +s32 cellSpursEventFlagTryWait(PPUThread& ppu, vm::ptr eventFlag, vm::ptr mask, u32 mode); +s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& ppu, vm::ptr eventFlag); s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag); s32 cellSpursEventFlagGetDirection(vm::ptr eventFlag, vm::ptr direction); s32 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::ptr clear_mode); @@ -281,9 +281,9 @@ bool spursIsLibProfLoaded() //---------------------------------------------------------------------------- /// Create an LV2 event queue and attach it to the SPURS instance -s32 spursCreateLv2EventQueue(PPUThread& CPU, vm::ptr spurs, vm::ptr queueId, vm::ptr port, s32 size, vm::cptr name) +s32 spursCreateLv2EventQueue(PPUThread& ppu, vm::ptr spurs, vm::ptr queueId, vm::ptr port, s32 size, vm::cptr name) { - vm::stackvar attr(CPU); + vm::stackvar attr(ppu); auto sys_event_queue_attribute_initialize = [](vm::ptr attr) { @@ -299,8 +299,8 @@ s32 spursCreateLv2EventQueue(PPUThread& CPU, vm::ptr spurs, vm::ptr _port(CPU); - if (s32 rc = spursAttachLv2EventQueue(CPU, spurs, *queueId, _port, 1 /*isDynamic*/, true /*spursCreated*/)) + vm::stackvar _port(ppu); + if (s32 rc = spursAttachLv2EventQueue(ppu, spurs, *queueId, _port, 1 /*isDynamic*/, true /*spursCreated*/)) { sys_event_queue_destroy(*queueId, SYS_EVENT_QUEUE_DESTROY_FORCE); } @@ -310,7 +310,7 @@ s32 spursCreateLv2EventQueue(PPUThread& CPU, vm::ptr spurs, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool spursCreated) +s32 spursAttachLv2EventQueue(PPUThread& ppu, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool spursCreated) { if (!spurs || !port) { @@ -350,7 +350,7 @@ s32 spursAttachLv2EventQueue(PPUThread& CPU, vm::ptr spurs, u32 queue portMask |= 1ull << (i); } - vm::stackvar connectedPort(CPU); + vm::stackvar connectedPort(ppu); if (s32 res = sys_spu_thread_group_connect_event_all_threads(spurs->spuTG, queue, portMask, connectedPort)) { if (res == CELL_EISCONN) @@ -412,9 +412,9 @@ s32 spursDetachLv2EventQueue(vm::ptr spurs, u8 spuPort, bool spursCre } /// Wait until a workload in the SPURS instance becomes ready -void spursHandlerWaitReady(PPUThread& CPU, vm::ptr spurs) +void spursHandlerWaitReady(PPUThread& ppu, vm::ptr spurs) { - if (s32 rc = sys_lwmutex_lock(CPU, spurs.of(&CellSpurs::mutex), 0)) + if (s32 rc = sys_lwmutex_lock(ppu, spurs.of(&CellSpurs::mutex), 0)) { throw EXCEPTION("sys_lwmutex_lock() failed (0x%x)", rc); } @@ -427,12 +427,12 @@ void spursHandlerWaitReady(PPUThread& CPU, vm::ptr spurs) { extern u32 g_ppu_func_index__sys_lwmutex_unlock; // test - if (s32 rc = CALL_FUNC(CPU, sys_lwmutex_unlock, CPU, spurs.of(&CellSpurs::mutex))) + if (s32 rc = CALL_FUNC(ppu, sys_lwmutex_unlock, ppu, spurs.of(&CellSpurs::mutex))) { throw EXCEPTION("sys_lwmutex_unlock() failed (0x%x)", rc); } - sys_ppu_thread_exit(CPU, 0); + sys_ppu_thread_exit(ppu, 0); } // Find a runnable workload @@ -487,7 +487,7 @@ void spursHandlerWaitReady(PPUThread& CPU, vm::ptr spurs) spurs->handlerWaiting.store(1); if (spurs->handlerDirty.load() == 0) { - if (s32 rc = sys_lwcond_wait(CPU, spurs.of(&CellSpurs::cond), 0)) + if (s32 rc = sys_lwcond_wait(ppu, spurs.of(&CellSpurs::cond), 0)) { throw EXCEPTION("sys_lwcond_wait() failed (0x%x)", rc); } @@ -497,20 +497,20 @@ void spursHandlerWaitReady(PPUThread& CPU, vm::ptr spurs) } // If we reach here then a runnable workload was found - if (s32 rc = sys_lwmutex_unlock(CPU, spurs.of(&CellSpurs::mutex))) + if (s32 rc = sys_lwmutex_unlock(ppu, spurs.of(&CellSpurs::mutex))) { throw EXCEPTION("sys_lwmutex_unlock() failed (0x%x)", rc); } } /// Entry point of the SPURS handler thread. This thread is responsible for starting the SPURS SPU thread group. -void spursHandlerEntry(PPUThread& CPU) +void spursHandlerEntry(PPUThread& ppu) { - auto spurs = vm::ptr::make(VM_CAST(CPU.GPR[3])); + auto spurs = vm::ptr::make(VM_CAST(ppu.GPR[3])); if (spurs->flags & SAF_UNKNOWN_FLAG_30) { - sys_ppu_thread_exit(CPU, 0); + sys_ppu_thread_exit(ppu, 0); } while (true) @@ -519,7 +519,7 @@ void spursHandlerEntry(PPUThread& CPU) if (spurs->flags1 & SF1_EXIT_IF_NO_WORK) { - spursHandlerWaitReady(CPU, spurs); + spursHandlerWaitReady(ppu, spurs); } if (s32 rc = sys_spu_thread_group_start(spurs->spuTG)) @@ -531,7 +531,7 @@ void spursHandlerEntry(PPUThread& CPU) { if (rc == CELL_ESTAT) { - sys_ppu_thread_exit(CPU, 0); + sys_ppu_thread_exit(ppu, 0); } throw EXCEPTION("sys_spu_thread_group_join() failed (0x%x)", rc); @@ -544,7 +544,7 @@ void spursHandlerEntry(PPUThread& CPU) throw EXCEPTION("Unexpected handlerExiting value (false)"); } - sys_ppu_thread_exit(CPU, 0); + sys_ppu_thread_exit(ppu, 0); } } } @@ -558,7 +558,7 @@ s32 spursCreateHandler(vm::ptr spurs, u32 ppuPriority) } /// Invoke event handlers -s32 spursInvokeEventHandlers(PPUThread& CPU, vm::ptr eventPortMux) +s32 spursInvokeEventHandlers(PPUThread& ppu, vm::ptr eventPortMux) { if (eventPortMux->reqPending.exchange(0).data()) { @@ -566,7 +566,7 @@ s32 spursInvokeEventHandlers(PPUThread& CPU, vm::ptr ev for (auto node = handlerList; node; node = node->next) { - node->handler(CPU, eventPortMux, node->data); + node->handler(ppu, eventPortMux, node->data); } } @@ -574,7 +574,7 @@ s32 spursInvokeEventHandlers(PPUThread& CPU, vm::ptr ev } // Invoke workload shutdown completion callbacks -s32 spursWakeUpShutdownCompletionWaiter(PPUThread& CPU, vm::ptr spurs, u32 wid) +s32 spursWakeUpShutdownCompletionWaiter(PPUThread& ppu, vm::ptr spurs, u32 wid) { if (!spurs) { @@ -608,7 +608,7 @@ s32 spursWakeUpShutdownCompletionWaiter(PPUThread& CPU, vm::ptr spurs if (wklF.hook) { - wklF.hook(CPU, spurs, wid, wklF.hookArg); + wklF.hook(ppu, spurs, wid, wklF.hookArg); assert(wklEvent.load() & 0x01); assert(wklEvent.load() & 0x02); @@ -627,28 +627,28 @@ s32 spursWakeUpShutdownCompletionWaiter(PPUThread& CPU, vm::ptr spurs } /// Entry point of the SPURS event helper thread -void spursEventHelperEntry(PPUThread& CPU) +void spursEventHelperEntry(PPUThread& ppu) { - const auto spurs = vm::ptr::make(VM_CAST(CPU.GPR[3])); + const auto spurs = vm::ptr::make(VM_CAST(ppu.GPR[3])); bool terminate = false; - vm::stackvar eventArray(CPU, sizeof32(sys_event_t) * 8); - vm::stackvar> count(CPU); + vm::stackvar eventArray(ppu, sizeof32(sys_event_t) * 8); + vm::stackvar> count(ppu); vm::ptr events = eventArray; while (!terminate) { - if (s32 rc = sys_event_queue_receive(CPU, spurs->eventQueue, vm::null, 0 /*timeout*/)) + if (s32 rc = sys_event_queue_receive(ppu, spurs->eventQueue, vm::null, 0 /*timeout*/)) { throw EXCEPTION("sys_event_queue_receive() failed (0x%x)", rc); } - const u64 event_src = CPU.GPR[4]; - const u64 event_data1 = CPU.GPR[5]; - const u64 event_data2 = CPU.GPR[6]; - const u64 event_data3 = CPU.GPR[7]; + const u64 event_src = ppu.GPR[4]; + const u64 event_data1 = ppu.GPR[5]; + const u64 event_data2 = ppu.GPR[6]; + const u64 event_data3 = ppu.GPR[7]; if (event_src == SYS_SPU_THREAD_EVENT_EXCEPTION_KEY) { @@ -691,7 +691,7 @@ void spursEventHelperEntry(PPUThread& CPU) { if (shutdownMask & (0x80000000u >> wid)) { - if (s32 rc = spursWakeUpShutdownCompletionWaiter(CPU, spurs, wid)) + if (s32 rc = spursWakeUpShutdownCompletionWaiter(ppu, spurs, wid)) { throw EXCEPTION("spursWakeUpShutdownCompletionWaiter() failed (0x%x)", rc); } @@ -699,7 +699,7 @@ void spursEventHelperEntry(PPUThread& CPU) if ((spurs->flags1 & SF1_32_WORKLOADS) && (shutdownMask & (0x8000 >> wid))) { - if (s32 rc = spursWakeUpShutdownCompletionWaiter(CPU, spurs, wid + 0x10)) + if (s32 rc = spursWakeUpShutdownCompletionWaiter(ppu, spurs, wid + 0x10)) { throw EXCEPTION("spursWakeUpShutdownCompletionWaiter() failed (0x%x)", rc); } @@ -715,7 +715,7 @@ void spursEventHelperEntry(PPUThread& CPU) } else if (data0 == 3) { - if (s32 rc = spursInvokeEventHandlers(CPU, spurs.of(&CellSpurs::eventPortMux))) + if (s32 rc = spursInvokeEventHandlers(ppu, spurs.of(&CellSpurs::eventPortMux))) { throw EXCEPTION("spursInvokeEventHandlers() failed (0x%x)", rc); } @@ -729,12 +729,12 @@ void spursEventHelperEntry(PPUThread& CPU) } /// Create the SPURS event helper thread -s32 spursCreateSpursEventHelper(PPUThread& CPU, vm::ptr spurs, u32 ppuPriority) +s32 spursCreateSpursEventHelper(PPUThread& ppu, vm::ptr spurs, u32 ppuPriority) { - vm::stackvar evqName(CPU, 8); + vm::stackvar evqName(ppu, 8); memcpy(evqName.get_ptr(), "_spuPrv", 8); - if (s32 rc = spursCreateLv2EventQueue(CPU, spurs, spurs.of(&CellSpurs::eventQueue), spurs.of(&CellSpurs::spuPort), 0x2A /*size*/, evqName)) + if (s32 rc = spursCreateLv2EventQueue(ppu, spurs, spurs.of(&CellSpurs::eventQueue), spurs.of(&CellSpurs::spuPort), 0x2A /*size*/, evqName)) { return rc; } @@ -843,7 +843,7 @@ s32 spursFinalizeSpu(vm::ptr spurs) } /// Stop the event helper thread -s32 spursStopEventHelper(PPUThread& CPU, vm::ptr spurs) +s32 spursStopEventHelper(PPUThread& ppu, vm::ptr spurs) { if (spurs->ppu1 == 0xFFFFFFFF) { @@ -855,7 +855,7 @@ s32 spursStopEventHelper(PPUThread& CPU, vm::ptr spurs) return CELL_SPURS_CORE_ERROR_STAT; } - if (sys_ppu_thread_join(CPU, (u32)spurs->ppu1, vm::stackvar>(CPU)) != CELL_OK) + if (sys_ppu_thread_join(ppu, (u32)spurs->ppu1, vm::stackvar>(ppu)) != CELL_OK) { return CELL_SPURS_CORE_ERROR_STAT; } @@ -886,19 +886,19 @@ s32 spursStopEventHelper(PPUThread& CPU, vm::ptr spurs) } /// Signal to the SPURS handler thread -s32 spursSignalToHandlerThread(PPUThread& CPU, vm::ptr spurs) +s32 spursSignalToHandlerThread(PPUThread& ppu, vm::ptr spurs) { - if (s32 rc = sys_lwmutex_lock(CPU, spurs.of(&CellSpurs::mutex), 0 /* forever */)) + if (s32 rc = sys_lwmutex_lock(ppu, spurs.of(&CellSpurs::mutex), 0 /* forever */)) { throw EXCEPTION("sys_lwmutex_lock() failed (0x%x)", rc); } - if (s32 rc = sys_lwcond_signal(CPU, spurs.of(&CellSpurs::cond))) + if (s32 rc = sys_lwcond_signal(ppu, spurs.of(&CellSpurs::cond))) { throw EXCEPTION("sys_lwcond_signal() failed (0x%x)", rc); } - if (s32 rc = sys_lwmutex_unlock(CPU, spurs.of(&CellSpurs::mutex))) + if (s32 rc = sys_lwmutex_unlock(ppu, spurs.of(&CellSpurs::mutex))) { throw EXCEPTION("sys_lwmutex_unlock() failed (0x%x)", rc); } @@ -907,14 +907,14 @@ s32 spursSignalToHandlerThread(PPUThread& CPU, vm::ptr spurs) } /// Join the SPURS handler thread -s32 spursJoinHandlerThread(PPUThread& CPU, vm::ptr spurs) +s32 spursJoinHandlerThread(PPUThread& ppu, vm::ptr spurs) { if (spurs->ppu0 == 0xFFFFFFFF) { return CELL_SPURS_CORE_ERROR_STAT; } - if (s32 rc = sys_ppu_thread_join(CPU, (u32)spurs->ppu0, vm::stackvar>(CPU))) + if (s32 rc = sys_ppu_thread_join(ppu, (u32)spurs->ppu0, vm::stackvar>(ppu))) { throw EXCEPTION("sys_ppu_thread_join() failed (0x%x)", rc); } @@ -925,7 +925,7 @@ s32 spursJoinHandlerThread(PPUThread& CPU, vm::ptr spurs) /// Initialise SPURS s32 spursInit( - PPUThread& CPU, + PPUThread& ppu, vm::ptr spurs, u32 revision, u32 sdkVersion, @@ -940,17 +940,17 @@ s32 spursInit( u32 swlMaxSpu, u32 swlIsPreem) { - vm::stackvar> sem(CPU); - vm::stackvar semAttr(CPU); - vm::stackvar lwCondAttr(CPU); - vm::stackvar lwMutexAttr(CPU); - vm::stackvar> spuTgId(CPU); - vm::stackvar spuTgName(CPU, 128); - vm::stackvar spuTgAttr(CPU); - vm::stackvar spuThArgs(CPU); - vm::stackvar> spuThreadId(CPU); - vm::stackvar spuThAttr(CPU); - vm::stackvar spuThName(CPU, 128); + vm::stackvar> sem(ppu); + vm::stackvar semAttr(ppu); + vm::stackvar lwCondAttr(ppu); + vm::stackvar lwMutexAttr(ppu); + vm::stackvar> spuTgId(ppu); + vm::stackvar spuTgName(ppu, 128); + vm::stackvar spuTgAttr(ppu); + vm::stackvar spuThArgs(ppu); + vm::stackvar> spuThreadId(ppu); + vm::stackvar spuThAttr(ppu); + vm::stackvar spuThName(ppu, 128); if (!spurs) { @@ -1167,7 +1167,7 @@ s32 spursInit( if (flags & SAF_SPU_PRINTF_ENABLED) { // spu_printf: attach group - if (!spu_printf_agcb || spu_printf_agcb(CPU, spurs->spuTG) != CELL_OK) + if (!spu_printf_agcb || spu_printf_agcb(ppu, spurs->spuTG) != CELL_OK) { // remove flag if failed spurs->flags &= ~SAF_SPU_PRINTF_ENABLED; @@ -1197,7 +1197,7 @@ s32 spursInit( memcpy(lwCondAttr->name, "_spuPrv", 8); if (s32 rc = sys_lwcond_create(lwCond, lwMutex, lwCondAttr)) { - sys_lwmutex_destroy(CPU, lwMutex); + sys_lwmutex_destroy(ppu, lwMutex); spursFinalizeSpu(spurs); return rollback(), rc; } @@ -1211,10 +1211,10 @@ s32 spursInit( spurs->ppuPriority = ppuPriority; // Create the SPURS event helper thread - if (s32 rc = spursCreateSpursEventHelper(CPU, spurs, ppuPriority)) + if (s32 rc = spursCreateSpursEventHelper(ppu, spurs, ppuPriority)) { sys_lwcond_destroy(lwCond); - sys_lwmutex_destroy(CPU, lwMutex); + sys_lwmutex_destroy(ppu, lwMutex); spursFinalizeSpu(spurs); return rollback(), rc; } @@ -1222,9 +1222,9 @@ s32 spursInit( // Create the SPURS handler thread if (s32 rc = spursCreateHandler(spurs, ppuPriority)) { - spursStopEventHelper(CPU, spurs); + spursStopEventHelper(ppu, spurs); sys_lwcond_destroy(lwCond); - sys_lwmutex_destroy(CPU, lwMutex); + sys_lwmutex_destroy(ppu, lwMutex); spursFinalizeSpu(spurs); return rollback(), rc; } @@ -1232,11 +1232,11 @@ s32 spursInit( // Enable SPURS exception handler if (s32 rc = cellSpursEnableExceptionEventHandler(spurs, true /*enable*/)) { - spursSignalToHandlerThread(CPU, spurs); - spursJoinHandlerThread(CPU, spurs); - spursStopEventHelper(CPU, spurs); + spursSignalToHandlerThread(ppu, spurs); + spursJoinHandlerThread(ppu, spurs); + spursStopEventHelper(ppu, spurs); sys_lwcond_destroy(lwCond); - sys_lwmutex_destroy(CPU, lwMutex); + sys_lwmutex_destroy(ppu, lwMutex); spursFinalizeSpu(spurs); return rollback(), rc; } @@ -1259,22 +1259,22 @@ s32 spursInit( } else if (flags & SAF_EXIT_IF_NO_WORK) { - return cellSpursWakeUp(CPU, spurs); + return cellSpursWakeUp(ppu, spurs); } return CELL_OK; } /// Initialise SPURS -s32 cellSpursInitialize(PPUThread& CPU, vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) +s32 cellSpursInitialize(PPUThread& ppu, vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { cellSpurs.Warning("cellSpursInitialize(spurs=*0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", spurs, nSpus, spuPriority, ppuPriority, exitIfNoWork); - return spursInit(CPU, spurs, 0, 0, nSpus, spuPriority, ppuPriority, exitIfNoWork ? SAF_EXIT_IF_NO_WORK : SAF_NONE, vm::null, 0, 0, vm::null, 0, 0); + return spursInit(ppu, spurs, 0, 0, nSpus, spuPriority, ppuPriority, exitIfNoWork ? SAF_EXIT_IF_NO_WORK : SAF_NONE, vm::null, 0, 0, vm::null, 0, 0); } /// Initialise SPURS -s32 cellSpursInitializeWithAttribute(PPUThread& CPU, vm::ptr spurs, vm::cptr attr) +s32 cellSpursInitializeWithAttribute(PPUThread& ppu, vm::ptr spurs, vm::cptr attr) { cellSpurs.Warning("cellSpursInitializeWithAttribute(spurs=*0x%x, attr=*0x%x)", spurs, attr); @@ -1294,7 +1294,7 @@ s32 cellSpursInitializeWithAttribute(PPUThread& CPU, vm::ptr spurs, v } return spursInit( - CPU, + ppu, spurs, attr->revision, attr->sdkVersion, @@ -1311,7 +1311,7 @@ s32 cellSpursInitializeWithAttribute(PPUThread& CPU, vm::ptr spurs, v } /// Initialise SPURS -s32 cellSpursInitializeWithAttribute2(PPUThread& CPU, vm::ptr spurs, vm::cptr attr) +s32 cellSpursInitializeWithAttribute2(PPUThread& ppu, vm::ptr spurs, vm::cptr attr) { cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs=*0x%x, attr=*0x%x)", spurs, attr); @@ -1331,7 +1331,7 @@ s32 cellSpursInitializeWithAttribute2(PPUThread& CPU, vm::ptr spurs, } return spursInit( - CPU, + ppu, spurs, attr->revision, attr->sdkVersion, @@ -1745,11 +1745,11 @@ s32 cellSpursSetPreemptionVictimHints(vm::ptr spurs, vm::cptr i } /// Attach an LV2 event queue to a SPURS instance -s32 cellSpursAttachLv2EventQueue(PPUThread& CPU, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic) +s32 cellSpursAttachLv2EventQueue(PPUThread& ppu, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic) { cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs=*0x%x, queue=0x%x, port=*0x%x, isDynamic=%d)", spurs, queue, port, isDynamic); - return spursAttachLv2EventQueue(CPU, spurs, queue, port, isDynamic, false /*spursCreated*/); + return spursAttachLv2EventQueue(ppu, spurs, queue, port, isDynamic, false /*spursCreated*/); } /// Detach an LV2 event queue from a SPURS instance @@ -1860,7 +1860,7 @@ s32 cellSpursGetSpuGuid() //---------------------------------------------------------------------------- /// Signal SPUs to update trace status -void spursTraceStatusUpdate(vm::ptr spurs) +void spursTraceStatusUpdate(PPUThread& ppu, vm::ptr spurs) { u8 init; @@ -1877,7 +1877,7 @@ void spursTraceStatusUpdate(vm::ptr spurs) { spurs->sysSrvMessage.store(0xFF); - if (s32 rc = sys_semaphore_wait((u32)spurs->semPrv, 0)) + if (s32 rc = sys_semaphore_wait(ppu, (u32)spurs->semPrv, 0)) { throw EXCEPTION("sys_semaphore_wait() failed (0x%x)", rc); } @@ -1885,7 +1885,7 @@ void spursTraceStatusUpdate(vm::ptr spurs) } /// Initialize SPURS trace -s32 spursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus) +s32 spursTraceInitialize(PPUThread& ppu, vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus) { if (!spurs || !buffer) { @@ -1929,14 +1929,14 @@ s32 spursTraceInitialize(vm::ptr spurs, vm::ptr b spurs->sysSrvTraceControl = 0; if (updateStatus) { - spursTraceStatusUpdate(spurs); + spursTraceStatusUpdate(ppu, spurs); } return CELL_OK; } /// Initialize SPURS trace -s32 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode) +s32 cellSpursTraceInitialize(PPUThread& ppu, vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode) { cellSpurs.Warning("cellSpursTraceInitialize(spurs=*0x%x, buffer=*0x%x, size=0x%x, mode=0x%x)", spurs, buffer, size, mode); @@ -1945,11 +1945,11 @@ s32 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr spurs) +s32 cellSpursTraceFinalize(PPUThread& ppu, vm::ptr spurs) { cellSpurs.Warning("cellSpursTraceFinalize(spurs=*0x%x)", spurs); @@ -1971,12 +1971,12 @@ s32 cellSpursTraceFinalize(vm::ptr spurs) spurs->sysSrvTraceControl = 0; spurs->traceMode = 0; spurs->traceBuffer = vm::null; - spursTraceStatusUpdate(spurs); + spursTraceStatusUpdate(ppu, spurs); return CELL_OK; } /// Start SPURS trace -s32 spursTraceStart(vm::ptr spurs, u32 updateStatus) +s32 spursTraceStart(PPUThread& ppu, vm::ptr spurs, u32 updateStatus) { if (!spurs) { @@ -1996,14 +1996,14 @@ s32 spursTraceStart(vm::ptr spurs, u32 updateStatus) spurs->sysSrvTraceControl = 1; if (updateStatus) { - spursTraceStatusUpdate(spurs); + spursTraceStatusUpdate(ppu, spurs); } return CELL_OK; } /// Start SPURS trace -s32 cellSpursTraceStart(vm::ptr spurs) +s32 cellSpursTraceStart(PPUThread& ppu, vm::ptr spurs) { cellSpurs.Warning("cellSpursTraceStart(spurs=*0x%x)", spurs); @@ -2017,11 +2017,11 @@ s32 cellSpursTraceStart(vm::ptr spurs) return CELL_SPURS_CORE_ERROR_ALIGN; } - return spursTraceStart(spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); + return spursTraceStart(ppu, spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); } /// Stop SPURS trace -s32 spursTraceStop(vm::ptr spurs, u32 updateStatus) +s32 spursTraceStop(PPUThread& ppu, vm::ptr spurs, u32 updateStatus) { if (!spurs) { @@ -2041,14 +2041,14 @@ s32 spursTraceStop(vm::ptr spurs, u32 updateStatus) spurs->sysSrvTraceControl = 2; if (updateStatus) { - spursTraceStatusUpdate(spurs); + spursTraceStatusUpdate(ppu, spurs); } return CELL_OK; } /// Stop SPURS trace -s32 cellSpursTraceStop(vm::ptr spurs) +s32 cellSpursTraceStop(PPUThread& ppu, vm::ptr spurs) { cellSpurs.Warning("cellSpursTraceStop(spurs=*0x%x)", spurs); @@ -2062,7 +2062,7 @@ s32 cellSpursTraceStop(vm::ptr spurs) return CELL_SPURS_CORE_ERROR_ALIGN; } - return spursTraceStop(spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); + return spursTraceStop(ppu, spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); } //---------------------------------------------------------------------------- @@ -2384,7 +2384,7 @@ s32 cellSpursRemoveWorkload() } /// Activate the SPURS kernel -s32 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs) +s32 cellSpursWakeUp(PPUThread& ppu, vm::ptr spurs) { cellSpurs.Warning("cellSpursWakeUp(spurs=*0x%x)", spurs); @@ -2407,7 +2407,7 @@ s32 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs) if (spurs->handlerWaiting.load()) { - spursSignalToHandlerThread(CPU, spurs); + spursSignalToHandlerThread(ppu, spurs); } return CELL_OK; @@ -2761,7 +2761,7 @@ s32 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) } /// Set a SPURS event flag -s32 cellSpursEventFlagSet(PPUThread& CPU, vm::ptr eventFlag, u16 bits) +s32 cellSpursEventFlagSet(PPUThread& ppu, vm::ptr eventFlag, u16 bits) { cellSpurs.Warning("cellSpursEventFlagSet(eventFlag=*0x%x, bits=0x%x)", eventFlag, bits); @@ -2867,17 +2867,17 @@ s32 cellSpursEventFlagSet(PPUThread& CPU, vm::ptr eventFlag, if (pendingRecv & (0x8000 >> i)) { eventFlag->pendingRecvTaskEvents[i] = pendingRecvTaskEvents[i]; - vm::stackvar> taskset(CPU); + vm::stackvar> taskset(ppu); if (eventFlag->isIwl) { - cellSpursLookUpTasksetAddress(CPU, vm::ptr::make((u32)eventFlag->addr), taskset, eventFlag->waitingTaskWklId[i]); + cellSpursLookUpTasksetAddress(ppu, vm::ptr::make((u32)eventFlag->addr), taskset, eventFlag->waitingTaskWklId[i]); } else { taskset->set((u32)eventFlag->addr); } - auto rc = _cellSpursSendSignal(CPU, taskset.value(), eventFlag->waitingTaskId[i]); + auto rc = _cellSpursSendSignal(ppu, taskset.value(), eventFlag->waitingTaskId[i]); if (rc == CELL_SPURS_TASK_ERROR_INVAL || rc == CELL_SPURS_TASK_ERROR_STAT) { return CELL_SPURS_TASK_ERROR_FATAL; @@ -2895,7 +2895,7 @@ s32 cellSpursEventFlagSet(PPUThread& CPU, vm::ptr eventFlag, } /// Wait for SPURS event flag -s32 spursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block) +s32 spursEventFlagWait(PPUThread& ppu, vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block) { if (!eventFlag || !mask) { @@ -3033,7 +3033,7 @@ s32 spursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm if (recv) { // Block till something happens - if (s32 rc = sys_event_queue_receive(CPU, eventFlag->eventQueueId, vm::null, 0)) + if (s32 rc = sys_event_queue_receive(ppu, eventFlag->eventQueueId, vm::null, 0)) { throw EXCEPTION("sys_event_queue_receive() failed (0x%x)", rc); } @@ -3053,23 +3053,23 @@ s32 spursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm } /// Wait for SPURS event flag -s32 cellSpursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode) +s32 cellSpursEventFlagWait(PPUThread& ppu, vm::ptr eventFlag, vm::ptr mask, u32 mode) { cellSpurs.Warning("cellSpursEventFlagWait(eventFlag=*0x%x, mask=*0x%x, mode=%d)", eventFlag, mask, mode); - return spursEventFlagWait(CPU, eventFlag, mask, mode, 1 /*block*/); + return spursEventFlagWait(ppu, eventFlag, mask, mode, 1 /*block*/); } /// Check SPURS event flag -s32 cellSpursEventFlagTryWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode) +s32 cellSpursEventFlagTryWait(PPUThread& ppu, vm::ptr eventFlag, vm::ptr mask, u32 mode) { cellSpurs.Warning("cellSpursEventFlagTryWait(eventFlag=*0x%x, mask=*0x%x, mode=0x%x)", eventFlag, mask, mode); - return spursEventFlagWait(CPU, eventFlag, mask, mode, 0 /*block*/); + return spursEventFlagWait(ppu, eventFlag, mask, mode, 0 /*block*/); } /// Attach an LV2 event queue to a SPURS event flag -s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& CPU, vm::ptr eventFlag) +s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& ppu, vm::ptr eventFlag) { cellSpurs.Warning("cellSpursEventFlagAttachLv2EventQueue(eventFlag=*0x%x)", eventFlag); @@ -3104,9 +3104,9 @@ s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& CPU, vm::ptrspurs; } - vm::stackvar> eventQueueId(CPU); - vm::stackvar port(CPU); - vm::stackvar evqName(CPU, 8); + vm::stackvar> eventQueueId(ppu); + vm::stackvar port(ppu); + vm::stackvar evqName(ppu, 8); memcpy(evqName.get_ptr(), "_spuEvF", 8); auto failure = [](s32 rc) -> s32 @@ -3115,7 +3115,7 @@ s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& CPU, vm::ptrdirection == CELL_SPURS_EVENT_FLAG_ANY2ANY) { - vm::stackvar> eventPortId(CPU); + vm::stackvar> eventPortId(ppu); s32 rc = sys_event_port_create(eventPortId, SYS_EVENT_PORT_LOCAL, 0); if (rc == CELL_OK) @@ -3374,7 +3374,7 @@ s32 cellSpursQueueGetDirection() return CELL_OK; } -s32 spursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 max_contention, vm::cptr name, u32 size, s32 enable_clear_ls) +s32 spursCreateTaskset(PPUThread& ppu, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 max_contention, vm::cptr name, u32 size, s32 enable_clear_ls) { if (!spurs || !taskset) { @@ -3393,7 +3393,7 @@ s32 spursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptrenable_clear_ls = enable_clear_ls > 0 ? 1 : 0; taskset->size = size; - vm::stackvar wkl_attr(CPU); + vm::stackvar wkl_attr(ppu); _cellSpursWorkloadAttributeInitialize(wkl_attr, 1 /*revision*/, 0x33 /*sdk_version*/, vm::cptr::make(SPURS_IMG_ADDR_TASKSET_PM), 0x1E40 /*pm_size*/, taskset.addr(), priority, 8 /*min_contention*/, max_contention); // TODO: Check return code @@ -3404,7 +3404,7 @@ s32 spursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr> wid(CPU); + vm::stackvar> wid(ppu); cellSpursAddWorkloadWithAttribute(spurs, wid, wkl_attr); // TODO: Check return code @@ -3416,7 +3416,7 @@ s32 spursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr spurs, vm::ptr taskset, vm::ptr attr) +s32 cellSpursCreateTasksetWithAttribute(PPUThread& ppu, vm::ptr spurs, vm::ptr taskset, vm::ptr attr) { cellSpurs.Warning("cellSpursCreateTasksetWithAttribute(spurs=*0x%x, taskset=*0x%x, attr=*0x%x)", spurs, taskset, attr); @@ -3435,7 +3435,7 @@ s32 cellSpursCreateTasksetWithAttribute(PPUThread& CPU, vm::ptr spurs return CELL_SPURS_TASK_ERROR_INVAL; } - auto rc = spursCreateTaskset(CPU, spurs, taskset, attr->args, attr.of(&CellSpursTasksetAttribute::priority), attr->max_contention, attr->name, attr->taskset_size, attr->enable_clear_ls); + auto rc = spursCreateTaskset(ppu, spurs, taskset, attr->args, attr.of(&CellSpursTasksetAttribute::priority), attr->max_contention, attr->name, attr->taskset_size, attr->enable_clear_ls); if (attr->taskset_size >= sizeof32(CellSpursTaskset2)) { @@ -3445,11 +3445,11 @@ s32 cellSpursCreateTasksetWithAttribute(PPUThread& CPU, vm::ptr spurs return rc; } -s32 cellSpursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 maxContention) +s32 cellSpursCreateTaskset(PPUThread& ppu, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 maxContention) { cellSpurs.Warning("cellSpursCreateTaskset(spurs=*0x%x, taskset=*0x%x, args=0x%llx, priority=*0x%x, maxContention=%d)", spurs, taskset, args, priority, maxContention); - return spursCreateTaskset(CPU, spurs, taskset, args, priority, maxContention, vm::null, sizeof32(CellSpursTaskset), 0); + return spursCreateTaskset(ppu, spurs, taskset, args, priority, maxContention, vm::null, sizeof32(CellSpursTaskset), 0); } s32 cellSpursJoinTaskset(vm::ptr taskset) @@ -3587,7 +3587,7 @@ s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm: return CELL_OK; } -s32 spursTaskStart(PPUThread& CPU, vm::ptr taskset, u32 taskId) +s32 spursTaskStart(PPUThread& ppu, vm::ptr taskset, u32 taskId) { auto pendingReady = taskset->pending_ready.value(); pendingReady._bit[taskId] = true; @@ -3595,7 +3595,7 @@ s32 spursTaskStart(PPUThread& CPU, vm::ptr taskset, u32 taskId cellSpursSendWorkloadSignal(taskset->spurs, taskset->wid); - if (s32 rc = cellSpursWakeUp(CPU, taskset->spurs)) + if (s32 rc = cellSpursWakeUp(ppu, taskset->spurs)) { if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) { @@ -3610,7 +3610,7 @@ s32 spursTaskStart(PPUThread& CPU, vm::ptr taskset, u32 taskId return CELL_OK; } -s32 cellSpursCreateTask(PPUThread& CPU, vm::ptr taskset, vm::ptr taskId, vm::cptr elf, vm::cptr context, u32 size, vm::ptr lsPattern, vm::ptr argument) +s32 cellSpursCreateTask(PPUThread& ppu, vm::ptr taskset, vm::ptr taskId, vm::cptr elf, vm::cptr context, u32 size, vm::ptr lsPattern, vm::ptr argument) { cellSpurs.Warning("cellSpursCreateTask(taskset=*0x%x, taskID=*0x%x, elf=*0x%x, context=*0x%x, size=0x%x, lsPattern=*0x%x, argument=*0x%x)", taskset, taskId, elf, context, size, lsPattern, argument); @@ -3624,14 +3624,14 @@ s32 cellSpursCreateTask(PPUThread& CPU, vm::ptr taskset, vm::p return CELL_SPURS_TASK_ERROR_ALIGN; } - vm::stackvar> tmpTaskId(CPU); + vm::stackvar> tmpTaskId(ppu); auto rc = spursCreateTask(taskset, tmpTaskId, elf, context, size, lsPattern, argument); if (rc != CELL_OK) { return rc; } - rc = spursTaskStart(CPU, taskset, tmpTaskId.value()); + rc = spursTaskStart(ppu, taskset, tmpTaskId.value()); if (rc != CELL_OK) { return rc; @@ -3641,7 +3641,7 @@ s32 cellSpursCreateTask(PPUThread& CPU, vm::ptr taskset, vm::p return CELL_OK; } -s32 _cellSpursSendSignal(PPUThread& CPU, vm::ptr taskset, u32 taskId) +s32 _cellSpursSendSignal(PPUThread& ppu, vm::ptr taskset, u32 taskId) { if (!taskset) { @@ -3675,7 +3675,7 @@ s32 _cellSpursSendSignal(PPUThread& CPU, vm::ptr taskset, u32 if (shouldSignal) { cellSpursSendWorkloadSignal(taskset->spurs, taskset->wid); - auto rc = cellSpursWakeUp(CPU, taskset->spurs); + auto rc = cellSpursWakeUp(ppu, taskset->spurs); if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) { return CELL_SPURS_TASK_ERROR_STAT; @@ -3847,11 +3847,11 @@ s32 cellSpursTaskGetContextSaveAreaSize() return CELL_OK; } -s32 cellSpursCreateTaskset2(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, vm::ptr attr) +s32 cellSpursCreateTaskset2(PPUThread& ppu, vm::ptr spurs, vm::ptr taskset, vm::ptr attr) { cellSpurs.Warning("cellSpursCreateTaskset2(spurs=*0x%x, taskset=*0x%x, attr=*0x%x)", spurs, taskset, attr); - vm::stackvar tmp_attr(CPU); + vm::stackvar tmp_attr(ppu); if (!attr) { @@ -3859,7 +3859,7 @@ s32 cellSpursCreateTaskset2(PPUThread& CPU, vm::ptr spurs, vm::ptrargs, attr.of(&CellSpursTasksetAttribute2::priority), attr->max_contention, attr->name, sizeof32(CellSpursTaskset2), attr->enable_clear_ls)) + if (s32 rc = spursCreateTaskset(ppu, spurs, taskset, attr->args, attr.of(&CellSpursTasksetAttribute2::priority), attr->max_contention, attr->name, sizeof32(CellSpursTaskset2), attr->enable_clear_ls)) { return rc; } @@ -3956,7 +3956,7 @@ s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset return CELL_OK; } -s32 cellSpursLookUpTasksetAddress(PPUThread& CPU, vm::ptr spurs, vm::pptr taskset, u32 id) +s32 cellSpursLookUpTasksetAddress(PPUThread& ppu, vm::ptr spurs, vm::pptr taskset, u32 id) { cellSpurs.Warning("cellSpursLookUpTasksetAddress(spurs=*0x%x, taskset=**0x%x, id=0x%x)", spurs, taskset, id); @@ -3965,7 +3965,7 @@ s32 cellSpursLookUpTasksetAddress(PPUThread& CPU, vm::ptr spurs, vm:: return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - vm::stackvar> data(CPU); + vm::stackvar> data(ppu); if (s32 rc = cellSpursGetWorkloadData(spurs, data, id)) { // Convert policy module error code to a task error code diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index ae6df82b57..1f77a1ebe6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -76,7 +76,7 @@ s32 sys_cond_destroy(u32 cond_id) return CELL_ESRCH; } - if (!cond->sq.empty() || cond.use_count() > 2) + if (!cond->sq.empty()) { return CELL_EBUSY; } @@ -197,7 +197,7 @@ s32 sys_cond_wait(PPUThread& ppu, u32 cond_id, u64 timeout) // add waiter; protocol is ignored in current implementation sleep_queue_entry_t waiter(ppu, cond->sq); - // add empty mutex waiter (may be actually set later) + // potential mutex waiter (not added immediately) sleep_queue_entry_t mutex_waiter(ppu, cond->mutex->sq, defer_sleep); while (!ppu.unsignal()) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index f6fb695c49..a542bb5863 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -80,7 +80,6 @@ s32 sys_mutex_destroy(u32 mutex_id) return CELL_ESRCH; } - // assuming that the mutex is locked immediately by another waiting thread when unlocked if (mutex->owner || mutex->sq.size()) { return CELL_EBUSY; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index 9884a712a0..7a7cc84a50 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -5,18 +5,17 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/Cell/PPUThread.h" -#include "sleep_queue.h" #include "sys_semaphore.h" SysCallBase sys_semaphore("sys_semaphore"); extern u64 get_system_time(); -s32 sys_semaphore_create(vm::ptr sem, vm::ptr attr, s32 initial_val, s32 max_val) +s32 sys_semaphore_create(vm::ptr sem_id, vm::ptr attr, s32 initial_val, s32 max_val) { - sys_semaphore.Warning("sys_semaphore_create(sem=*0x%x, attr=*0x%x, initial_val=%d, max_val=%d)", sem, attr, initial_val, max_val); + sys_semaphore.Warning("sys_semaphore_create(sem_id=*0x%x, attr=*0x%x, initial_val=%d, max_val=%d)", sem_id, attr, initial_val, max_val); - if (!sem || !attr) + if (!sem_id || !attr) { return CELL_EFAULT; } @@ -29,12 +28,10 @@ s32 sys_semaphore_create(vm::ptr sem, vm::ptr at const u32 protocol = attr->protocol; - switch (protocol) + if (protocol != SYS_SYNC_FIFO && protocol != SYS_SYNC_PRIORITY && protocol != SYS_SYNC_PRIORITY_INHERIT) { - 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; + sys_semaphore.Error("sys_semaphore_create(): unknown protocol (0x%x)", protocol); + return CELL_EINVAL; } if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data()) @@ -43,103 +40,115 @@ s32 sys_semaphore_create(vm::ptr sem, vm::ptr at return CELL_EINVAL; } - *sem = Emu.GetIdManager().make(protocol, max_val, attr->name_u64, initial_val); + *sem_id = Emu.GetIdManager().make(protocol, max_val, attr->name_u64, initial_val); return CELL_OK; } -s32 sys_semaphore_destroy(u32 sem) +s32 sys_semaphore_destroy(u32 sem_id) { - sys_semaphore.Warning("sys_semaphore_destroy(sem=0x%x)", sem); + sys_semaphore.Warning("sys_semaphore_destroy(sem_id=0x%x)", sem_id); LV2_LOCK; - const auto semaphore = Emu.GetIdManager().get(sem); + const auto sem = Emu.GetIdManager().get(sem_id); - if (!semaphore) + if (!sem) { return CELL_ESRCH; } - if (semaphore->waiters) + if (sem->sq.size()) { return CELL_EBUSY; } - Emu.GetIdManager().remove(sem); + Emu.GetIdManager().remove(sem_id); return CELL_OK; } -s32 sys_semaphore_wait(u32 sem, u64 timeout) +s32 sys_semaphore_wait(PPUThread& ppu, u32 sem_id, u64 timeout) { - sys_semaphore.Log("sys_semaphore_wait(sem=0x%x, timeout=0x%llx)", sem, timeout); + sys_semaphore.Log("sys_semaphore_wait(sem_id=0x%x, timeout=0x%llx)", sem_id, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - const auto semaphore = Emu.GetIdManager().get(sem); + const auto sem = Emu.GetIdManager().get(sem_id); - if (!semaphore) + if (!sem) { return CELL_ESRCH; } - // protocol is ignored in current implementation - semaphore->waiters++; + if (sem->value > 0) + { + sem->value--; + + return CELL_OK; + } - while (semaphore->value <= 0) + // add waiter; protocol is ignored in current implementation + sleep_queue_entry_t waiter(ppu, sem->sq); + + while (!ppu.unsignal()) { CHECK_EMU_STATUS; - if (timeout && get_system_time() - start_time > timeout) + if (timeout) { - semaphore->waiters--; - return CELL_ETIMEDOUT; + const u64 passed = get_system_time() - start_time; + + if (passed >= timeout) + { + return CELL_ETIMEDOUT; + } + + ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed)); + } + else + { + ppu.cv.wait(lv2_lock); } - - semaphore->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } - semaphore->value--; - semaphore->waiters--; - return CELL_OK; } -s32 sys_semaphore_trywait(u32 sem) +s32 sys_semaphore_trywait(u32 sem_id) { - sys_semaphore.Log("sys_semaphore_trywait(sem=0x%x)", sem); + sys_semaphore.Log("sys_semaphore_trywait(sem_id=0x%x)", sem_id); LV2_LOCK; - const auto semaphore = Emu.GetIdManager().get(sem); + const auto sem = Emu.GetIdManager().get(sem_id); - if (!semaphore) + if (!sem) { return CELL_ESRCH; } - if (semaphore->value <= 0 || semaphore->waiters) + if (sem->value <= 0 || sem->sq.size()) { return CELL_EBUSY; } - semaphore->value--; + sem->value--; return CELL_OK; } -s32 sys_semaphore_post(u32 sem, s32 count) +s32 sys_semaphore_post(u32 sem_id, s32 count) { - sys_semaphore.Log("sys_semaphore_post(sem=0x%x, count=%d)", sem, count); + sys_semaphore.Log("sys_semaphore_post(sem_id=0x%x, count=%d)", sem_id, count); LV2_LOCK; - const auto semaphore = Emu.GetIdManager().get(sem); + const auto sem = Emu.GetIdManager().get(sem_id); - if (!semaphore) + if (!sem) { return CELL_ESRCH; } @@ -149,43 +158,53 @@ s32 sys_semaphore_post(u32 sem, s32 count) return CELL_EINVAL; } - const u64 new_value = semaphore->value + count; - const u64 max_value = semaphore->max + semaphore->waiters; + // get comparable values considering waiting threads + const u64 new_value = sem->value + count; + const u64 max_value = sem->max + sem->sq.size(); if (new_value > max_value) { return CELL_EBUSY; } - semaphore->value += count; - - if (semaphore->waiters) + // wakeup as much threads as possible + while (count && !sem->sq.empty()) { - semaphore->cv.notify_all(); + count--; + + if (!sem->sq.front()->signal()) + { + throw EXCEPTION("Thread already signaled"); + } + + sem->sq.pop_front(); } + // add the rest to the value + sem->value += count; + return CELL_OK; } -s32 sys_semaphore_get_value(u32 sem, vm::ptr count) +s32 sys_semaphore_get_value(u32 sem_id, vm::ptr count) { - sys_semaphore.Log("sys_semaphore_get_value(sem=0x%x, count=*0x%x)", sem, count); + sys_semaphore.Log("sys_semaphore_get_value(sem_id=0x%x, count=*0x%x)", sem_id, count); + + LV2_LOCK; if (!count) { return CELL_EFAULT; } - LV2_LOCK; + const auto sem = Emu.GetIdManager().get(sem_id); - const auto semaphore = Emu.GetIdManager().get(sem); - - if (!semaphore) + if (!sem) { return CELL_ESRCH; } - *count = std::max(0, semaphore->value - semaphore->waiters); + *count = sem->value; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h index 25a0071cc0..d1922bad28 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h @@ -1,5 +1,7 @@ #pragma once +#include "sleep_queue.h" + namespace vm { using namespace ps3; } struct sys_semaphore_attribute_t @@ -25,26 +27,26 @@ struct lv2_sema_t std::atomic value; - // TODO: use sleep queue, possibly remove condition variable - std::condition_variable cv; - std::atomic waiters; + sleep_queue_t sq; lv2_sema_t(u32 protocol, s32 max, u64 name, s32 value) : protocol(protocol) , max(max) , name(name) , value(value) - , waiters(0) { } }; REG_ID_TYPE(lv2_sema_t, 0x96); // SYS_SEMAPHORE_OBJECT +// Aux +class PPUThread; + // SysCalls -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); +s32 sys_semaphore_create(vm::ptr sem_id, vm::ptr attr, s32 initial_val, s32 max_val); +s32 sys_semaphore_destroy(u32 sem_id); +s32 sys_semaphore_wait(PPUThread& ppu, 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); diff --git a/rpcs3/Gui/KernelExplorer.cpp b/rpcs3/Gui/KernelExplorer.cpp index 27846cc590..e61920c5e6 100644 --- a/rpcs3/Gui/KernelExplorer.cpp +++ b/rpcs3/Gui/KernelExplorer.cpp @@ -86,7 +86,7 @@ void KernelExplorer::Update() for (const auto id : Emu.GetIdManager().get_IDs(SYS_SEMAPHORE_OBJECT)) { const auto sem = Emu.GetIdManager().get(id); - sprintf(name, "Semaphore: ID = 0x%x '%s', Count = %d, Max Count = %d, Waiters = %d", id, &name64(sem->name), sem->value.load(), sem->max, sem->waiters.load()); + sprintf(name, "Semaphore: ID = 0x%x '%s', Count = %d, Max Count = %d, Waiters = %lld", id, &name64(sem->name), sem->value.load(), sem->max, sem->sq.size()); m_tree->AppendItem(node, name); } }