Define lll_mutex_cond_trylock.
authordrepper <drepper>
Wed, 24 Mar 2004 06:35:18 +0000 (06:35 +0000)
committerdrepper <drepper>
Wed, 24 Mar 2004 06:35:18 +0000 (06:35 +0000)
Define BUSY_WAIT_NOP.

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 a9823d8..b86f11c 100644 (file)
@@ -40,6 +40,7 @@
 /* Initializer for compatibility lock.  */
 #define LLL_MUTEX_LOCK_INITIALIZER             (0)
 #define LLL_MUTEX_LOCK_INITIALIZER_LOCKED      (1)
+#define LLL_MUTEX_LOCK_INITIALIZER_WAITERS     (2)
 
 
 #ifdef PIC
@@ -60,6 +61,9 @@
 # define LLL_ENTER_KERNEL      "int $0x80\n\t"
 #endif
 
+/* Delay in spinlock loop.  */
+#define BUSY_WAIT_NOP          asm ("rep; nop")
+
 
 #define lll_futex_wait(futex, val) \
   do {                                                                       \
@@ -117,6 +121,16 @@ extern int __lll_mutex_unlock_wake (int *__futex)
      ret; })
 
 
+#define lll_mutex_cond_trylock(futex) \
+  ({ int ret;                                                                \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1"                          \
+                      : "=a" (ret), "=m" (futex)                             \
+                      : "r" (LLL_MUTEX_LOCK_INITIALIZER_WAITERS),            \
+                         "m" (futex), "0" (LLL_MUTEX_LOCK_INITIALIZER)       \
+                      : "memory");                                           \
+     ret; })
+
+
 #define lll_mutex_lock(futex) \
   (void) ({ int ignore1, ignore2;                                            \
            __asm __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t"                \
index e462776..6ed21fd 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -31,6 +31,9 @@
 #define FUTEX_WAKE             1
 #define FUTEX_REQUEUE          3
 
+/* Delay in spinlock loop.  */
+#define BUSY_WAIT_NOP          asm ("hint @pause")
+
 /* Initializer for compatibility lock. */
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
 
 #define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex))
 
 
+#define __lll_mutex_cond_trylock(futex) \
+  (atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0)
+#define lll_mutex_cond_trylock(futex) __lll_mutex_cond_trylock (&(futex))
+
+
 extern void __lll_lock_wait (int *futex) attribute_hidden;
 
 
index 156d1f7..ca8d568 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
 /* Initializer for compatibility lock.  */
 #define LLL_MUTEX_LOCK_INITIALIZER             (0)
 #define LLL_MUTEX_LOCK_INITIALIZER_LOCKED      (1)
+#define LLL_MUTEX_LOCK_INITIALIZER_WAITERS     (2)
+
+/* Delay in spinlock loop.  */
+#define BUSY_WAIT_NOP          asm ("rep; nop")
 
 
 #define lll_futex_wait(futex, val) \
@@ -77,9 +81,14 @@ extern int __lll_mutex_timedlock_wait (int *__futex, int __val,
 extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
 
 
+/* NB: in the lll_mutex_trylock macro we simply return the value in %eax
+   after the cmpxchg instruction.  In case the operation succeded this
+   value is zero.  In case the operation failed, the cmpxchg instruction
+   has loaded the current value of the memory work which is guaranteed
+   to be nonzero.  */
 #define lll_mutex_trylock(futex) \
-  ({ unsigned char ret;                                                              \
-     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1; setne %0"                \
+  ({ int ret;                                                                \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1"                          \
                       : "=a" (ret), "=m" (futex)                             \
                       : "r" (LLL_MUTEX_LOCK_INITIALIZER_LOCKED), "m" (futex),\
                         "0" (LLL_MUTEX_LOCK_INITIALIZER)                     \
@@ -87,6 +96,16 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
      ret; })
 
 
+#define lll_mutex_cond_trylock(futex) \
+  ({ int ret;                                                                \
+     __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1"                          \
+                      : "=a" (ret), "=m" (futex)                             \
+                      : "r" (LLL_MUTEX_LOCK_INITIALIZER_WAITERS),            \
+                        "m" (futex), "0" (LLL_MUTEX_LOCK_INITIALIZER)        \
+                      : "memory");                                           \
+     ret; })
+
+
 #define lll_mutex_lock(futex) \
   (void) ({ int ignore1, ignore2, ignore3;                                   \
            __asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t"                \