* sysdeps/mips/nptl/tls.h (THREAD_GSCOPE_RESET_FLAG): Pass

LLL_PRIVATE argument to lll_futex_wake.
	* sysdeps/unix/sysv/linux/mips/bits/fcntl.h (O_CLOEXEC): Define.
	* sysdeps/unix/sysv/linux/mips/bits/socket.h (PF_UNIX): Update
	comment.
	(PF_IUCV, PF_RXRPC): Define.
	(PF_MAX): Update.
	(AF_IUCV, AF_RXRPC): Define.
	(MSG_CMSG_CLOEXEC): Define.
	(_EXTERN_INLINE): Define to __extern_inline.
	* sysdeps/unix/sysv/linux/mips/bits/stat.h (UTIME_NOW,
	UTIME_OMIT): Define.
	* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h: Include <tls.h>.
	* sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h: Renamed all
	lll_mutex_* resp. lll_robust_mutex_* macros to lll_*
	resp. lll_robust_*.  Renamed all LLL_MUTEX_LOCK_* macros to
	LLL_LOCK_*.  Include <kernel-features.h>.
	(LLL_LOCK_INITIALIZER): Remove duplicate definition.
	(LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
	* sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c
	(clear_once_control, __pthread_once): Pass LLL_PRIVATE argument to
	lll_futex_wait.
	(lll_futex_wait, lll_futex_timed_wait, lll_futex_wake,
	lll_robust_dead, lll_futex_requeue, lll_futex_wake_unlock): Take
	private arguments.
	(__lll_robust_trylock): Convert to macro.
	(__lll_robust_lock_wait): Add private argument.
	(__lll_lock_wait_private, __lll_lock_wait): Declare.
	(__lll_lock): Convert to macro.  Take private argument.
	(__lll_cond_lock): Likewise.
	(lll_lock, lll_cond_lock): Take private arguments.
	(__lll_robust_lock): Take private argument.  Convert to macro.
	(lll_robust_lock, __lll_cond_lock, lll_cond_lock,
	lll_robust_cond_lock): Take private arguments.
	(__lll_timedlock_wait, __lll_robust_timedlock_wait): Take private
	arguments.
	(__lll_timedlock, __lll_robust_timedlock): Take private arguments.
	(lll_timedlock, lll_robust_timedlock): Take private arguments.
	(__lll_unlock, __lll_robust_unlock): Convert to macros.  Take
	private arguments.
	(lll_unlock, lll_robust_unlock): Take private arguments.
	(__lll_mutex_unlock_force, lll_mutex_unlock_force, lll_lock_t,
	lll_trylock, lll_lock, lll_unlock, lll_islocked): Remove.
	(lll_wait_tid): Pass LLL_SHARED to lll_futex_wait.
	(__lll_cond_wait, __lll_cond_timedwait, __lll_cond_wake,
	__lll_cond_broadcast, lll_cond_wait, lll_cond_timedwait,
	lll_cond_wake, lll_cond_broadcast): Remove.
	* sysdeps/unix/sysv/linux/mips/sys/tas.h (_EXTERN_INLINE): Define
	to __extern_inline.
This commit is contained in:
Daniel Jacobowitz 2007-09-12 12:57:41 +00:00
parent 713ddf8d12
commit 8c2766740d
11 changed files with 220 additions and 147 deletions

View File

@ -1,3 +1,57 @@
2007-09-12 Joseph Myers <joseph@codesourcery.com>
* sysdeps/mips/nptl/tls.h (THREAD_GSCOPE_RESET_FLAG): Pass
LLL_PRIVATE argument to lll_futex_wake.
* sysdeps/unix/sysv/linux/mips/bits/fcntl.h (O_CLOEXEC): Define.
* sysdeps/unix/sysv/linux/mips/bits/socket.h (PF_UNIX): Update
comment.
(PF_IUCV, PF_RXRPC): Define.
(PF_MAX): Update.
(AF_IUCV, AF_RXRPC): Define.
(MSG_CMSG_CLOEXEC): Define.
(_EXTERN_INLINE): Define to __extern_inline.
* sysdeps/unix/sysv/linux/mips/bits/stat.h (UTIME_NOW,
UTIME_OMIT): Define.
* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h: Include <tls.h>.
* sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h: Renamed all
lll_mutex_* resp. lll_robust_mutex_* macros to lll_*
resp. lll_robust_*. Renamed all LLL_MUTEX_LOCK_* macros to
LLL_LOCK_*. Include <kernel-features.h>.
(LLL_LOCK_INITIALIZER): Remove duplicate definition.
(LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
* sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c
(clear_once_control, __pthread_once): Pass LLL_PRIVATE argument to
lll_futex_wait.
(lll_futex_wait, lll_futex_timed_wait, lll_futex_wake,
lll_robust_dead, lll_futex_requeue, lll_futex_wake_unlock): Take
private arguments.
(__lll_robust_trylock): Convert to macro.
(__lll_robust_lock_wait): Add private argument.
(__lll_lock_wait_private, __lll_lock_wait): Declare.
(__lll_lock): Convert to macro. Take private argument.
(__lll_cond_lock): Likewise.
(lll_lock, lll_cond_lock): Take private arguments.
(__lll_robust_lock): Take private argument. Convert to macro.
(lll_robust_lock, __lll_cond_lock, lll_cond_lock,
lll_robust_cond_lock): Take private arguments.
(__lll_timedlock_wait, __lll_robust_timedlock_wait): Take private
arguments.
(__lll_timedlock, __lll_robust_timedlock): Take private arguments.
(lll_timedlock, lll_robust_timedlock): Take private arguments.
(__lll_unlock, __lll_robust_unlock): Convert to macros. Take
private arguments.
(lll_unlock, lll_robust_unlock): Take private arguments.
(__lll_mutex_unlock_force, lll_mutex_unlock_force, lll_lock_t,
lll_trylock, lll_lock, lll_unlock, lll_islocked): Remove.
(lll_wait_tid): Pass LLL_SHARED to lll_futex_wait.
(__lll_cond_wait, __lll_cond_timedwait, __lll_cond_wake,
__lll_cond_broadcast, lll_cond_wait, lll_cond_timedwait,
lll_cond_wake, lll_cond_broadcast): Remove.
* sysdeps/unix/sysv/linux/mips/sys/tas.h (_EXTERN_INLINE): Define
to __extern_inline.
2007-08-06 Maciej W. Rozycki <macro@linux-mips.org> 2007-08-06 Maciej W. Rozycki <macro@linux-mips.org>
* sysdeps/unix/sysv/linux/mips/dl-cache.h (_DL_CACHE_DEFAULT_ID): * sysdeps/unix/sysv/linux/mips/dl-cache.h (_DL_CACHE_DEFAULT_ID):

View File

@ -166,7 +166,7 @@ typedef struct
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \ THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \ if (__res == THREAD_GSCOPE_FLAG_WAIT) \
lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \ } \
while (0) while (0)
#define THREAD_GSCOPE_SET_FLAG() \ #define THREAD_GSCOPE_SET_FLAG() \

View File

@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux. /* O_*, F_*, FD_* bit values for Linux.
Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2006 Copyright (C) 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2006, 2007
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
@ -51,6 +51,7 @@
# define O_DIRECT 0x8000 /* Direct disk access hint. */ # define O_DIRECT 0x8000 /* Direct disk access hint. */
# define O_DIRECTORY 0x10000 /* Must be a directory. */ # define O_DIRECTORY 0x10000 /* Must be a directory. */
# define O_NOATIME 0x40000 /* Do not set atime. */ # define O_NOATIME 0x40000 /* Do not set atime. */
# define O_CLOEXEC 02000000 /* Set close_on_exec. */
#endif #endif
/* For now Linux has no synchronisity options for data and read operations. /* For now Linux has no synchronisity options for data and read operations.

View File

@ -1,5 +1,5 @@
/* System-specific socket constants and types. Linux/MIPS version. /* System-specific socket constants and types. Linux/MIPS version.
Copyright (C) 1991, 92, 1994-1999, 2000, 2001, 2004, 2005, 2006 Copyright (C) 1991, 92, 1994-1999, 2000, 2001, 2004, 2005, 2006, 2007
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
@ -63,7 +63,7 @@ enum __socket_type
/* Protocol families. */ /* Protocol families. */
#define PF_UNSPEC 0 /* Unspecified. */ #define PF_UNSPEC 0 /* Unspecified. */
#define PF_LOCAL 1 /* Local to host (pipes and file-domain). */ #define PF_LOCAL 1 /* Local to host (pipes and file-domain). */
#define PF_UNIX PF_LOCAL /* Old BSD name for PF_LOCAL. */ #define PF_UNIX PF_LOCAL /* POSIX name for PF_LOCAL. */
#define PF_FILE PF_LOCAL /* Another non-standard name for PF_LOCAL. */ #define PF_FILE PF_LOCAL /* Another non-standard name for PF_LOCAL. */
#define PF_INET 2 /* IP protocol family. */ #define PF_INET 2 /* IP protocol family. */
#define PF_AX25 3 /* Amateur Radio AX.25. */ #define PF_AX25 3 /* Amateur Radio AX.25. */
@ -90,7 +90,9 @@ enum __socket_type
#define PF_PPPOX 24 /* PPPoX sockets. */ #define PF_PPPOX 24 /* PPPoX sockets. */
#define PF_WANPIPE 25 /* Wanpipe API sockets. */ #define PF_WANPIPE 25 /* Wanpipe API sockets. */
#define PF_BLUETOOTH 31 /* Bluetooth sockets. */ #define PF_BLUETOOTH 31 /* Bluetooth sockets. */
#define PF_MAX 32 /* For now.. */ #define PF_IUCV 32 /* IUCV sockets. */
#define PF_RXRPC 33 /* RxRPC sockets. */
#define PF_MAX 34 /* For now.. */
/* Address families. */ /* Address families. */
#define AF_UNSPEC PF_UNSPEC #define AF_UNSPEC PF_UNSPEC
@ -122,6 +124,8 @@ enum __socket_type
#define AF_PPPOX PF_PPPOX #define AF_PPPOX PF_PPPOX
#define AF_WANPIPE PF_WANPIPE #define AF_WANPIPE PF_WANPIPE
#define AF_BLUETOOTH PF_BLUETOOTH #define AF_BLUETOOTH PF_BLUETOOTH
#define AF_IUCV PF_IUCV
#define AF_RXRPC PF_RXRPC
#define AF_MAX PF_MAX #define AF_MAX PF_MAX
/* Socket level values. Others are defined in the appropriate headers. /* Socket level values. Others are defined in the appropriate headers.
@ -206,8 +210,13 @@ enum
#define MSG_ERRQUEUE MSG_ERRQUEUE #define MSG_ERRQUEUE MSG_ERRQUEUE
MSG_NOSIGNAL = 0x4000, /* Do not generate SIGPIPE. */ MSG_NOSIGNAL = 0x4000, /* Do not generate SIGPIPE. */
#define MSG_NOSIGNAL MSG_NOSIGNAL #define MSG_NOSIGNAL MSG_NOSIGNAL
MSG_MORE = 0x8000 /* Sender will send more. */ MSG_MORE = 0x8000, /* Sender will send more. */
#define MSG_MORE MSG_MORE #define MSG_MORE MSG_MORE
MSG_CMSG_CLOEXEC = 0x40000000 /* Set close_on_exit for file
descriptor received through
SCM_RIGHTS. */
#define MSG_CMSG_CLOEXEC MSG_CMSG_CLOEXEC
}; };
@ -259,7 +268,7 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
struct cmsghdr *__cmsg) __THROW; struct cmsghdr *__cmsg) __THROW;
#ifdef __USE_EXTERN_INLINES #ifdef __USE_EXTERN_INLINES
# ifndef _EXTERN_INLINE # ifndef _EXTERN_INLINE
# define _EXTERN_INLINE extern __inline # define _EXTERN_INLINE __extern_inline
# endif # endif
_EXTERN_INLINE struct cmsghdr * _EXTERN_INLINE struct cmsghdr *
__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))

