* sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_RESET_FLAG): Use

lll_private_futex_wake.
	* sysdeps/unix/sysv/linux/arm/check_pf.c: Update from generic version.
	* sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c
	(pthread_cancel_init): Add noinline and barriers.
	* sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c
	(__lll_timedlock_wait): Update call to lll_futex_timed_wait.
	(__lll_timedwait_tid): Likewise.
	* sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h (LLL_PRIVATE,
	LLL_SHARED): Define.
	(lll_futex_wait): Use lll_futex_timed_wait.
	(lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock): Take a
	PRIVATE argument.
	(lll_private_futex_wait, lll_private_futex_timed_wait,
	lll_private_futex_wake): New.
	(lll_robust_mutex_dead,  __lll_mutex_lock, __lll_mutex_cond_lock,
	__lll_mutex_unlock, __lll_robust_mutex_unlock,
	__lll_mutex_unlock_force, lll_wait_tid): Update calls.
	* sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c (clear_once_control,
	__pthread_once): Use private futexes.
	* sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
	(pthread_cancel_init): Add noinline and barriers.

	* sysdeps/unix/sysv/aix/bits/fcntl.h,
	sysdeps/unix/sysv/linux/am33/bits/fcntl.h,
	sysdeps/unix/sysv/linux/arm/bits/fcntl.h,
	sysdeps/unix/sysv/linux/cris/bits/fcntl.h,
	sysdeps/unix/sysv/linux/m68k/bits/fcntl.h,
	sysdeps/unix/sysv/linux/mips/bits/fcntl.h: Comment fix.

	* sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h (SEM_VALUE_MAX):
	Delete.
	* sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h (SEM_VALUE_MAX):
	Delete.
This commit is contained in:
Daniel Jacobowitz 2007-07-10 13:35:30 +00:00
parent e8955bf409
commit 8323b1abc6
21 changed files with 256 additions and 75 deletions

View File

@ -1,3 +1,7 @@
2007-07-10 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/unix/sysv/aix/bits/fcntl.h: Comment fix.
2005-12-27 Roland McGrath <roland@redhat.com> 2005-12-27 Roland McGrath <roland@redhat.com>
* sysdeps/unix/sysv/aix/bits/setjmp.h (_JMPBUF_UNWINDS): Take third * sysdeps/unix/sysv/aix/bits/setjmp.h (_JMPBUF_UNWINDS): Take third

View File

@ -1,3 +1,7 @@
2007-07-10 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/unix/sysv/linux/am33/bits/fcntl.h: Comment fix.
2006-01-12 Roland McGrath <roland@redhat.com> 2006-01-12 Roland McGrath <roland@redhat.com>
* sysdeps/am33/jmpbuf-unwind.h: Include <jmpbuf-offsets.h>. * sysdeps/am33/jmpbuf-unwind.h: Include <jmpbuf-offsets.h>.

View File

@ -1,3 +1,33 @@
2007-07-10 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_RESET_FLAG): Use
lll_private_futex_wake.
* sysdeps/unix/sysv/linux/arm/check_pf.c: Update from generic version.
* sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c
(pthread_cancel_init): Add noinline and barriers.
* sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c
(__lll_timedlock_wait): Update call to lll_futex_timed_wait.
(__lll_timedwait_tid): Likewise.
* sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h (LLL_PRIVATE,
LLL_SHARED): Define.
(lll_futex_wait): Use lll_futex_timed_wait.
(lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock): Take a
PRIVATE argument.
(lll_private_futex_wait, lll_private_futex_timed_wait,
lll_private_futex_wake): New.
(lll_robust_mutex_dead, __lll_mutex_lock, __lll_mutex_cond_lock,
__lll_mutex_unlock, __lll_robust_mutex_unlock,
__lll_mutex_unlock_force, lll_wait_tid): Update calls.
* sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c (clear_once_control,
__pthread_once): Use private futexes.
* sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
(pthread_cancel_init): Add noinline and barriers.
* sysdeps/unix/sysv/linux/arm/bits/fcntl.h: Comment fix.
* sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h (SEM_VALUE_MAX):
Delete.
2007-06-06 Daniel Jacobowitz <dan@codesourcery.com> 2007-06-06 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_FLAG_UNUSED, * sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_FLAG_UNUSED,

View File

