* 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.
This commit is contained in:
Ulrich Drepper 2004-03-24 06:36:06 +00:00
parent 565699e492
commit 2c0b891afe
31 changed files with 364 additions and 28 deletions

View File

@ -1 +1 @@
NPTL 0.60 by Ulrich Drepper NPTL 0.61 by Ulrich Drepper

View File

@ -1,5 +1,42 @@
2004-03-23 Ulrich Drepper <drepper@redhat.com> 2004-03-23 Ulrich Drepper <drepper@redhat.com>
* 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.
* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
(__lll_mutex_timedlock_wait): Preserve r8 and r9 since the (__lll_mutex_timedlock_wait): Preserve r8 and r9 since the
vgettimeofday call miht destroy the content. vgettimeofday call miht destroy the content.

View File

@ -190,7 +190,7 @@ omit-deps = $(unix-syscalls:%=ptw-%)
tests = tst-attr1 tst-attr2 tst-attr3 \ tests = tst-attr1 tst-attr2 tst-attr3 \
tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
tst-mutex7 tst-mutex8 tst-mutex9 \ tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \
tst-spin1 tst-spin2 tst-spin3 \ tst-spin1 tst-spin2 tst-spin3 \
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \ tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \

View File

@ -31,6 +31,7 @@
#include <fork.h> #include <fork.h>
#include <version.h> #include <version.h>
#include <shlib-compat.h> #include <shlib-compat.h>
#include <smp.h>
#ifndef __NR_set_tid_address #ifndef __NR_set_tid_address
@ -61,6 +62,9 @@ size_t __default_stacksize attribute_hidden;
size_t __static_tls_size; size_t __static_tls_size;
size_t __static_tls_align_m1; size_t __static_tls_align_m1;
/* Flag whether the machine is SMP or not. */
int __is_smp attribute_hidden;
/* Version of the library, used in libthread_db to detect mismatches. */ /* Version of the library, used in libthread_db to detect mismatches. */
static const char nptl_version[] __attribute_used__ = VERSION; static const char nptl_version[] __attribute_used__ = VERSION;
@ -301,6 +305,9 @@ __pthread_initialize_minimal_internal (void)
#endif #endif
__libc_pthread_init (&__fork_generation, __reclaim_stacks, __libc_pthread_init (&__fork_generation, __reclaim_stacks,
ptr_pthread_functions); ptr_pthread_functions);
/* Determine whether the machine is SMP or not. */
__is_smp = is_smp_system ();
} }
strong_alias (__pthread_initialize_minimal_internal, strong_alias (__pthread_initialize_minimal_internal,
__pthread_initialize_minimal) __pthread_initialize_minimal)

View File

