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 <someone2639@gmail.com>
This commit is contained in:
someone2639
2023-09-22 09:35:17 -04:00
committed by GitHub
parent e61bf8fbc1
commit 42cbaed631
2 changed files with 17 additions and 3 deletions

View File

@@ -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) {

View File

@@ -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);