From: Daniel Jacobowitz Date: Tue, 10 Jul 2007 13:35:30 +0000 (+0000) Subject: * sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_RESET_FLAG): Use X-Git-Tag: glibc-2.16-ports-before-merge~762 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8323b1abc6a9f7a4a2458be35bd4cc941da725af;p=thirdparty%2Fglibc.git * 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. --- diff --git a/ChangeLog.aix b/ChangeLog.aix index 5305d338db5..3e3e4df3079 100644 --- a/ChangeLog.aix +++ b/ChangeLog.aix @@ -1,3 +1,7 @@ +2007-07-10 Daniel Jacobowitz + + * sysdeps/unix/sysv/aix/bits/fcntl.h: Comment fix. + 2005-12-27 Roland McGrath * sysdeps/unix/sysv/aix/bits/setjmp.h (_JMPBUF_UNWINDS): Take third diff --git a/ChangeLog.am33 b/ChangeLog.am33 index f794cc55dcf..c10f8d08e46 100644 --- a/ChangeLog.am33 +++ b/ChangeLog.am33 @@ -1,3 +1,7 @@ +2007-07-10 Daniel Jacobowitz + + * sysdeps/unix/sysv/linux/am33/bits/fcntl.h: Comment fix. + 2006-01-12 Roland McGrath * sysdeps/am33/jmpbuf-unwind.h: Include . diff --git a/ChangeLog.arm b/ChangeLog.arm index 39e14dca952..5a24c54ff9a 100644 --- a/ChangeLog.arm +++ b/ChangeLog.arm @@ -1,3 +1,33 @@ +2007-07-10 Daniel Jacobowitz + + * 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 * sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_FLAG_UNUSED, diff --git a/ChangeLog.cris b/ChangeLog.cris index af91a1d4203..746c89cbf51 100644 --- a/ChangeLog.cris +++ b/ChangeLog.cris @@ -1,3 +1,7 @@ +2007-07-10 Daniel Jacobowitz + + * sysdeps/unix/sysv/linux/cris/bits/fcntl.h: Comment fix. + 2005-12-27 Roland McGrath * sysdeps/cris/bits/setjmp.h (_JMPBUF_UNWINDS): Take third argument diff --git a/ChangeLog.m68k b/ChangeLog.m68k index 51f6dfa022b..fb591ad11d6 100644 --- a/ChangeLog.m68k +++ b/ChangeLog.m68k @@ -1,3 +1,7 @@ +2007-07-10 Daniel Jacobowitz + + * sysdeps/unix/sysv/linux/m68k/bits/fcntl.h: Comment fix. + 2006-11-28 Andreas Schwab * sysdeps/unix/sysv/linux/m68k/sysdep.h (DOARGS_6, _DOARGS_6) diff --git a/ChangeLog.mips b/ChangeLog.mips index 346237f3462..3ea63cd8c7f 100644 --- a/ChangeLog.mips +++ b/ChangeLog.mips @@ -1,3 +1,10 @@ +2007-07-10 Daniel Jacobowitz + + * 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 * sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h (ARGIFY): New. diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h index ae2aecc42bc..e80b6b8d067 100644 --- a/sysdeps/arm/nptl/tls.h +++ b/sysdeps/arm/nptl/tls.h @@ -142,7 +142,7 @@ typedef struct = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ THREAD_GSCOPE_FLAG_UNUSED); \ 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) #define THREAD_GSCOPE_SET_FLAG() \ diff --git a/sysdeps/unix/sysv/aix/bits/fcntl.h b/sysdeps/unix/sysv/aix/bits/fcntl.h index c65b8beeb4b..d53c0f7d9bd 100644 --- a/sysdeps/unix/sysv/aix/bits/fcntl.h +++ b/sysdeps/unix/sysv/aix/bits/fcntl.h @@ -79,7 +79,7 @@ # define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */ #endif -/* For F_[GET|SET]FL. */ +/* For F_[GET|SET]FD. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ diff --git a/sysdeps/unix/sysv/linux/am33/bits/fcntl.h b/sysdeps/unix/sysv/linux/am33/bits/fcntl.h index 4c276c54852..f2c88fad101 100644 --- a/sysdeps/unix/sysv/linux/am33/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/am33/bits/fcntl.h @@ -94,7 +94,7 @@ # define F_NOTIFY 1026 /* Request notfications on a directory. */ #endif -/* For F_[GET|SET]FL. */ +/* For F_[GET|SET]FD. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ diff --git a/sysdeps/unix/sysv/linux/arm/bits/fcntl.h b/sysdeps/unix/sysv/linux/arm/bits/fcntl.h index 7c7b7c20278..59539e17587 100644 --- a/sysdeps/unix/sysv/linux/arm/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/arm/bits/fcntl.h @@ -98,7 +98,7 @@ # define F_NOTIFY 1026 /* Request notfications on a directory. */ #endif -/* For F_[GET|SET]FL. */ +/* For F_[GET|SET]FD. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ diff --git a/sysdeps/unix/sysv/linux/arm/check_pf.c b/sysdeps/unix/sysv/linux/arm/check_pf.c index ee13d8019c6..dfca75d374c 100644 --- a/sysdeps/unix/sysv/linux/arm/check_pf.c +++ b/sysdeps/unix/sysv/linux/arm/check_pf.c @@ -1,5 +1,5 @@ -/* Determine protocol families for which interfaces exist. ARM Linux version. - Copyright (C) 2003, 2006 Free Software Foundation, Inc. +/* Determine protocol families for which interfaces exist. Linux version. + Copyright (C) 2003, 2006, 2007 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 @@ -69,17 +69,38 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, memset (&nladdr, '\0', sizeof (nladdr)); 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, (struct sockaddr *) &nladdr, sizeof (nladdr))) < 0) - return -1; + goto out_fail; *seen_ipv4 = false; *seen_ipv6 = false; bool done = false; - char buf[4096]; - struct iovec iov = { buf, sizeof (buf) }; struct in6ailist { 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)); if (read_len < 0) - return -1; + goto out_fail; if (msg.msg_flags & MSG_TRUNC) - return -1; + goto out_fail; struct nlmsghdr *nlmh; for (nlmh = (struct nlmsghdr *) buf; @@ -116,40 +137,72 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, if (nlmh->nlmsg_type == RTM_NEWADDR) { 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) { + const void *local; + const void *address; + case AF_INET: - *seen_ipv4 = true; + 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_v4; + } + + 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: - *seen_ipv6 = true; + 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 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)) - { - switch (rta->rta_type) - { - case IFA_LOCAL: - local = RTA_DATA (rta); - break; - - case IFA_ADDRESS: - address = RTA_DATA (rta); - break; - } - - rta = RTA_NEXT (rta, len); - } - struct in6ailist *newp = alloca (sizeof (*newp)); newp->info.flags = (((ifam->ifa_flags & IFA_F_DEPRECATED) ? 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); - if (in6ailist != NULL) + if (*seen_ipv6 && in6ailist != NULL) { *in6ai = malloc (in6ailistlen * sizeof (**in6ai)); if (*in6ai == NULL) - return -1; + goto out_fail; *in6ailen = in6ailistlen; @@ -196,7 +249,14 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, while (in6ailist != NULL); } + if (use_malloc) + free (buf); return 0; + +out_fail: + if (use_malloc) + free (buf); + return -1; } diff --git a/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c index ca1cc8d68e3..24ce61ba19f 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c +++ b/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c @@ -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. Contributed by Jakub Jelinek . @@ -30,13 +30,18 @@ static _Unwind_Reason_Code (*libgcc_s_forcedunwind) static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *); void +__attribute_noinline__ pthread_cancel_init (void) { void *resume, *personality, *forcedunwind, *getcfa; void *handle; if (__builtin_expect (libgcc_s_getcfa != NULL, 1)) - return; + { + /* Force gcc to reload all values. */ + asm volatile ("" ::: "memory"); + return; + } handle = __libc_dlopen ("libgcc_s.so.1"); @@ -55,6 +60,10 @@ pthread_cancel_init (void) libgcc_s_resume = resume; libgcc_s_personality = personality; 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; } @@ -92,6 +101,7 @@ __gcc_personality_v0 (_Unwind_State state, { if (__builtin_expect (libgcc_s_personality == NULL, 0)) pthread_cancel_init (); + 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)) pthread_cancel_init (); + 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)) pthread_cancel_init (); + return libgcc_s_getcfa (context); } diff --git a/sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h b/sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h index 3fc647d31dd..dadfac2af2c 100644 --- a/sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h +++ b/sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h @@ -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. The GNU C Library is free software; you can redistribute it and/or @@ -27,9 +27,6 @@ /* Value returned if `sem_open' failed. */ #define SEM_FAILED ((sem_t *) 0) -/* Maximum value the semaphore can have. */ -#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) - typedef union { diff --git a/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c b/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c index 66a4d7b3604..44867ecc834 100644 --- a/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c +++ b/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c @@ -55,7 +55,8 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime) if (rt.tv_sec < 0) 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); @@ -96,7 +97,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) return ETIMEDOUT; /* 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; } diff --git a/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h b/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h index 15cf1478fd4..468fe716fd1 100644 --- a/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h +++ b/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h @@ -12,7 +12,7 @@ Lesser General Public License for more details. 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 02111-1307 USA. */ @@ -36,42 +36,87 @@ #define FUTEX_TRYLOCK_PI 8 #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. */ #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) + +#define lll_futex_timed_wait(futexp, val, timespec, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), 0); \ + (futexp), FUTEX_WAIT, (val), (timespec)); \ __ret; \ }) -#define lll_futex_timed_wait(futexp, val, timespec) \ +#define lll_futex_wake(futexp, nr, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ __ret = INTERNAL_SYSCALL (futex, __err, 4, \ - (futexp), FUTEX_WAIT, (val), (timespec)); \ + (futexp), FUTEX_WAKE, (nr), 0); \ __ret; \ }) -#define lll_futex_wake(futexp, nr) \ +#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_WAKE, (nr), 0); \ + (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) \ do \ { \ int *__futexp = &(futexv); \ atomic_or (__futexp, FUTEX_OWNER_DIED); \ - lll_futex_wake (__futexp, 1); \ + lll_futex_wake (__futexp, 1, 0); \ } \ while (0) @@ -88,7 +133,7 @@ /* 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); \ long int __ret; \ @@ -156,7 +201,7 @@ __lll_mutex_lock (int *futex) if (__builtin_expect (val != 0, 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)) @@ -182,7 +227,7 @@ __lll_mutex_cond_lock (int *futex) if (__builtin_expect (val != 0, 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)) @@ -229,7 +274,7 @@ __lll_mutex_unlock (int *futex) { int val = atomic_exchange_rel (futex, 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)) @@ -239,7 +284,7 @@ __lll_robust_mutex_unlock (int *futex, int mask) { int val = atomic_exchange_rel (futex, 0); if (__builtin_expect (val & mask, 0)) - lll_futex_wake (futex, 1); + lll_futex_wake (futex, 1, 0); } #define lll_robust_mutex_unlock(futex) \ __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS) @@ -249,7 +294,7 @@ static inline void __attribute__ ((always_inline)) __lll_mutex_unlock_force (int *futex) { (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)) @@ -286,7 +331,7 @@ typedef int lll_lock_t; do { \ __typeof (tid) __tid; \ while ((__tid = (tid)) != 0) \ - lll_futex_wait (&(tid), __tid); \ + lll_futex_wait (&(tid), __tid, 0);\ } while (0) extern int __lll_timedwait_tid (int *, const struct timespec *) diff --git a/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c index c8925810cbe..909e8327a53 100644 --- a/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c +++ b/sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c @@ -27,7 +27,7 @@ clear_once_control (void *arg) pthread_once_t *once_control = (pthread_once_t *) arg; *once_control = 0; - lll_futex_wake (once_control, INT_MAX); + lll_private_futex_wake (once_control, INT_MAX); } int @@ -66,7 +66,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) break; /* 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. @@ -82,7 +82,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) *once_control = __fork_generation | 2; /* Wake up all other threads. */ - lll_futex_wake (once_control, INT_MAX); + lll_private_futex_wake (once_control, INT_MAX); return 0; } diff --git a/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c index ba5327a4d1a..b2819635688 100644 --- a/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c +++ b/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c @@ -33,6 +33,7 @@ static void (*libgcc_s_sjlj_register) (struct SjLj_Function_Context *); static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *); void +__attribute_noinline__ pthread_cancel_init (void) { void *resume, *personality, *forcedunwind, *getcfa; @@ -40,7 +41,11 @@ pthread_cancel_init (void) void *sjlj_register, *sjlj_unregister; if (__builtin_expect (libgcc_s_getcfa != NULL, 1)) - return; + { + /* Force gcc to reload all values. */ + asm volatile ("" ::: "memory"); + return; + } handle = __libc_dlopen ("libgcc_s.so.1"); @@ -58,9 +63,13 @@ pthread_cancel_init (void) libgcc_s_resume = resume; libgcc_s_personality = personality; libgcc_s_forcedunwind = forcedunwind; - libgcc_s_getcfa = getcfa; libgcc_s_sjlj_register = sjlj_register; 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 @@ -68,6 +77,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc) { if (__builtin_expect (libgcc_s_resume == NULL, 0)) pthread_cancel_init (); + libgcc_s_resume (exc); } @@ -79,6 +89,7 @@ __gcc_personality_v0 (int version, _Unwind_Action actions, { if (__builtin_expect (libgcc_s_personality == NULL, 0)) pthread_cancel_init (); + return libgcc_s_personality (version, actions, exception_class, 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)) pthread_cancel_init (); + 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)) pthread_cancel_init (); + 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)) pthread_cancel_init (); + 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)) pthread_cancel_init (); + libgcc_s_sjlj_unregister (fc); } diff --git a/sysdeps/unix/sysv/linux/cris/bits/fcntl.h b/sysdeps/unix/sysv/linux/cris/bits/fcntl.h index 36799aa50e4..270a8de58aa 100644 --- a/sysdeps/unix/sysv/linux/cris/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/cris/bits/fcntl.h @@ -96,7 +96,7 @@ # define F_NOTIFY 1026 /* Request notfications on a directory. */ #endif -/* For F_[GET|SET]FL. */ +/* For F_[GET|SET]FD. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ diff --git a/sysdeps/unix/sysv/linux/m68k/bits/fcntl.h b/sysdeps/unix/sysv/linux/m68k/bits/fcntl.h index 90c0a481e4d..733a088cf5d 100644 --- a/sysdeps/unix/sysv/linux/m68k/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/m68k/bits/fcntl.h @@ -95,7 +95,7 @@ # define F_NOTIFY 1026 /* Request notfications on a directory. */ #endif -/* For F_[GET|SET]FL. */ +/* For F_[GET|SET]FD. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ diff --git a/sysdeps/unix/sysv/linux/mips/bits/fcntl.h b/sysdeps/unix/sysv/linux/mips/bits/fcntl.h index d40b4b6386b..340466392a9 100644 --- a/sysdeps/unix/sysv/linux/mips/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/mips/bits/fcntl.h @@ -101,7 +101,7 @@ # define F_NOTIFY 1026 /* Request notfications on a directory. */ #endif -/* For F_[GET|SET]FL. */ +/* For F_[GET|SET]FD. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ /* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ diff --git a/sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h b/sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h index c4440f9e9e9..af43a604849 100644 --- a/sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h +++ b/sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h @@ -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. The GNU C Library is free software; you can redistribute it and/or @@ -29,9 +29,6 @@ /* Value returned if `sem_open' failed. */ #define SEM_FAILED ((sem_t *) 0) -/* Maximum value the semaphore can have. */ -#define SEM_VALUE_MAX (2147483647) - typedef union {