@ -45,6 +45,12 @@
#endif #endif
/* Adaptive mutex definitions. */
#ifndef MAX_ADAPTIVE_COUNT
# define MAX_ADAPTIVE_COUNT 100
#endif
/* Internal variables. */ /* Internal variables. */
@ -55,6 +61,9 @@ extern size_t __default_stacksize attribute_hidden;
extern size_t __static_tls_size attribute_hidden; extern size_t __static_tls_size attribute_hidden;
extern size_t __static_tls_align_m1 attribute_hidden; extern size_t __static_tls_align_m1 attribute_hidden;
/* Flag whether the machine is SMP or not. */
extern int __is_smp attribute_hidden;
/* Thread descriptor handling. */ /* Thread descriptor handling. */
extern list_t __stack_user; extern list_t __stack_user;
hidden_proto (__stack_user) hidden_proto (__stack_user)

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -50,6 +50,7 @@ __pthread_mutex_init (mutex, mutexattr)
// mutex->__count = 0; already done by memset // mutex->__count = 0; already done by memset
// mutex->__owner = 0; already done by memset // mutex->__owner = 0; already done by memset
// mutex->__nusers = 0; already done by memset // mutex->__nusers = 0; already done by memset
// mutex->__spins = 0; already done by memset
return 0; return 0;
} }

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -25,6 +25,7 @@
#ifndef LLL_MUTEX_LOCK #ifndef LLL_MUTEX_LOCK
# define LLL_MUTEX_LOCK(mutex) lll_mutex_lock (mutex) # define LLL_MUTEX_LOCK(mutex) lll_mutex_lock (mutex)
# define LLL_MUTEX_TRYLOCK(mutex) lll_mutex_trylock (mutex)
#endif #endif
@ -32,6 +33,8 @@ int
__pthread_mutex_lock (mutex) __pthread_mutex_lock (mutex)
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
{ {
assert (sizeof (mutex->__size) >= sizeof (mutex->__data));
pid_t id = THREAD_GETMEM (THREAD_SELF, tid); pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP)) switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
@ -68,10 +71,37 @@ __pthread_mutex_lock (mutex)
default: default:
/* Correct code cannot set any other type. */ /* Correct code cannot set any other type. */
case PTHREAD_MUTEX_TIMED_NP: case PTHREAD_MUTEX_TIMED_NP:
case PTHREAD_MUTEX_ADAPTIVE_NP: simple:
/* Normal mutex. */ /* Normal mutex. */
LLL_MUTEX_LOCK (mutex->__data.__lock); LLL_MUTEX_LOCK (mutex->__data.__lock);
break; break;
case PTHREAD_MUTEX_ADAPTIVE_NP:
if (! __is_smp)
goto simple;
if (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0)
{
int cnt = 0;
int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
mutex->__data.__spins * 2 + 10);
do
{
if (cnt++ >= max_cnt)
{
LLL_MUTEX_LOCK (mutex->__data.__lock);
break;
}
#ifdef BUSY_WAIT_NOP
BUSY_WAIT_NOP;
#endif
}
while (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0);
mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
}
break;
} }
/* Record the ownership. */ /* Record the ownership. */

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -73,10 +73,37 @@ pthread_mutex_timedlock (mutex, abstime)
default: default:
/* Correct code cannot set any other type. */ /* Correct code cannot set any other type. */
case PTHREAD_MUTEX_TIMED_NP: case PTHREAD_MUTEX_TIMED_NP:
case PTHREAD_MUTEX_ADAPTIVE_NP: simple:
/* Normal mutex. */ /* Normal mutex. */
result = lll_mutex_timedlock (mutex->__data.__lock, abstime); result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
break; break;
case PTHREAD_MUTEX_ADAPTIVE_NP:
if (! __is_smp)
goto simple;
if (lll_mutex_trylock (mutex->__data.__lock) != 0)
{
int cnt = 0;
int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
mutex->__data.__spins * 2 + 10);
do
{
if (cnt++ >= max_cnt)
{
result = lll_mutex_timedlock (mutex->__data.__lock, abstime);
break;
}
#ifdef BUSY_WAIT_NOP
BUSY_WAIT_NOP;
#endif
}
while (lll_mutex_trylock (mutex->__data.__lock) != 0);
mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
}
break;
} }
if (result == 0) if (result == 0)

View File

@ -1,5 +1,5 @@
/* Machine-specific pthread type layouts. Alpha version. /* 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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 /* KIND must stay at this position in the structure to maintain
binary compatibility. */ binary compatibility. */
int __kind; int __kind;
int __spins;
} __data; } __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T]; char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align; long int __align;

View 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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)) #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; extern void __lll_lock_wait (int *futex) attribute_hidden;
static inline void __attribute__((always_inline)) static inline void __attribute__((always_inline))

View 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -56,6 +56,7 @@ typedef union
binary compatibility. */ binary compatibility. */
int __kind; int __kind;
unsigned int __nusers; unsigned int __nusers;
int __spins;
} __data; } __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T]; char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align; long int __align;

View File

