]> Chaos Git - corbenik/ctrulib.git/commitdiff
Add LightLock_TryLock and RecursiveLock_TryLock
authorfincs <fincs.alt1@gmail.com>
Sat, 21 Nov 2015 10:48:20 +0000 (11:48 +0100)
committerfincs <fincs.alt1@gmail.com>
Sat, 21 Nov 2015 10:48:20 +0000 (11:48 +0100)
libctru/include/3ds/synchronization.h
libctru/source/synchronization.c

index c8703bcfc04552e04508739936ea83a881649c45..05d94c6506b38cf86e6c66ad9c389b1e1a7c87a2 100644 (file)
@@ -75,6 +75,13 @@ void LightLock_Init(LightLock* lock);
  */
 void LightLock_Lock(LightLock* lock);
 
+/**
+ * @brief Attempts to lock a light lock.
+ * @param lock Pointer to the lock.
+ * @return Zero on success, non-zero on failure.
+ */
+int LightLock_TryLock(LightLock* lock);
+
 /**
  * @brief Unlocks a light lock.
  * @param lock Pointer to the lock.
@@ -93,6 +100,13 @@ void RecursiveLock_Init(RecursiveLock* lock);
  */
 void RecursiveLock_Lock(RecursiveLock* lock);
 
+/**
+ * @brief Attempts to lock a recursive lock.
+ * @param lock Pointer to the lock.
+ * @return Zero on success, non-zero on failure.
+ */
+int RecursiveLock_TryLock(RecursiveLock* lock);
+
 /**
  * @brief Unlocks a recursive lock.
  * @param lock Pointer to the lock.
index 9bc293fec6d790f2deb849da2a730ee3c75f2eb3..d2a550c2d3b616967229f2d8acc55548ce2c2360 100644 (file)
@@ -39,6 +39,21 @@ _begin:
        } while (__strex(lock, -val));
 }
 
+int LightLock_TryLock(LightLock* lock)
+{
+       s32 val;
+       do
+       {
+               val = __ldrex(lock);
+               if (val < 0)
+               {
+                       __clrex();
+                       return 1; // Failure
+               }
+       } while (__strex(lock, -val));
+       return 0; // Success
+}
+
 void LightLock_Unlock(LightLock* lock)
 {
        s32 val;
@@ -73,6 +88,19 @@ void RecursiveLock_Lock(RecursiveLock* lock)
        lock->counter ++;
 }
 
+int RecursiveLock_TryLock(RecursiveLock* lock)
+{
+       u32 tag = (u32)getThreadLocalStorage();
+       if (lock->thread_tag != tag)
+       {
+               if (LightLock_TryLock(&lock->lock))
+                       return 1; // Failure
+               lock->thread_tag = tag;
+       }
+       lock->counter ++;
+       return 0; // Success
+}
+
 void RecursiveLock_Unlock(RecursiveLock* lock)
 {
        if (!--lock->counter)