From 2c0b891afe29dd28d0e6d75e0da8681db7fd100d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 24 Mar 2004 06:36:06 +0000 Subject: Update. * sysdeps/unix/sysv/linux/smp.h: New file. * sysdeps/unix/sysv/linux/sh/smp.h: New file. * init.c: Define __is_smp. (__pthread_initialize_minimal_internal): Call is_smp_system to initialize __is_smp. * pthreadP.h: Declare __is_smp. Define MAX_ADAPTIVE_COUNT is necessary. * pthread_mutex_init.c: Add comment regarding __spins field. * pthread_mutex_lock.c: Implement adaptive mutex type. * pthread_mutex_timedlock.c: Likewise. * sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c: Likewise. * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h (pthread_mutex_t): Add __spins field. * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h: Define lll_mutex_cond_trylock. * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise. Define BUSY_WAIT_NOP. * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise. * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Likewise. * tst-mutex5.c: Add support for testing adaptive mutexes. * tst-mutex7.c: Likewise. * tst-mutex5a.c: New file. * tst-mutex7a.c: New file. * Makefile (tests): Add tst-mutex5a and tst-mutex7a. --- .../unix/sysv/linux/alpha/bits/pthreadtypes.h | 3 +- nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h | 10 ++++- .../unix/sysv/linux/i386/bits/pthreadtypes.h | 3 +- nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h | 14 ++++++ .../unix/sysv/linux/ia64/bits/pthreadtypes.h | 3 +- nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h | 10 ++++- .../unix/sysv/linux/powerpc/bits/pthreadtypes.h | 3 +- .../sysdeps/unix/sysv/linux/powerpc/lowlevellock.h | 17 +++++++- .../unix/sysv/linux/pthread_mutex_cond_lock.c | 1 + .../unix/sysv/linux/s390/bits/pthreadtypes.h | 3 +- nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h | 16 ++++++- .../sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h | 3 +- nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h | 25 ++++++++++- nptl/sysdeps/unix/sysv/linux/sh/smp.h | 24 +++++++++++ nptl/sysdeps/unix/sysv/linux/smp.h | 50 ++++++++++++++++++++++ .../unix/sysv/linux/sparc/bits/pthreadtypes.h | 3 +- nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h | 12 +++++- .../unix/sysv/linux/x86_64/bits/pthreadtypes.h | 3 +- nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h | 25 +++++++++-- 19 files changed, 210 insertions(+), 18 deletions(-) create mode 100644 nptl/sysdeps/unix/sysv/linux/sh/smp.h create mode 100644 nptl/sysdeps/unix/sysv/linux/smp.h (limited to 'nptl/sysdeps/unix/sysv') diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h index 2d8a00b93f..0fed5cc918 100644 --- a/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h @@ -1,5 +1,5 @@ /* Machine-specific pthread type layouts. Alpha version. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -56,6 +56,7 @@ typedef union /* KIND must stay at this position in the structure to maintain binary compatibility. */ int __kind; + int __spins; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h index 9d125e0d6d..a7079a8490 100644 --- a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h @@ -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. The GNU C Library is free software; you can redistribute it and/or @@ -80,6 +80,14 @@ __lll_mutex_trylock(int *futex) #define lll_mutex_trylock(lock) __lll_mutex_trylock (&(lock)) +static inline int __attribute__((always_inline)) +__lll_mutex_cond_trylock(int *futex) +{ + return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0; +} +#define lll_mutex_cond_trylock(lock) __lll_mutex_cond_trylock (&(lock)) + + extern void __lll_lock_wait (int *futex) attribute_hidden; static inline void __attribute__((always_inline)) diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h index fc0a54c036..f998138d7e 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h @@ -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. The GNU C Library is free software; you can redistribute it and/or @@ -56,6 +56,7 @@ typedef union binary compatibility. */ int __kind; unsigned int __nusers; + int __spins; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h index a9823d8d4b..b86f11c9b4 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h @@ -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" \ diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h index 6cd6c05705..e4c15d1e20 100644 --- a/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h @@ -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 , 2003. @@ -56,6 +56,7 @@ typedef union /* KIND must stay at this position in the structure to maintain binary compatibility. */ int __kind; + int __spins; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h index e462776c02..6ed21fdc14 100644 --- a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h @@ -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 , 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) @@ -62,6 +65,11 @@ #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; diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h index 2d98a80e36..d6d94cda24 100644 --- a/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h @@ -1,5 +1,5 @@ /* Machine-specific pthread type layouts. PowerPC version. - 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 Paul Mackerras , 2003. @@ -76,6 +76,7 @@ typedef union #if __WORDSIZE != 64 unsigned int __nusers; #endif + int __spins; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h index a715879dbd..e9f895d6e8 100644 --- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h @@ -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 Paul Mackerras , 2003. @@ -100,6 +100,21 @@ #define lll_mutex_trylock(lock) __lll_trylock (&(lock)) +/* Set *futex to 2 if it is 0, atomically. Returns the old value */ +#define lll_mutex_cond_trylock(futex) \ + ({ int __val; \ + __asm __volatile ("1: lwarx %0,0,%2\n" \ + " cmpwi 0,%0,0\n" \ + " bne 2f\n" \ + " stwcx. %3,0,%2\n" \ + " bne- 1b\n" \ + "2: " __lll_acq_instr \ + : "=&r" (__val), "=m" (*futex) \ + : "r" (futex), "r" (2), "1" (*futex) \ + : "cr0", "memory"); \ + __val; \ + }) + extern void __lll_lock_wait (int *futex) attribute_hidden; diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c b/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c index d253c72ea4..990db87416 100644 --- a/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c +++ b/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c @@ -1,6 +1,7 @@ #include #define LLL_MUTEX_LOCK(mutex) lll_mutex_cond_lock(mutex) +#define LLL_MUTEX_TRYLOCK(mutex) lll_mutex_cond_trylock(mutex) #define __pthread_mutex_lock __pthread_mutex_cond_lock #define NO_INCR diff --git a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h index 022ba4982b..e2606aff8e 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h @@ -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 Martin Schwidefsky , 2003. @@ -75,6 +75,7 @@ typedef union #if __WORDSIZE != 64 unsigned int __nusers; #endif + int __spins; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h index 5751206dd9..8b460eb98f 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h @@ -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 Martin Schwidefsky , 2003. @@ -127,6 +127,20 @@ __lll_mutex_trylock (int *futex) #define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex)) +static inline int +__attribute__ ((always_inline)) +__lll_mutex_cond_trylock (int *futex) +{ + unsigned int old; + + __asm __volatile ("cs %0,%3,%1" + : "=d" (old), "=Q" (*futex) + : "0" (0), "d" (2), "m" (*futex) : "cc" ); + return old != 0; +} +#define lll_mutex_cond_trylock(futex) __lll_mutex_cond_trylock (&(futex)) + + extern void __lll_lock_wait (int *futex) attribute_hidden; static inline void diff --git a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h index 3cd84864f4..7d05908778 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h @@ -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 , 2002. @@ -57,6 +57,7 @@ typedef union binary compatibility. */ int __kind; unsigned int __nusers; + int __spins; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h index 37842263b6..00ff1b20fb 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h @@ -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. The GNU C Library is free software; you can redistribute it and/or @@ -31,6 +31,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) extern int __lll_mutex_lock_wait (int val, int *__futex) attribute_hidden; extern int __lll_mutex_timedlock_wait (int val, int *__futex, @@ -61,6 +62,28 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden; : "r0", "r1", "r2", "t", "memory"); \ __result; }) +#define lll_mutex_cond_trylock(futex) \ + ({ unsigned char __result; \ + __asm __volatile ("\ + .align 2\n\ + mova 1f,r0\n\ + nop\n\ + mov r15,r1\n\ + mov #-8,r15\n\ + 0: mov.l @%1,r2\n\ + cmp/eq r2,%3\n\ + bf 1f\n\ + mov.l %2,@%1\n\ + 1: mov r1,r15\n\ + mov #-1,%0\n\ + negc %0,%0"\ + : "=r" (__result) \ + : "r" (&(futex)), \ + "r" (LLL_MUTEX_LOCK_INITIALIZER_WAITERS), \ + "r" (LLL_MUTEX_LOCK_INITIALIZER) \ + : "r0", "r1", "r2", "t", "memory"); \ + __result; }) + #define lll_mutex_lock(futex) \ (void) ({ int __result, val, *__futex = &(futex); \ __asm __volatile ("\ diff --git a/nptl/sysdeps/unix/sysv/linux/sh/smp.h b/nptl/sysdeps/unix/sysv/linux/sh/smp.h new file mode 100644 index 0000000000..2c0cbe99ac --- /dev/null +++ b/nptl/sysdeps/unix/sysv/linux/sh/smp.h @@ -0,0 +1,24 @@ +/* Determine whether the host has multiple processors. SH version. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +static inline int +is_smp_system (void) +{ + return 0; +} diff --git a/nptl/sysdeps/unix/sysv/linux/smp.h b/nptl/sysdeps/unix/sysv/linux/smp.h new file mode 100644 index 0000000000..718fab683b --- /dev/null +++ b/nptl/sysdeps/unix/sysv/linux/smp.h @@ -0,0 +1,50 @@ +/* Determine whether the host has multiple processors. Linux version. + Copyright (C) 1996, 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include + +/* Test whether the machine has more than one processor. This is not the + best test but good enough. More complicated tests would require `malloc' + which is not available at that time. */ +static inline int +is_smp_system (void) +{ + static const int sysctl_args[] = { CTL_KERN, KERN_VERSION }; + char buf[512]; + size_t reslen = sizeof (buf); + + /* Try reading the number using `sysctl' first. */ + if (__sysctl ((int *) sysctl_args, + sizeof (sysctl_args) / sizeof (sysctl_args[0]), + buf, &reslen, NULL, 0) < 0) + { + /* This was not successful. Now try reading the /proc filesystem. */ + int fd = __open ("/proc/sys/kernel/version", O_RDONLY); + if (__builtin_expect (fd, 0) == -1 + || (reslen = __read (fd, buf, sizeof (buf))) <= 0) + /* This also didn't work. We give up and say it's a UP machine. */ + buf[0] = '\0'; + + __close (fd); + } + + return strstr (buf, "SMP") != NULL; +} diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h index b947439e34..d123fd059f 100644 --- a/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h @@ -1,5 +1,5 @@ /* Machine-specific pthread type layouts. SPARC version. - 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 , 2003. @@ -76,6 +76,7 @@ typedef union #if __WORDSIZE != 64 unsigned int __nusers; #endif + int __spins; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h index 76ec431a6c..05bc5a2974 100644 --- a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h @@ -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 , 2003. @@ -86,6 +86,14 @@ __lll_mutex_trylock (int *futex) } #define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex)) +static inline int +__attribute__ ((always_inline)) +__lll_mutex_cond_trylock (int *futex) +{ + return 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; @@ -124,7 +132,7 @@ __lll_mutex_timedlock (int *futex, const struct timespec *abstime) { int val = atomic_compare_and_exchange_val_acq (futex, 1, 0); int result = 0; - + if (__builtin_expect (val != 0, 0)) result = __lll_timedlock_wait (futex, abstime); return result; diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h index 3f151d04ed..1b4820eb0c 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h @@ -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 , 2002. @@ -56,6 +56,7 @@ typedef union /* KIND must stay at this position in the structure to maintain binary compatibility. */ int __kind; + int __spins; } __data; char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align; diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h index 156d1f7c64..ca8d568038 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h @@ -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 , 2002. @@ -40,6 +40,10 @@ /* 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" \ -- cgit 1.4.1