mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-27 18:52:11 -04:00
67455d81c4
The CI wrappers skipped every interrupt check while g_call_unit_depth > 0 (interp caller -> native callee). A callee polling for an IRQ-set flag (libcard MemCardSync) then spun forever: LoD "Checking MEMORY CARD". Deliver by default (thread switches are already deferred by psx_check_interrupts); legacy skip kept behind PSX_OVERLAY_UNIT_IRQ_DEFER=1. overlay_loader_status now reports call_unit_depth and ci_skip_*. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
32 lines
1.2 KiB
C
32 lines
1.2 KiB
C
/* IRQ policy for nested overlay call units (overlay_unit_defer.h).
|
|
*
|
|
* Regression for the Legend of Dragoon "Checking MEMORY CARD" hang: libcard's
|
|
* MemCardSync busy-waits on a flag set by an IRQ-driven event callback. Called
|
|
* from an interpreted caller into a native shard it ran as an atomic call unit
|
|
* and the overlay CI wrappers skipped every interrupt check for the whole call,
|
|
* so the flag was never set. The default must be to DELIVER inside units; the
|
|
* blanket skip exists only as an explicit A/B knob.
|
|
*
|
|
* Run: `ctest -R overlay_unit_defer_test`. */
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
|
|
#include "../src/overlay_unit_defer.h"
|
|
|
|
int main(void)
|
|
{
|
|
/* Default policy: never defer, at any nesting depth. */
|
|
assert(OVERLAY_UNIT_IRQ_DEFER_DEFAULT == 0);
|
|
for (int depth = -1; depth <= 8; depth++)
|
|
assert(overlay_unit_irq_must_defer(depth, OVERLAY_UNIT_IRQ_DEFER_DEFAULT) == 0);
|
|
|
|
/* Legacy A/B knob: defers exactly while inside a unit. */
|
|
assert(overlay_unit_irq_must_defer(0, 1) == 0);
|
|
assert(overlay_unit_irq_must_defer(1, 1) == 1);
|
|
assert(overlay_unit_irq_must_defer(3, 1) == 1);
|
|
assert(overlay_unit_irq_must_defer(-1, 1) == 0);
|
|
|
|
printf("overlay_unit_defer_test: ok\n");
|
|
return 0;
|
|
}
|