]> Chaos Git - corbenik/ctrulib.git/commitdiff
LightLock: avoid the svcArbitrateAddress() call if no thread is waiting
authorfincs <fincs.alt1@gmail.com>
Wed, 30 Sep 2015 20:39:57 +0000 (22:39 +0200)
committerfincs <fincs.alt1@gmail.com>
Wed, 30 Sep 2015 20:39:57 +0000 (22:39 +0200)
libctru/source/synchronization.c

index 1055c061f57c8b4aa6a196f3cf8580fdd58f4c3e..146a539d495ca57854b9f9a999ae0aaa83aea444 100644 (file)
@@ -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)