Define lll_mutex_cond_lock.
authordrepper <drepper>
Mon, 26 May 2003 02:38:05 +0000 (02:38 +0000)
committerdrepper <drepper>
Mon, 26 May 2003 02:38:05 +0000 (02:38 +0000)
nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h

index 5fd50b9..8923afb 100644 (file)
@@ -126,6 +126,24 @@ extern int __lll_mutex_unlock_wait (int *__futex)
                              : "memory"); })
 
 
+/* Special version of lll_mutex_lock which causes the unlock function to
+   always wakeup waiters.  */
+#define lll_mutex_cond_lock(futex) \
+  (void) ({ int ignore1, ignore2;                                            \
+           __asm __volatile (LOCK_INSTR "xaddl %0, %2\n\t"                   \
+                             "testl %0, %0\n\t"                              \
+                             "jne 1f\n\t"                                    \
+                             ".subsection 1\n"                               \
+                             "1:\tleal %2, %%ecx\n\t"                        \
+                             "call __lll_mutex_lock_wait\n\t"                \
+                             "jmp 2f\n\t"                                    \
+                             ".previous\n"                                   \
+                             "2:"                                            \
+                             : "=a" (ignore1), "=&c" (ignore2), "=m" (futex) \
+                             : "0" (2), "2" (futex)                          \
+                             : "memory"); })
+
+
 #define lll_mutex_timedlock(futex, timeout) \
   ({ int result, ignore1, ignore2;                                           \
      __asm __volatile (LOCK_INSTR "xaddl %0, %3\n\t"                         \
index 92c0b5c..b1941e0 100644 (file)
@@ -29,6 +29,7 @@
 #define SYS_futex              1230
 #define FUTEX_WAIT             0
 #define FUTEX_WAKE             1
+#define FUTEX_REQUEUE          3
 
 /* Initializer for compatibility lock. */
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
@@ -64,7 +65,7 @@
                         "=r" (__o0), "=r" (__o1), "=r" (__o2), "=r" (__o3)   \
                       : "i" (0x100000), "2" (__r15), "3" (__o0), "4" (__o1), \
                         "5" (__o2), "6" (__o3)                               \
-                      : lll_futex_clobbers);                                 \
+                      : "out4", lll_futex_clobbers);                         \
      __r10 == -1 ? -__r8 : __r8;                                             \
   })
 
                         "=r" (__o0), "=r" (__o1), "=r" (__o2)                \
                       : "i" (0x100000), "2" (__r15), "3" (__o0), "4" (__o1), \
                         "5" (__o2)                                           \
-                      : "out3", lll_futex_clobbers);                         \
+                      : "out3", "out4", lll_futex_clobbers);                 \
      __r10 == -1 ? -__r8 : __r8;                                             \
   })
 
+
+#define lll_futex_requeue(futex, nr_wake, nr_move, mutex) \
+  ({                                                                         \
+     register long int __o0 asm ("out0") = (long int) (futex);               \
+     register long int __o1 asm ("out1") = FUTEX_REQUEUE;                    \
+     register long int __o2 asm ("out2") = (long int) (nr_wake);             \
+     register long int __o3 asm ("out3") = (long int) (nr_move);             \
+     register long int __o4 asm ("out4") = (long int) (mutex);               \
+     register long int __r8 asm ("r8");                                              \
+     register long int __r10 asm ("r10");                                    \
+     register long int __r15 asm ("r15") = SYS_futex;                        \
+                                                                             \
+     __asm __volatile ("break %7;;"                                          \
+                      : "=r" (__r8), "=r" (__r10), "=r" (__r15),             \
+                        "=r" (__o0), "=r" (__o1), "=r" (__o2), "r" (__o3),   \
+                        "=r" (__o4)                                          \
+                      : "i" (0x100000), "2" (__r15), "3" (__o0), "4" (__o1), \
+                        "5" (__o2), "6" (__o3), "7" (__o4)                   \
+                      : lll_futex_clobbers);                                 \
+     __r8;                                                                   \
+  })
+
+
 static inline int
 __attribute__ ((always_inline))
 __lll_mutex_trylock (int *futex)
@@ -111,6 +135,18 @@ __lll_mutex_lock (int *futex)
 #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
 
 
+static inline void
+__attribute__ ((always_inline))
+__lll_mutex_cond_lock (int *futex)
+{
+  int val = atomic_exchange_and_add (futex, 2);
+
+  if (__builtin_expect (val != 0, 0))
+    __lll_lock_wait (futex, val);
+}
+#define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
+
+
 extern int __lll_timedlock_wait (int *futex, int val, const struct timespec *)
      attribute_hidden;
 
@@ -140,7 +176,11 @@ __lll_mutex_unlock (int *futex)
   if (__builtin_expect (val > 1, 0))
     lll_futex_wake (futex, 1);
 }
-#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex))
+#define lll_mutex_unlock(futex) \
+  __lll_mutex_unlock(&(futex))
+
+#define lll_mutex_unlock_force(futex) \
+  lll_futex_wake (&(futex), 1)
 
 #define lll_mutex_islocked(futex) \
   (futex != 0)
index 8e1742b..136dc57 100644 (file)
@@ -102,6 +102,25 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
                              : "0" (1), "2" (futex)                          \
                              : "cx", "r11", "cc", "memory"); })
 
+
+#define lll_mutex_cond_lock(futex) \
+  (void) ({ int ignore1, ignore2;                                            \
+           __asm __volatile (LOCK_INSTR "xaddl %0, %2\n\t"                   \
+                             "testl %0, %0\n\t"                              \
+                             "jne 1f\n\t"                                    \
+                             ".subsection 1\n"                               \
+                             "1:\tleaq %2, %%rdi\n\t"                        \
+                             "subq $128, %%rsp\n\t"                          \
+                             "callq __lll_mutex_lock_wait\n\t"               \
+                             "addq $128, %%rsp\n\t"                          \
+                             "jmp 2f\n\t"                                    \
+                             ".previous\n"                                   \
+                             "2:"                                            \
+                             : "=S" (ignore1), "=&D" (ignore2), "=m" (futex) \
+                             : "0" (2), "2" (futex)                          \
+                             : "cx", "r11", "cc", "memory"); })
+
+
 #define lll_mutex_timedlock(futex, timeout) \
   ({ int result, ignore1, ignore2, ignore3;                                  \
      __asm __volatile (LOCK_INSTR "xaddl %0, %4\n\t"                         \