View File

@ -1,5 +1,5 @@
/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 /* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004,
Free Software Foundation, Inc. 2007 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
@ -253,3 +253,9 @@ struct stat64
#define __S_IREAD 0400 /* Read by owner. */ #define __S_IREAD 0400 /* Read by owner. */
#define __S_IWRITE 0200 /* Write by owner. */ #define __S_IWRITE 0200 /* Write by owner. */
#define __S_IEXEC 0100 /* Execute by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */
#if defined __USE_ATFILE || defined __USE_GNU
/* XXX This will change to the macro for the next 2008 POSIX revision. */
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#endif

View File

@ -22,6 +22,8 @@
/* There is some commonality. */ /* There is some commonality. */
#include <sysdeps/unix/mips/mips32/sysdep.h> #include <sysdeps/unix/mips/mips32/sysdep.h>
#include <tls.h>
/* For Linux we can use the system call table in the header file /* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h /usr/include/asm/unistd.h
of the kernel. But these symbols do not follow the SYS_* syntax of the kernel. But these symbols do not follow the SYS_* syntax

View File

@ -23,6 +23,8 @@
/* There is some commonality. */ /* There is some commonality. */
#include <sysdeps/unix/mips/mips64/n32/sysdep.h> #include <sysdeps/unix/mips/mips64/n32/sysdep.h>
#include <tls.h>
/* For Linux we can use the system call table in the header file /* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h /usr/include/asm/unistd.h
of the kernel. But these symbols do not follow the SYS_* syntax of the kernel. But these symbols do not follow the SYS_* syntax

View File

@ -23,6 +23,8 @@
/* There is some commonality. */ /* There is some commonality. */
#include <sysdeps/unix/mips/mips64/n64/sysdep.h> #include <sysdeps/unix/mips/mips64/n64/sysdep.h>
#include <tls.h>
/* For Linux we can use the system call table in the header file /* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h /usr/include/asm/unistd.h
of the kernel. But these symbols do not follow the SYS_* syntax of the kernel. But these symbols do not follow the SYS_* syntax

View File

@ -24,7 +24,7 @@
#include <bits/pthreadtypes.h> #include <bits/pthreadtypes.h>
#include <atomic.h> #include <atomic.h>
#include <sysdep.h> #include <sysdep.h>
#include <kernel-features.h>
#define FUTEX_WAIT 0 #define FUTEX_WAIT 0
#define FUTEX_WAKE 1 #define FUTEX_WAKE 1
@ -37,200 +37,224 @@
#define FUTEX_TRYLOCK_PI 8 #define FUTEX_TRYLOCK_PI 8
#define FUTEX_PRIVATE_FLAG 128 #define FUTEX_PRIVATE_FLAG 128
/* Initializer for compatibility lock. */ /* Values for 'private' parameter of locking macros. Yes, the
#define LLL_MUTEX_LOCK_INITIALIZER (0) definition seems to be backwards. But it is not. The bit will be
reversed before passing to the system call. */
#define LLL_PRIVATE 0
#define LLL_SHARED FUTEX_PRIVATE_FLAG
#define lll_futex_wait(futexp, val) \
#if !defined NOT_IN_libc || defined IS_IN_rtld
/* In libc.so or ld.so all futexes are private. */
# ifdef __ASSUME_PRIVATE_FUTEX
# define __lll_private_flag(fl, private) \
((fl) | FUTEX_PRIVATE_FLAG)
# else
# define __lll_private_flag(fl, private) \
((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
# endif
#else
# ifdef __ASSUME_PRIVATE_FUTEX
# define __lll_private_flag(fl, private) \
(((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
# else
# define __lll_private_flag(fl, private) \
(__builtin_constant_p (private) \
? ((private) == 0 \
? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
: (fl)) \
: ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
& THREAD_GETMEM (THREAD_SELF, header.private_futex))))
# endif
#endif
#define lll_futex_wait(futexp, val, private) \
lll_futex_timed_wait(futexp, val, NULL, private)
#define lll_futex_timed_wait(futexp, val, timespec, private) \
({ \ ({ \
INTERNAL_SYSCALL_DECL (__err); \ INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \ long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \ __ret = INTERNAL_SYSCALL (futex, __err, 4, (long) (futexp), \
(long) (futexp), FUTEX_WAIT, (val), 0); \ __lll_private_flag (FUTEX_WAIT, private), \
(val), (timespec)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
}) })
#define lll_futex_timed_wait(futexp, val, timespec) \ #define lll_futex_wake(futexp, nr, private) \
({ \ ({ \
INTERNAL_SYSCALL_DECL (__err); \ INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \ long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \ __ret = INTERNAL_SYSCALL (futex, __err, 4, (long) (futexp), \
(long) (futexp), FUTEX_WAIT, (val), (timespec));\ __lll_private_flag (FUTEX_WAKE, private), \
(nr), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
}) })
#define lll_futex_wake(futexp, nr) \ #define lll_robust_dead(futexv, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(long) (futexp), FUTEX_WAKE, (nr), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
#define lll_robust_mutex_dead(futexv) \
do \ do \
{ \ { \
int *__futexp = &(futexv); \ int *__futexp = &(futexv); \
atomic_or (__futexp, FUTEX_OWNER_DIED); \ atomic_or (__futexp, FUTEX_OWNER_DIED); \
lll_futex_wake (__futexp, 1); \ lll_futex_wake (__futexp, 1, private); \
} \ } \
while (0) while (0)
/* Returns non-zero if error happened, zero if success. */ /* Returns non-zero if error happened, zero if success. */
#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \ #define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
({ \ ({ \
INTERNAL_SYSCALL_DECL (__err); \ INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \ long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 6, \ __ret = INTERNAL_SYSCALL (futex, __err, 6, (long) (futexp), \
(long) (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
(nr_move), (mutex), (val)); \ (nr_wake), (nr_move), (mutex), (val)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
}) })
/* Returns non-zero if error happened, zero if success. */ /* Returns non-zero if error happened, zero if success. */
#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \ #define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
({ \ ({ \
INTERNAL_SYSCALL_DECL (__err); \ INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \ long int __ret; \
\ \
__ret = INTERNAL_SYSCALL (futex, __err, 6, \ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
(futexp), FUTEX_WAKE_OP, (nr_wake), \ __lll_private_flag (FUTEX_WAKE_OP, private), \
(nr_wake2), (futexp2), \ (nr_wake), (nr_wake2), (futexp2), \
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
}) })
static inline int __attribute__((always_inline)) static inline int __attribute__((always_inline))
__lll_mutex_trylock(int *futex) __lll_trylock(int *futex)
{ {
return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0; return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0;
} }
#define lll_mutex_trylock(lock) __lll_mutex_trylock (&(lock)) #define lll_trylock(lock) __lll_trylock (&(lock))
static inline int __attribute__((always_inline)) static inline int __attribute__((always_inline))
__lll_mutex_cond_trylock(int *futex) __lll_cond_trylock(int *futex)
{ {
return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0; return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0;
} }
#define lll_mutex_cond_trylock(lock) __lll_mutex_cond_trylock (&(lock)) #define lll_cond_trylock(lock) __lll_cond_trylock (&(lock))
static inline int __attribute__((always_inline)) static inline int __attribute__((always_inline))
__lll_robust_mutex_trylock(int *futex, int id) __lll_robust_trylock(int *futex, int id)
{ {
return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0; return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
} }
#define lll_robust_mutex_trylock(lock, id) \ #define lll_robust_trylock(lock, id) \
__lll_robust_mutex_trylock (&(lock), id) __lll_robust_trylock (&(lock), id)
extern void __lll_lock_wait (int *futex) attribute_hidden; extern void __lll_lock_wait_private (int *futex) attribute_hidden;
extern int __lll_robust_lock_wait (int *futex) attribute_hidden; extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
static inline void __attribute__((always_inline)) #define __lll_lock(futex, private) \
__lll_mutex_lock(int *futex) ((void) ({ \
{ int *__futex = (futex); \
if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0) if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, \
__lll_lock_wait (futex); 1, 0), 0)) \
} { \
#define lll_mutex_lock(futex) __lll_mutex_lock (&(futex)) if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
__lll_lock_wait_private (__futex); \
else \
__lll_lock_wait (__futex, private); \
} \
}))
#define lll_lock(futex, private) __lll_lock (&(futex), private)
static inline int __attribute__ ((always_inline)) #define __lll_robust_lock(futex, id, private) \
__lll_robust_mutex_lock (int *futex, int id) ({ \
{ int *__futex = (futex); \
int result = 0; int __val = 0; \
if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) \
result = __lll_robust_lock_wait (futex); if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \
return result; 0), 0)) \
} __val = __lll_robust_lock_wait (__futex, private); \
#define lll_robust_mutex_lock(futex, id) \ __val; \
__lll_robust_mutex_lock (&(futex), id) })
#define lll_robust_lock(futex, id, private) \
__lll_robust_lock (&(futex), id, private)
static inline void __attribute__ ((always_inline)) static inline void __attribute__ ((always_inline))
__lll_mutex_cond_lock (int *futex) __lll_cond_lock (int *futex, int private)
{ {
if (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0) if (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0)
__lll_lock_wait (futex); __lll_lock_wait (futex, private);
} }
#define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex)) #define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
#define lll_robust_mutex_cond_lock(futex, id) \ #define lll_robust_cond_lock(futex, id, private) \
__lll_robust_mutex_lock (&(futex), (id) | FUTEX_WAITERS) __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
extern int __lll_timedlock_wait (int *futex, const struct timespec *) extern int __lll_timedlock_wait (int *futex, const struct timespec *,
attribute_hidden; int private) attribute_hidden;
extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *) extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
attribute_hidden; int private) attribute_hidden;
static inline int __attribute__ ((always_inline)) static inline int __attribute__ ((always_inline))
__lll_mutex_timedlock (int *futex, const struct timespec *abstime) __lll_timedlock (int *futex, const struct timespec *abstime, int private)
{ {
int result = 0; int result = 0;
if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0) if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0)
result = __lll_timedlock_wait (futex, abstime); result = __lll_timedlock_wait (futex, abstime, private);
return result; return result;
} }
#define lll_mutex_timedlock(futex, abstime) \ #define lll_timedlock(futex, abstime, private) \
__lll_mutex_timedlock (&(futex), abstime) __lll_timedlock (&(futex), abstime, private)
static inline int __attribute__ ((always_inline)) static inline int __attribute__ ((always_inline))
__lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime, __lll_robust_timedlock (int *futex, const struct timespec *abstime,
int id) int id, int private)
{ {
int result = 0; int result = 0;
if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0) if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
result = __lll_robust_timedlock_wait (futex, abstime); result = __lll_robust_timedlock_wait (futex, abstime, private);
return result; return result;
} }
#define lll_robust_mutex_timedlock(futex, abstime, id) \ #define lll_robust_timedlock(futex, abstime, id, private) \
__lll_robust_mutex_timedlock (&(futex), abstime, id) __lll_robust_timedlock (&(futex), abstime, id, private)
static inline void __attribute__ ((always_inline)) #define __lll_unlock(futex, private) \
__lll_mutex_unlock (int *futex) ((void) ({ \
{ int *__futex = (futex); \
int val = atomic_exchange_rel (futex, 0); int __val = atomic_exchange_rel (__futex, 0); \
if (__builtin_expect (val > 1, 0)) \
lll_futex_wake (futex, 1); if (__builtin_expect (__val > 1, 0)) \
} lll_futex_wake (__futex, 1, private); \
#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex)) }))
#define lll_unlock(futex, private) __lll_unlock(&(futex), private)
static inline void __attribute__ ((always_inline)) #define __lll_robust_unlock(futex, private) \
__lll_robust_mutex_unlock (int *futex, int mask) ((void) ({ \
{ int *__futex = (futex); \
int val = atomic_exchange_rel (futex, 0); int __val = atomic_exchange_rel (__futex, 0); \
if (__builtin_expect (val & mask, 0)) \
lll_futex_wake (futex, 1); if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \
} lll_futex_wake (__futex, 1, private); \
#define lll_robust_mutex_unlock(futex) \ }))
__lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS) #define lll_robust_unlock(futex, private) \
__lll_robust_unlock(&(futex), private)
static inline void __attribute__ ((always_inline)) #define lll_islocked(futex) \
__lll_mutex_unlock_force (int *futex)
{
(void) atomic_exchange_rel (futex, 0);
lll_futex_wake (futex, 1);
}
#define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex))
#define lll_mutex_islocked(futex) \
(futex != 0) (futex != 0)
/* Our internal lock implementation is identical to the binary-compatible /* Our internal lock implementation is identical to the binary-compatible
mutex implementation. */ mutex implementation. */
/* Type for lock object. */
typedef int lll_lock_t;
/* Initializers for lock. */ /* Initializers for lock. */
#define LLL_LOCK_INITIALIZER (0) #define LLL_LOCK_INITIALIZER (0)
#define LLL_LOCK_INITIALIZER_LOCKED (1) #define LLL_LOCK_INITIALIZER_LOCKED (1)
@ -240,20 +264,15 @@ typedef int lll_lock_t;
1 - taken by one user 1 - taken by one user
>1 - taken by more users */ >1 - taken by more users */
#define lll_trylock(lock) lll_mutex_trylock (lock)
#define lll_lock(lock) lll_mutex_lock (lock)
#define lll_unlock(lock) lll_mutex_unlock (lock)
#define lll_islocked(lock) lll_mutex_islocked (lock)
/* The kernel notifies a process which uses CLONE_CLEARTID via futex /* The kernel notifies a process which uses CLONE_CLEARTID via futex
wakeup when the clone terminates. The memory location contains the wakeup when the clone terminates. The memory location contains the
thread ID while the clone is running and is reset to zero thread ID while the clone is running and is reset to zero
afterwards. */ afterwards. */
#define lll_wait_tid(tid) \ #define lll_wait_tid(tid) \
do { \ do { \
__typeof (tid) __tid; \ __typeof (tid) __tid; \
while ((__tid = (tid)) != 0) \ while ((__tid = (tid)) != 0) \
lll_futex_wait (&(tid), __tid); \ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
} while (0) } while (0)
extern int __lll_timedwait_tid (int *, const struct timespec *) extern int __lll_timedwait_tid (int *, const struct timespec *)
@ -267,26 +286,4 @@ extern int __lll_timedwait_tid (int *, const struct timespec *)
__res; \ __res; \
}) })
/* Conditional variable handling. */
extern void __lll_cond_wait (pthread_cond_t *cond)
attribute_hidden;
extern int __lll_cond_timedwait (pthread_cond_t *cond,
const struct timespec *abstime)
attribute_hidden;
extern void __lll_cond_wake (pthread_cond_t *cond)
attribute_hidden;
extern void __lll_cond_broadcast (pthread_cond_t *cond)
attribute_hidden;
#define lll_cond_wait(cond) \
__lll_cond_wait (cond)
#define lll_cond_timedwait(cond, abstime) \
__lll_cond_timedwait (cond, abstime)
#define lll_cond_wake(cond) \
__lll_cond_wake (cond)
#define lll_cond_broadcast(cond) \
__lll_cond_broadcast (cond)
#endif /* lowlevellock.h */ #endif /* lowlevellock.h */

View File

@ -30,7 +30,7 @@ clear_once_control (void *arg)
pthread_once_t *once_control = (pthread_once_t *) arg; pthread_once_t *once_control = (pthread_once_t *) arg;
*once_control = 0; *once_control = 0;
lll_futex_wake (once_control, INT_MAX); lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
} }
@ -65,7 +65,7 @@ __pthread_once (once_control, init_routine)
if (((oldval ^ newval) & -4) == 0) if (((oldval ^ newval) & -4) == 0)
{ {
/* Same generation, some other thread was faster. Wait. */ /* Same generation, some other thread was faster. Wait. */
lll_futex_wait (once_control, newval); lll_futex_wait (once_control, newval, LLL_PRIVATE);
continue; continue;
} }
} }
@ -84,7 +84,7 @@ __pthread_once (once_control, init_routine)
atomic_increment (once_control); atomic_increment (once_control);
/* Wake up all other threads. */ /* Wake up all other threads. */
lll_futex_wake (once_control, INT_MAX); lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
break; break;
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc. /* Copyright (C) 2000, 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Maciej W. Rozycki <macro@ds2.pg.gda.pl>, 2000. Contributed by Maciej W. Rozycki <macro@ds2.pg.gda.pl>, 2000.
@ -30,7 +30,7 @@ extern int _test_and_set (int *p, int v) __THROW;
#ifdef __USE_EXTERN_INLINES #ifdef __USE_EXTERN_INLINES
# ifndef _EXTERN_INLINE # ifndef _EXTERN_INLINE
# define _EXTERN_INLINE extern __inline # define _EXTERN_INLINE __extern_inline
# endif # endif
_EXTERN_INLINE int _EXTERN_INLINE int