@ -1,3 +1,7 @@
2007-07-10 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/unix/sysv/linux/cris/bits/fcntl.h: Comment fix.
2005-12-27 Roland McGrath <roland@redhat.com> 2005-12-27 Roland McGrath <roland@redhat.com>
* sysdeps/cris/bits/setjmp.h (_JMPBUF_UNWINDS): Take third argument * sysdeps/cris/bits/setjmp.h (_JMPBUF_UNWINDS): Take third argument

View File

@ -1,3 +1,7 @@
2007-07-10 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/unix/sysv/linux/m68k/bits/fcntl.h: Comment fix.
2006-11-28 Andreas Schwab <schwab@suse.de> 2006-11-28 Andreas Schwab <schwab@suse.de>
* sysdeps/unix/sysv/linux/m68k/sysdep.h (DOARGS_6, _DOARGS_6) * sysdeps/unix/sysv/linux/m68k/sysdep.h (DOARGS_6, _DOARGS_6)

View File

@ -1,3 +1,10 @@
2007-07-10 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/unix/sysv/linux/mips/bits/fcntl.h: Comment fix.
* sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h (SEM_VALUE_MAX):
Delete.
2007-06-07 Daniel Jacobowitz <dan@codesourcery.com> 2007-06-07 Daniel Jacobowitz <dan@codesourcery.com>
* sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h (ARGIFY): New. * sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h (ARGIFY): New.

View File

@ -142,7 +142,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_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
} \ } \
while (0) while (0)
#define THREAD_GSCOPE_SET_FLAG() \ #define THREAD_GSCOPE_SET_FLAG() \

View File

@ -79,7 +79,7 @@
# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */ # define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */
#endif #endif
/* For F_[GET|SET]FL. */ /* For F_[GET|SET]FD. */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */

View File

@ -94,7 +94,7 @@
# define F_NOTIFY 1026 /* Request notfications on a directory. */ # define F_NOTIFY 1026 /* Request notfications on a directory. */
#endif #endif
/* For F_[GET|SET]FL. */ /* For F_[GET|SET]FD. */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */

View File

@ -98,7 +98,7 @@
# define F_NOTIFY 1026 /* Request notfications on a directory. */ # define F_NOTIFY 1026 /* Request notfications on a directory. */
#endif #endif
/* For F_[GET|SET]FL. */ /* For F_[GET|SET]FD. */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */

View File