@ -40,6 +40,7 @@
/* Initializer for compatibility lock. */ /* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0) #define LLL_MUTEX_LOCK_INITIALIZER (0)
#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1) #define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1)
#define LLL_MUTEX_LOCK_INITIALIZER_WAITERS (2)
#ifdef PIC #ifdef PIC
@ -60,6 +61,9 @@
# define LLL_ENTER_KERNEL "int $0x80\n\t" # define LLL_ENTER_KERNEL "int $0x80\n\t"
#endif #endif
/* Delay in spinlock loop. */
#define BUSY_WAIT_NOP asm ("rep; nop")
#define lll_futex_wait(futex, val) \ #define lll_futex_wait(futex, val) \
do { \ do { \
@ -117,6 +121,16 @@ extern int __lll_mutex_unlock_wake (int *__futex)
ret; }) 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) \ #define lll_mutex_lock(futex) \
(void) ({ int ignore1, ignore2; \ (void) ({ int ignore1, ignore2; \
__asm __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t" \ __asm __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t" \

View 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. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -56,6 +56,7 @@ typedef union
/* KIND must stay at this position in the structure to maintain /* KIND must stay at this position in the structure to maintain
binary compatibility. */ binary compatibility. */
int __kind; int __kind;
int __spins;
} __data; } __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T]; char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align; long int __align;

View 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. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -31,6 +31,9 @@
#define FUTEX_WAKE 1 #define FUTEX_WAKE 1
#define FUTEX_REQUEUE 3 #define FUTEX_REQUEUE 3
/* Delay in spinlock loop. */
#define BUSY_WAIT_NOP asm ("hint @pause")
/* Initializer for compatibility lock. */ /* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0) #define LLL_MUTEX_LOCK_INITIALIZER (0)
@ -62,6 +65,11 @@
#define lll_mutex_trylock(futex) __lll_mutex_trylock (&(futex)) #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; extern void __lll_lock_wait (int *futex) attribute_hidden;

View File

@ -1,5 +1,5 @@
/* Machine-specific pthread type layouts. PowerPC version. /* 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. This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003. Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
@ -76,6 +76,7 @@ typedef union
#if __WORDSIZE != 64 #if __WORDSIZE != 64
unsigned int __nusers; unsigned int __nusers;
#endif #endif
int __spins;
} __data; } __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T]; char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align; long int __align;

View 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. This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003. Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
@ -100,6 +100,21 @@
#define lll_mutex_trylock(lock) __lll_trylock (&(lock)) #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; extern void __lll_lock_wait (int *futex) attribute_hidden;

View File

@ -1,6 +1,7 @@
#include <pthreadP.h> #include <pthreadP.h>
#define LLL_MUTEX_LOCK(mutex) lll_mutex_cond_lock(mutex) #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 __pthread_mutex_lock __pthread_mutex_cond_lock
#define NO_INCR #define NO_INCR

View 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. This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@ -75,6 +75,7 @@ typedef union
#if __WORDSIZE != 64 #if __WORDSIZE != 64
unsigned int __nusers; unsigned int __nusers;
#endif #endif
int __spins;
} __data; } __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T]; char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align; long int __align;

View 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. This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@ -127,6 +127,20 @@ __lll_mutex_trylock (int *futex)
#define lll_mutex_trylock(futex) __lll_mutex_trylock (&(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; extern void __lll_lock_wait (int *futex) attribute_hidden;
static inline void static inline void

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -57,6 +57,7 @@ typedef union
binary compatibility. */ binary compatibility. */
int __kind; int __kind;
unsigned int __nusers; unsigned int __nusers;
int __spins;
} __data; } __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T]; char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align; long int __align;

