all repos — mgba @ c9ede88332bf9d1def0b3af005ad4d29456289e9

mGBA Game Boy Advance Emulator

GBA SIO: Attempt to stabilize lockstep driver
Jeffrey Pfau jeffrey@endrift.com
Thu, 01 Sep 2016 13:18:33 -0700
commit

c9ede88332bf9d1def0b3af005ad4d29456289e9

parent

f628f5bafcb5dedcbaa6a56c1e41cc086f2ceafa

1 files changed, 15 insertions(+), 18 deletions(-)

jump to
M src/gba/sio/lockstep.csrc/gba/sio/lockstep.c

@@ -13,37 +13,30 @@ #define LOCKSTEP_INCREMENT 3000

static bool _nodeWait(struct GBASIOLockstepNode* node, uint32_t mask) { uint32_t oldMask = 0; - if (ATOMIC_CMPXCHG(node->p->waiting[node->id], oldMask, mask)) { + if (ATOMIC_CMPXCHG(node->p->waiting[node->id], oldMask, mask | 0x10)) { node->p->wait(node->p, node->id); } -#ifndef NDEBUG - else if (oldMask != mask) { - abort(); - } -#endif - else if ((node->p->waiting[node->id] & oldMask) == node->p->waiting[node->id]) { - ATOMIC_AND(node->p->waitMask, ~mask); - return false; - } return true; } static bool _nodeSignal(struct GBASIOLockstepNode* node, uint32_t mask) { - mask = ATOMIC_OR(node->p->waitMask, mask); bool eventTriggered = false; int i; for (i = 0; i < node->p->attached; ++i) { - uint32_t waiting = node->p->waiting[i]; - if (waiting && (waiting & mask) == waiting && ATOMIC_CMPXCHG(node->p->waiting[i], waiting, 0)) { + uint32_t waiting = ATOMIC_AND(node->p->waiting[i], ~mask); + if (waiting == 0x10) { + if (!ATOMIC_CMPXCHG(node->p->waiting[i], waiting, 0)) { + return false; + } node->p->signal(node->p, i); eventTriggered = true; } } - if (eventTriggered) { - ATOMIC_STORE(node->p->waitMask, 0); + if (!eventTriggered) { + ATOMIC_STORE(node->p->waitMask, mask); } else { - mLOG(GBA_SIO, WARN, "Nothing woke with mask %X", mask); + ATOMIC_STORE(node->p->waitMask, 0); } return eventTriggered; }

@@ -71,7 +64,6 @@ lockstep->attached = 0;

lockstep->attachedMulti = 0; lockstep->transferActive = 0; memset(lockstep->waiting, 0, sizeof(lockstep->waiting)); - lockstep->waitMask = 0; #ifndef NDEBUG lockstep->transferId = 0; #endif

@@ -282,7 +274,11 @@ mask |= 1 << i;

} } if (mask) { - _nodeWait(node, mask); + if (!_nodeWait(node, mask)) { +#ifndef NDEBUG + abort(); +#endif + } } } // Tell the other GBAs they can continue up to where we were

@@ -373,6 +369,7 @@ if (cycles > 0) {

return cycles; } } + abort(); mLOG(GBA_SIO, WARN, "Sleeping needlessly"); } return cycles;