@ -1,5 +1,5 @@
/* Determine protocol families for which interfaces exist. ARM Linux version. /* Determine protocol families for which interfaces exist. Linux version.
Copyright (C) 2003, 2006 Free Software Foundation, Inc. Copyright (C) 2003, 2006, 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
@ -69,17 +69,38 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
memset (&nladdr, '\0', sizeof (nladdr)); memset (&nladdr, '\0', sizeof (nladdr));
nladdr.nl_family = AF_NETLINK; nladdr.nl_family = AF_NETLINK;
#ifdef PAGE_SIZE
/* Help the compiler optimize out the malloc call if PAGE_SIZE
is constant and smaller or equal to PTHREAD_STACK_MIN/4. */
const size_t buf_size = PAGE_SIZE;
#else
const size_t buf_size = __getpagesize ();
#endif
bool use_malloc = false;
char *buf;
if (__libc_use_alloca (buf_size))
buf = alloca (buf_size);
else
{
buf = malloc (buf_size);
if (buf != NULL)
use_malloc = true;
else
goto out_fail;
}
struct iovec iov = { buf, buf_size };
if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0, if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
(struct sockaddr *) &nladdr, (struct sockaddr *) &nladdr,
sizeof (nladdr))) < 0) sizeof (nladdr))) < 0)
return -1; goto out_fail;
*seen_ipv4 = false; *seen_ipv4 = false;
*seen_ipv6 = false; *seen_ipv6 = false;
bool done = false; bool done = false;
char buf[4096];
struct iovec iov = { buf, sizeof (buf) };
struct in6ailist struct in6ailist
{ {
struct in6addrinfo info; struct in6addrinfo info;
@ -99,10 +120,10 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0)); ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
if (read_len < 0) if (read_len < 0)
return -1; goto out_fail;
if (msg.msg_flags & MSG_TRUNC) if (msg.msg_flags & MSG_TRUNC)
return -1; goto out_fail;
struct nlmsghdr *nlmh; struct nlmsghdr *nlmh;
for (nlmh = (struct nlmsghdr *) buf; for (nlmh = (struct nlmsghdr *) buf;
@ -116,24 +137,17 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
if (nlmh->nlmsg_type == RTM_NEWADDR) if (nlmh->nlmsg_type == RTM_NEWADDR)
{ {
struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlmh); struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlmh);
struct rtattr *rta = IFA_RTA (ifam);
size_t len = nlmh->nlmsg_len - NLMSG_LENGTH (sizeof (*ifam));
switch (ifam->ifa_family) switch (ifam->ifa_family)
{ {
case AF_INET: const void *local;
*seen_ipv4 = true; const void *address;
break;
case AF_INET6:
*seen_ipv6 = true;
if (ifam->ifa_flags & (IFA_F_DEPRECATED case AF_INET:
| IFA_F_TEMPORARY local = NULL;
| IFA_F_HOMEADDRESS)) address = NULL;
{
struct rtattr *rta = IFA_RTA (ifam);
size_t len = (nlmh->nlmsg_len
- NLMSG_LENGTH (sizeof (*ifam)));
void *local = NULL;
void *address = NULL;
while (RTA_OK (rta, len)) while (RTA_OK (rta, len))
{ {
switch (rta->rta_type) switch (rta->rta_type)
@ -144,12 +158,51 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
case IFA_ADDRESS: case IFA_ADDRESS:
address = RTA_DATA (rta); address = RTA_DATA (rta);
break; goto out_v4;
} }
rta = RTA_NEXT (rta, len); rta = RTA_NEXT (rta, len);
} }
if (local != NULL)
{
out_v4:
if (*(const in_addr_t *) (address ?: local)
!= htonl (INADDR_LOOPBACK))
*seen_ipv4 = true;
}
break;
case AF_INET6:
local = NULL;
address = NULL;
while (RTA_OK (rta, len))
{
switch (rta->rta_type)
{
case IFA_LOCAL:
local = RTA_DATA (rta);
break;
case IFA_ADDRESS:
address = RTA_DATA (rta);
goto out_v6;
}
rta = RTA_NEXT (rta, len);
}
if (local != NULL)
{
out_v6:
if (!IN6_IS_ADDR_LOOPBACK (address ?: local))
*seen_ipv6 = true;
}
if (ifam->ifa_flags & (IFA_F_DEPRECATED
| IFA_F_TEMPORARY
| IFA_F_HOMEADDRESS))
{
struct in6ailist *newp = alloca (sizeof (*newp)); struct in6ailist *newp = alloca (sizeof (*newp));
newp->info.flags = (((ifam->ifa_flags & IFA_F_DEPRECATED) newp->info.flags = (((ifam->ifa_flags & IFA_F_DEPRECATED)
? in6ai_deprecated : 0) ? in6ai_deprecated : 0)
@ -180,11 +233,11 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
close_not_cancel_no_status (fd); close_not_cancel_no_status (fd);
if (in6ailist != NULL) if (*seen_ipv6 && in6ailist != NULL)
{ {
*in6ai = malloc (in6ailistlen * sizeof (**in6ai)); *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
if (*in6ai == NULL) if (*in6ai == NULL)
return -1; goto out_fail;
*in6ailen = in6ailistlen; *in6ailen = in6ailistlen;
@ -196,7 +249,14 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
while (in6ailist != NULL); while (in6ailist != NULL);
} }
if (use_malloc)
free (buf);
return 0; return 0;
out_fail:
if (use_malloc)
free (buf);
return -1;
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2003, 2005 Free Software Foundation, Inc. /* Copyright (C) 2003, 2005, 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 Jakub Jelinek <jakub@redhat.com>. Contributed by Jakub Jelinek <jakub@redhat.com>.
@ -30,13 +30,18 @@ static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *); static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
void void
__attribute_noinline__
pthread_cancel_init (void) pthread_cancel_init (void)
{ {
void *resume, *personality, *forcedunwind, *getcfa; void *resume, *personality, *forcedunwind, *getcfa;
void *handle; void *handle;
if (__builtin_expect (libgcc_s_getcfa != NULL, 1)) if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
{
/* Force gcc to reload all values. */
asm volatile ("" ::: "memory");
return; return;
}
handle = __libc_dlopen ("libgcc_s.so.1"); handle = __libc_dlopen ("libgcc_s.so.1");
@ -55,6 +60,10 @@ pthread_cancel_init (void)
libgcc_s_resume = resume; libgcc_s_resume = resume;
libgcc_s_personality = personality; libgcc_s_personality = personality;
libgcc_s_forcedunwind = forcedunwind; libgcc_s_forcedunwind = forcedunwind;
/* Make sure libgcc_s_getcfa is written last. Otherwise,
pthread_cancel_init might return early even when the pointer the
caller is interested in is not initialized yet. */
atomic_write_barrier ();
libgcc_s_getcfa = getcfa; libgcc_s_getcfa = getcfa;
} }
@ -92,6 +101,7 @@ __gcc_personality_v0 (_Unwind_State state,
{ {
if (__builtin_expect (libgcc_s_personality == NULL, 0)) if (__builtin_expect (libgcc_s_personality == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
return libgcc_s_personality (state, ue_header, context); return libgcc_s_personality (state, ue_header, context);
} }
@ -101,6 +111,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
{ {
if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0)) if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
return libgcc_s_forcedunwind (exc, stop, stop_argument); return libgcc_s_forcedunwind (exc, stop, stop_argument);
} }
@ -109,5 +120,6 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
{ {
if (__builtin_expect (libgcc_s_getcfa == NULL, 0)) if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
return libgcc_s_getcfa (context); return libgcc_s_getcfa (context);
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2005 Free Software Foundation, Inc. /* Copyright (C) 2002, 2005, 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
@ -27,9 +27,6 @@
/* Value returned if `sem_open' failed. */ /* Value returned if `sem_open' failed. */
#define SEM_FAILED ((sem_t *) 0) #define SEM_FAILED ((sem_t *) 0)
/* Maximum value the semaphore can have. */
#define SEM_VALUE_MAX ((int) ((~0u) >> 1))
typedef union typedef union
{ {

View File

@ -55,7 +55,8 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime)
if (rt.tv_sec < 0) if (rt.tv_sec < 0)
return ETIMEDOUT; return ETIMEDOUT;
lll_futex_timed_wait (futex, 2, &rt); // XYZ: Lost the lock to check whether it was private.
lll_futex_timed_wait (futex, 2, &rt, LLL_SHARED);
} }
while (atomic_exchange_acq (futex, 2) != 0); while (atomic_exchange_acq (futex, 2) != 0);
@ -96,7 +97,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
return ETIMEDOUT; return ETIMEDOUT;
/* Wait until thread terminates. */ /* Wait until thread terminates. */
if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT) // XYZ: Lost the lock to check whether it was private.
if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
return ETIMEDOUT; return ETIMEDOUT;
} }

View File

@ -12,7 +12,7 @@
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with the GNU C Libr \ary; if not, write to the Free License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
@ -36,19 +36,19 @@
#define FUTEX_TRYLOCK_PI 8 #define FUTEX_TRYLOCK_PI 8
#define FUTEX_PRIVATE_FLAG 128 #define FUTEX_PRIVATE_FLAG 128
/* Values for 'private' parameter of locking macros. Yes, the
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
/* Initializer for compatibility lock. */ /* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0) #define LLL_MUTEX_LOCK_INITIALIZER (0)
#define lll_futex_wait(futexp, val) \ #define lll_futex_wait(futexp, val, private) \
({ \ lll_futex_timed_wait(futexp, val, NULL, private)
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), FUTEX_WAIT, (val), 0); \
__ret; \
})
#define lll_futex_timed_wait(futexp, val, timespec) \ #define lll_futex_timed_wait(futexp, val, timespec, private) \
({ \ ({ \
INTERNAL_SYSCALL_DECL (__err); \ INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \ long int __ret; \
@ -57,7 +57,7 @@
__ret; \ __ret; \
}) })
#define lll_futex_wake(futexp, nr) \ #define lll_futex_wake(futexp, nr, private) \
({ \ ({ \
INTERNAL_SYSCALL_DECL (__err); \ INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \ long int __ret; \
@ -66,12 +66,57 @@
__ret; \ __ret; \
}) })
#define lll_private_futex_wait(futexp, val) \
lll_private_futex_timed_wait(futexp, val, NULL)
#ifdef __ASSUME_PRIVATE_FUTEX
#define lll_private_futex_timed_wait(futexp, val, timespec) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), FUTEX_WAIT | FUTEX_PRIVATE_FLAG, \
(val), (timespec)); \
__ret; \
})
#define lll_private_futex_wake(futexp, nr) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), FUTEX_WAKE | FUTEX_PRIVATE_FLAG, \
(nr), (0)); \
__ret; \
})
#else
#define lll_private_futex_timed_wait(futexp, val, timespec) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret, __op; \
__op = FUTEX_WAIT | THREAD_GETMEM (THREAD_SELF, header.private_futex); \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), __op, (val), (timespec)); \
__ret; \
})
#define lll_private_futex_wake(futexp, nr) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret, __op; \
__op = FUTEX_WAKE | THREAD_GETMEM (THREAD_SELF, header.private_futex); \
__ret = INTERNAL_SYSCALL (futex, __err, 4, \
(futexp), __op, (nr), 0); \
__ret; \
})
#endif
#define lll_robust_mutex_dead(futexv) \ #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, 0); \
} \ } \
while (0) while (0)
@ -88,7 +133,7 @@
/* 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; \
@ -156,7 +201,7 @@ __lll_mutex_lock (int *futex)
if (__builtin_expect (val != 0, 0)) if (__builtin_expect (val != 0, 0))
{ {
while (atomic_exchange_acq (futex, 2) != 0) while (atomic_exchange_acq (futex, 2) != 0)
lll_futex_wait (futex, 2); lll_futex_wait (futex, 2, 0);
} }
} }
#define lll_mutex_lock(futex) __lll_mutex_lock (&(futex)) #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
@ -182,7 +227,7 @@ __lll_mutex_cond_lock (int *futex)
if (__builtin_expect (val != 0, 0)) if (__builtin_expect (val != 0, 0))
{ {
while (atomic_exchange_acq (futex, 2) != 0) while (atomic_exchange_acq (futex, 2) != 0)
lll_futex_wait (futex, 2); lll_futex_wait (futex, 2, 0);
} }
} }
#define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex)) #define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
@ -229,7 +274,7 @@ __lll_mutex_unlock (int *futex)
{ {
int val = atomic_exchange_rel (futex, 0); int val = atomic_exchange_rel (futex, 0);
if (__builtin_expect (val > 1, 0)) if (__builtin_expect (val > 1, 0))
lll_futex_wake (futex, 1); lll_futex_wake (futex, 1, 0);
} }
#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex)) #define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex))
@ -239,7 +284,7 @@ __lll_robust_mutex_unlock (int *futex, int mask)
{ {
int val = atomic_exchange_rel (futex, 0); int val = atomic_exchange_rel (futex, 0);
if (__builtin_expect (val & mask, 0)) if (__builtin_expect (val & mask, 0))
lll_futex_wake (futex, 1); lll_futex_wake (futex, 1, 0);
} }
#define lll_robust_mutex_unlock(futex) \ #define lll_robust_mutex_unlock(futex) \
__lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS) __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
@ -249,7 +294,7 @@ static inline void __attribute__ ((always_inline))
__lll_mutex_unlock_force (int *futex) __lll_mutex_unlock_force (int *futex)
{ {
(void) atomic_exchange_rel (futex, 0); (void) atomic_exchange_rel (futex, 0);
lll_futex_wake (futex, 1); lll_futex_wake (futex, 1, 0);
} }
#define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex)) #define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex))
@ -286,7 +331,7 @@ typedef int lll_lock_t;
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, 0);\
} while (0) } while (0)
extern int __lll_timedwait_tid (int *, const struct timespec *) extern int __lll_timedwait_tid (int *, const struct timespec *)

View File

@ -27,7 +27,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_private_futex_wake (once_control, INT_MAX);
} }
int int
@ -66,7 +66,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
break; break;
/* Same generation, some other thread was faster. Wait. */ /* Same generation, some other thread was faster. Wait. */
lll_futex_wait (once_control, oldval); lll_private_futex_wait (once_control, oldval);
} }
/* This thread is the first here. Do the initialization. /* This thread is the first here. Do the initialization.
@ -82,7 +82,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
*once_control = __fork_generation | 2; *once_control = __fork_generation | 2;
/* Wake up all other threads. */ /* Wake up all other threads. */
lll_futex_wake (once_control, INT_MAX); lll_private_futex_wake (once_control, INT_MAX);
return 0; return 0;
} }