View 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -31,6 +31,7 @@
/* Initializer for compatibility lock. */ /* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0) #define LLL_MUTEX_LOCK_INITIALIZER (0)
#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1) #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_lock_wait (int val, int *__futex) attribute_hidden;
extern int __lll_mutex_timedlock_wait (int val, int *__futex, 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"); \ : "r0", "r1", "r2", "t", "memory"); \
__result; }) __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) \ #define lll_mutex_lock(futex) \
(void) ({ int __result, val, *__futex = &(futex); \ (void) ({ int __result, val, *__futex = &(futex); \
__asm __volatile ("\ __asm __volatile ("\

View File

@ -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;
}

View File

@ -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 <fcntl.h>
#include <string.h>
#include <sys/sysctl.h>
/* 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;
}

View File

@ -1,5 +1,5 @@
/* Machine-specific pthread type layouts. SPARC version. /* 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. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -76,6 +76,7 @@ typedef union
#if __WORDSIZE != 64 #if __WORDSIZE != 64
unsigned int __nusers; unsigned int __nusers;
#endif #endif
int __spins;
} __data; } __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T]; char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align; long int __align;

View 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. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -86,6 +86,14 @@ __lll_mutex_trylock (int *futex)
} }
#define lll_mutex_trylock(futex) __lll_mutex_trylock (&(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; 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 val = atomic_compare_and_exchange_val_acq (futex, 1, 0);
int result = 0; int result = 0;
if (__builtin_expect (val != 0, 0)) if (__builtin_expect (val != 0, 0))
result = __lll_timedlock_wait (futex, abstime); result = __lll_timedlock_wait (futex, abstime);
return result; return result;

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -56,6 +56,7 @@ typedef union
/* KIND must stay at this position in the structure to maintain /* KIND must stay at this position in the structure to maintain
binary compatibility. */ binary compatibility. */
int __kind; int __kind;
int __spins;
} __data; } __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T]; char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align; long int __align;

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -40,6 +40,10 @@
/* Initializer for compatibility lock. */ /* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0) #define LLL_MUTEX_LOCK_INITIALIZER (0)
#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1) #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) \ #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; 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) \ #define lll_mutex_trylock(futex) \
({ unsigned char ret; \ ({ int ret; \
__asm __volatile (LOCK_INSTR "cmpxchgl %2, %1; setne %0" \ __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
: "=a" (ret), "=m" (futex) \ : "=a" (ret), "=m" (futex) \
: "r" (LLL_MUTEX_LOCK_INITIALIZER_LOCKED), "m" (futex),\ : "r" (LLL_MUTEX_LOCK_INITIALIZER_LOCKED), "m" (futex),\
"0" (LLL_MUTEX_LOCK_INITIALIZER) \ "0" (LLL_MUTEX_LOCK_INITIALIZER) \
@ -87,6 +96,16 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
ret; }) 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) \ #define lll_mutex_lock(futex) \
(void) ({ int ignore1, ignore2, ignore3; \ (void) ({ int ignore1, ignore2, ignore3; \
__asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t" \ __asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t" \

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -25,6 +25,11 @@
#include <sys/time.h> #include <sys/time.h>
#ifndef TYPE
# define TYPE PTHREAD_MUTEX_NORMAL
#endif
static int static int
do_test (void) do_test (void)
{ {
@ -33,13 +38,32 @@ do_test (void)
struct timeval tv; struct timeval tv;
struct timeval tv2; struct timeval tv2;
int err; int err;
pthread_mutexattr_t a;
if (pthread_mutex_init (&m, NULL) != 0) if (pthread_mutexattr_init (&a) != 0)
{
puts ("mutexattr_init failed");
return 1;
}
if (pthread_mutexattr_settype (&a, TYPE) != 0)
{
puts ("mutexattr_settype failed");
return 1;
}
if (pthread_mutex_init (&m, &a) != 0)
{ {
puts ("mutex_init failed"); puts ("mutex_init failed");
return 1; return 1;
} }
if (pthread_mutexattr_destroy (&a) != 0)
{
puts ("mutexattr_destroy failed");
return 1;
}
if (pthread_mutex_lock (&m) != 0) if (pthread_mutex_lock (&m) != 0)
{ {
puts ("mutex_lock failed"); puts ("mutex_lock failed");

2
nptl/tst-mutex5a.c Normal file
View File

@ -0,0 +1,2 @@
#define TYPE PTHREAD_MUTEX_ADAPTIVE_NP
#include "tst-mutex5.c"

View File

@ -22,7 +22,12 @@
#include <time.h> #include <time.h>
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; #ifndef INIT
# define INIT PTHREAD_MUTEX_INITIALIZER
#endif
static pthread_mutex_t lock = INIT;
#define ROUNDS 1000 #define ROUNDS 1000

2
nptl/tst-mutex7a.c Normal file
View File

@ -0,0 +1,2 @@
#define INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
#include "tst-mutex7.c"