From bbf5fadd830f4859ac9ae6fc91d7df6ca04d2495 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Tue, 28 May 2024 13:33:29 +0100 Subject: [PATCH] Scheduling Fixes (#117) * Fix mod_assets.py for python 3.8 * sched.c: Defer RSP task completion signal until after the scheduler has started the next task to improve throughput * audio_thread_manager.c: Delay audio thread updates to give the graphics microcode time to generate work for the RDP before it has to yield * audio_thread_manager.c: Bump audio update delay to 3ms Co-authored-by: Sauraen --------- Co-authored-by: Sauraen --- src/code/audio_thread_manager.c | 9 +++++++++ src/code/sched.c | 15 ++++++++++----- tools/mod_assets.py | 8 +++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/code/audio_thread_manager.c b/src/code/audio_thread_manager.c index bda8e2dc6..a0732d8f2 100644 --- a/src/code/audio_thread_manager.c +++ b/src/code/audio_thread_manager.c @@ -23,6 +23,15 @@ void AudioMgr_NotifyTaskDone(AudioMgr* audioMgr) { void AudioMgr_HandleRetrace(AudioMgr* audioMgr) { AudioTask* rspTask; + // Delay the audio update by 3ms so that gfx has time to get going before it has to yield + OSTimer timer; + OSMesgQueue mq; + OSMesg mbuf; + osCreateMesgQueue(&mq, &mbuf, 1); + osSetTimer(&timer, OS_USEC_TO_CYCLES(3000), 0, &mq, NULL); + osRecvMesg(&mq, NULL, OS_MESG_BLOCK); + osStopTimer(&timer); + if (R_AUDIOMGR_DEBUG_LEVEL > AUDIOMGR_DEBUG_LEVEL_NONE) { // Inhibit audio rsp task processing audioMgr->rspTask = NULL; diff --git a/src/code/sched.c b/src/code/sched.c index d128b2e09..b1e72108f 100644 --- a/src/code/sched.c +++ b/src/code/sched.c @@ -552,7 +552,9 @@ void Sched_HandleRSPDone(Scheduler* sc) { SCHED_DEBUG_PRINTF("RSP DONE %d %d", curRSPTask->state & OS_SC_YIELD, osSpTaskYielded(&curRSPTask->list)); - if ((curRSPTask->state & OS_SC_YIELD) && osSpTaskYielded(&curRSPTask->list)) { + s32 inYield = (curRSPTask->state & OS_SC_YIELD) && osSpTaskYielded(&curRSPTask->list); + + if (inYield) { SCHED_DEBUG_PRINTF("[YIELDED]\n"); // Task yielded, set yielded state @@ -568,10 +570,6 @@ void Sched_HandleRSPDone(Scheduler* sc) { #if ENABLE_PROFILER Profiler_RSPDoneNotYield(curRSPTask->flags); #endif - - // Task has completed on the RSP, unset RSP flag and check if the task is fully complete - curRSPTask->state &= ~OS_SC_SP; - Sched_TaskComplete(sc, curRSPTask); } // Run next task in the queue if there is one and the necessary resources are available @@ -580,6 +578,13 @@ void Sched_HandleRSPDone(Scheduler* sc) { Sched_RunTask(sc, nextRSP, nextRDP); } SCHED_DEBUG_PRINTF("SP sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state); + + // Defer task completion signal until after the next task has been staged for maximum throughput + if (!inYield) { + // Task has completed on the RSP, unset RSP flag and check if the task is fully complete + curRSPTask->state &= ~OS_SC_SP; + Sched_TaskComplete(sc, curRSPTask); + } } /** diff --git a/tools/mod_assets.py b/tools/mod_assets.py index 244ae0291..8b541f2ed 100755 --- a/tools/mod_assets.py +++ b/tools/mod_assets.py @@ -101,6 +101,12 @@ def update_cache_time(root: str) -> int: return last_time +def remove_suffix(input_string, suffix): + if suffix and input_string.endswith(suffix): + return input_string[:-len(suffix)] + return input_string + + def main(): global allow_print @@ -109,7 +115,7 @@ def main(): args = parser.parse_args() allow_print = args.verbose - root = os.path.dirname(os.path.realpath(__file__)).removesuffix("/tools") + root = remove_suffix(os.path.dirname(os.path.realpath(__file__)), "/tools") last_cache_time = update_cache_time(root) copied_files = copy_all(root) remove_stale_assets(root, copied_files, last_cache_time)