From: fincs Date: Wed, 30 Sep 2015 20:39:57 +0000 (+0200) Subject: LightLock: avoid the svcArbitrateAddress() call if no thread is waiting X-Git-Tag: v1.0.0~100 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=9e43411a0ea44f0737cb0f468a25303911f5eee5;p=corbenik%2Fctrulib.git LightLock: avoid the svcArbitrateAddress() call if no thread is waiting --- diff --git a/libctru/source/synchronization.c b/libctru/source/synchronization.c index 1055c06..146a539 100644 --- a/libctru/source/synchronization.c +++ b/libctru/source/synchronization.c @@ -33,7 +33,7 @@ _begin: if (val < 0) { __clrex(); - svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0); + svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_DECREMENT_AND_WAIT_IF_LESS_THAN, 0, 0); goto _begin; // Try locking again } } while (__strex(lock, -val)); @@ -45,7 +45,14 @@ void LightLock_Unlock(LightLock* lock) do val = -__ldrex(lock); while (__strex(lock, val)); - svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_SIGNAL, 1, 0); + if (val > 1) + { + // Wake up exactly one thread + do + val = __ldrex(lock); + while (__strex(lock, val-1)); + svcArbitrateAddress(arbiter, (u32)lock, ARBITRATION_SIGNAL, 1, 0); + } } void RecursiveLock_Init(RecursiveLock* lock)