View File

@ -33,6 +33,7 @@ static void (*libgcc_s_sjlj_register) (struct SjLj_Function_Context *);
static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *); static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *);
void void
__attribute_noinline__
pthread_cancel_init (void) pthread_cancel_init (void)
{ {
void *resume, *personality, *forcedunwind, *getcfa; void *resume, *personality, *forcedunwind, *getcfa;
@ -40,7 +41,11 @@ pthread_cancel_init (void)
void *sjlj_register, *sjlj_unregister; void *sjlj_register, *sjlj_unregister;
if (__builtin_expect (libgcc_s_getcfa != NULL, 1)) if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
{
/* Force gcc to reload all values. */
asm volatile ("" ::: "memory");
return; return;
}
handle = __libc_dlopen ("libgcc_s.so.1"); handle = __libc_dlopen ("libgcc_s.so.1");
@ -58,9 +63,13 @@ pthread_cancel_init (void)
libgcc_s_resume = resume; libgcc_s_resume = resume;
libgcc_s_personality = personality; libgcc_s_personality = personality;
libgcc_s_forcedunwind = forcedunwind; libgcc_s_forcedunwind = forcedunwind;
libgcc_s_getcfa = getcfa;
libgcc_s_sjlj_register = sjlj_register; libgcc_s_sjlj_register = sjlj_register;
libgcc_s_sjlj_unregister = sjlj_unregister; libgcc_s_sjlj_unregister = sjlj_unregister;
/* Make sure libgcc_s_getcfa is written last. Otherwise,
pthread_cancel_init might return early even when the pointer the
caller is interested in is not initialized yet. */
atomic_write_barrier ();
libgcc_s_getcfa = getcfa;
} }
void void
@ -68,6 +77,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
{ {
if (__builtin_expect (libgcc_s_resume == NULL, 0)) if (__builtin_expect (libgcc_s_resume == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
libgcc_s_resume (exc); libgcc_s_resume (exc);
} }
@ -79,6 +89,7 @@ __gcc_personality_v0 (int version, _Unwind_Action actions,
{ {
if (__builtin_expect (libgcc_s_personality == NULL, 0)) if (__builtin_expect (libgcc_s_personality == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
return libgcc_s_personality (version, actions, exception_class, return libgcc_s_personality (version, actions, exception_class,
ue_header, context); ue_header, context);
} }
@ -89,6 +100,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
{ {
if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0)) if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
return libgcc_s_forcedunwind (exc, stop, stop_argument); return libgcc_s_forcedunwind (exc, stop, stop_argument);
} }
@ -97,6 +109,7 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
{ {
if (__builtin_expect (libgcc_s_getcfa == NULL, 0)) if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
return libgcc_s_getcfa (context); return libgcc_s_getcfa (context);
} }
@ -105,6 +118,7 @@ _Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
{ {
if (__builtin_expect (libgcc_s_sjlj_register == NULL, 0)) if (__builtin_expect (libgcc_s_sjlj_register == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
libgcc_s_sjlj_register (fc); libgcc_s_sjlj_register (fc);
} }
@ -113,5 +127,6 @@ _Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
{ {
if (__builtin_expect (libgcc_s_sjlj_unregister == NULL, 0)) if (__builtin_expect (libgcc_s_sjlj_unregister == NULL, 0))
pthread_cancel_init (); pthread_cancel_init ();
libgcc_s_sjlj_unregister (fc); libgcc_s_sjlj_unregister (fc);
} }

View File

@ -96,7 +96,7 @@
# define F_NOTIFY 1026 /* Request notfications on a directory. */ # define F_NOTIFY 1026 /* Request notfications on a directory. */
#endif #endif
/* For F_[GET|SET]FL. */ /* For F_[GET|SET]FD. */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */

View File

@ -95,7 +95,7 @@
# define F_NOTIFY 1026 /* Request notfications on a directory. */ # define F_NOTIFY 1026 /* Request notfications on a directory. */
#endif #endif
/* For F_[GET|SET]FL. */ /* For F_[GET|SET]FD. */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */

View File

@ -101,7 +101,7 @@
# define F_NOTIFY 1026 /* Request notfications on a directory. */ # define F_NOTIFY 1026 /* Request notfications on a directory. */
#endif #endif
/* For F_[GET|SET]FL. */ /* For F_[GET|SET]FD. */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2005 Free Software Foundation, Inc. /* Copyright (C) 2002, 2005, 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
@ -29,9 +29,6 @@
/* Value returned if `sem_open' failed. */ /* Value returned if `sem_open' failed. */
#define SEM_FAILED ((sem_t *) 0) #define SEM_FAILED ((sem_t *) 0)
/* Maximum value the semaphore can have. */
#define SEM_VALUE_MAX (2147483647)
typedef union typedef union
{ {