From 7f786168eb076b4d366c1d085f4b71751b555379 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 4 Mar 2025 02:02:33 +0200 Subject: [PATCH] spu: fix thread vs savestates races --- plugins/dfsound/freeze.c | 8 +++++--- plugins/dfsound/spu.c | 7 +++++++ plugins/dfsound/spu.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c index ae6f16ac..b1ab2b53 100644 --- a/plugins/dfsound/freeze.c +++ b/plugins/dfsound/freeze.c @@ -139,6 +139,7 @@ typedef struct uint32_t XALastVal; uint32_t last_keyon_cycles; uint32_t rvb_sb[2][4]; + int32_t interpolation; // which interpolation's data is in SPUCHAN_orig::SB } SPUOSSFreeze_t; @@ -238,7 +239,7 @@ static void load_register(unsigned long reg, unsigned int cycles) // SPUFREEZE: called by main emu on savestate load/save //////////////////////////////////////////////////////////////////////// -long CALLBACK SPUfreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, +long DoFreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, unsigned int cycles) { SPUOSSFreeze_t * pFO = NULL; @@ -318,6 +319,7 @@ long CALLBACK SPUfreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, pFO->last_keyon_cycles = spu.last_keyon_cycles; for (i = 0; i < 2; i++) memcpy(&pFO->rvb_sb[i], sb_rvb->SB_rvb[i], sizeof(pFO->rvb_sb[i])); + pFO->interpolation = spu.interpolation; for(i=0;iulFreezeSize >= sizeof(*pF) + offsetof(SPUOSSFreeze_t, rvb_sb)) { spu.cycles_dma_end = pFO->cycles_dma_end; spu.decode_dirty_ch = pFO->decode_dirty_ch; @@ -378,6 +381,7 @@ long CALLBACK SPUfreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) memcpy(&sb_rvb->SB_rvb[i][j*4], pFO->rvb_sb[i], 4 * sizeof(sb_rvb->SB_rvb[i][0])); + spu.interpolation = pFO->interpolation; } // repair some globals @@ -393,8 +397,6 @@ long CALLBACK SPUfreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, spu.rvb->StartAddr = regAreaGet(H_SPUReverbAddr) << 2; if (spu.rvb->CurrAddr < spu.rvb->StartAddr) spu.rvb->CurrAddr = spu.rvb->StartAddr; - // fix to prevent new interpolations from crashing - spu.interpolation = -1; ClearWorkingState(); diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 0938a34b..81592723 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -1574,6 +1574,13 @@ static void exit_spu_thread(void) #endif +long CALLBACK SPUfreeze(unsigned int ulFreezeMode, struct SPUFreeze * pF, + unsigned int cycles) +{ + sync_worker_thread(1); + return DoFreeze(ulFreezeMode, pF, cycles); +} + // SPUINIT: this func will be called first by the main emu long CALLBACK SPUinit(void) { diff --git a/plugins/dfsound/spu.h b/plugins/dfsound/spu.h index d49d9033..f2aa9a4e 100644 --- a/plugins/dfsound/spu.h +++ b/plugins/dfsound/spu.h @@ -42,5 +42,6 @@ void CALLBACK SPUsetCDvol(unsigned char ll, unsigned char lr, // internal void ClearWorkingState(void); +long DoFreeze(unsigned int, struct SPUFreeze *, unsigned int); #endif /* __P_SPU_H__ */ -- 2.39.5