From 42cbaed6318edd7fb3ce1d178520f53874ebd8ce Mon Sep 17 00:00:00 2001 From: someone2639 Date: Fri, 22 Sep 2023 09:35:17 -0400 Subject: [PATCH] Track whether the RCP hang timer has started to prevent double setting (#689) * Track whether the RCP hang timer has started to prevent double setting * removed single letter struct field * remove debug lines --------- Co-authored-by: someone2639 --- src/boot/main.c | 10 +++++++--- src/game/main.h | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/boot/main.c b/src/boot/main.c index 65c45572..985b8243 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -303,13 +303,17 @@ void handle_dp_complete(void) { sCurrentDisplaySPTask = NULL; } -OSTimer RCPHangTimer; +OSTimerEx RCPHangTimer; void start_rcp_hang_timer(void) { - osSetTimer(&RCPHangTimer, OS_USEC_TO_CYCLES(3000000), (OSTime) 0, &gIntrMesgQueue, (OSMesg) MESG_RCP_HUNG); + if (RCPHangTimer.started == FALSE) { + osSetTimer(&RCPHangTimer.timer, OS_USEC_TO_CYCLES(3000000), (OSTime) 0, &gIntrMesgQueue, (OSMesg) MESG_RCP_HUNG); + RCPHangTimer.started = TRUE; + } } void stop_rcp_hang_timer(void) { - osStopTimer(&RCPHangTimer); + osStopTimer(&RCPHangTimer.timer); + RCPHangTimer.started = FALSE; } void alert_rcp_hung_up(void) { diff --git a/src/game/main.h b/src/game/main.h index 26f4679f..2ee80007 100644 --- a/src/game/main.h +++ b/src/game/main.h @@ -97,6 +97,16 @@ extern s8 gDebugLevelSelect; extern s8 gShowDebugText; #endif +// Special struct that keeps track of whether its timer has been set. +// Without this check, there is a bug at high CPU loads in which +// the RCP timer gets set twice and the game tries to +// insert __osBaseTimer into a ring buffer that only contains itself, +// causing a particularly messy crash. +typedef struct { + u8 started; + OSTimer timer; +} OSTimerEx; + void set_vblank_handler(s32 index, struct VblankHandler *handler, OSMesgQueue *queue, OSMesg *msg); void dispatch_audio_sptask(struct SPTask *spTask); void exec_display_list(struct SPTask *spTask);