From jakub@redhat.com Wed Aug 1 09:48:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 01 Aug 2007 09:48:00 -0000 Subject: [PATCH] Fix posix_fallocate{,64} on i386 Message-ID: <20070801095307.GC4603@sunsite.mff.cuni.cz> Hi! On i386 INTERNAL_SYSCALL doesn't support 6 argument syscalls, but as we for !__ASSUME_FALLOCATE case need a fallback written in C, we can't just code the whole routine as i386/posix_fallocate{,64}.S. Fortunately PSEUDO_* handles 6 argument syscalls. I used __fallocate64, so that if we decide to export the fallocate syscall in addition to posix_fallocate{,64}, it doesn't clash with the private internal helper for posix_fallocate* if we decide it should return -1 and set errno on error rather than return 0 or error value directly. 2007-08-01 Jakub Jelinek * sysdeps/unix/sysv/linux/i386/syscalls.list (fallocate): Add fallocate syscall as __fallocate64. * sysdeps/unix/sysv/linux/i386/posix_fallocate.c: New file. * sysdeps/unix/sysv/linux/i386/posix_fallocate64.c: New file. --- libc/sysdeps/unix/sysv/linux/i386/syscalls.list.jj 2005-12-20 08:52:13.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/i386/syscalls.list 2007-08-01 11:33:03.000000000 +0200 @@ -6,3 +6,4 @@ vm86 - vm86 i:ip __vm86 vm86@@GLIBC_2 oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0 waitpid - waitpid Ci:ipi __waitpid waitpid __libc_waitpid +fallocate64 EXTRA fallocate Vi:iiiiii __fallocate64 --- libc/sysdeps/unix/sysv/linux/i386/posix_fallocate.c.jj 2007-08-01 11:14:15.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/posix_fallocate.c 2007-08-01 11:34:04.000000000 +0200 @@ -0,0 +1,58 @@ +/* Copyright (C) 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + 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 Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +#define posix_fallocate static internal_fallocate +#include +#undef posix_fallocate + +#if !defined __ASSUME_FALLOCATE && defined __NR_fallocate +int __have_fallocate attribute_hidden; +#endif + +extern int __fallocate64 (int fd, int mode, __off64_t offset, __off64_t len) + attribute_hidden; + +/* Reserve storage for the data of the file associated with FD. */ +int +posix_fallocate (int fd, __off_t offset, __off_t len) +{ +#ifdef __NR_fallocate +# ifndef __ASSUME_FALLOCATE + if (__builtin_expect (__have_fallocate >= 0, 1)) +# endif + { + int res = __fallocate64 (fd, 0, offset, len); + if (! res) + return 0; + +# ifndef __ASSUME_FALLOCATE + if (__builtin_expect (res == ENOSYS, 0)) + __have_fallocate = -1; + else +# endif + if (res != EOPNOTSUPP) + return res; + } +#endif + + return internal_fallocate (fd, offset, len); +} --- libc/sysdeps/unix/sysv/linux/i386/posix_fallocate64.c.jj 2007-08-01 11:14:18.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/posix_fallocate64.c 2007-08-01 11:34:22.000000000 +0200 @@ -0,0 +1,61 @@ +/* Copyright (C) 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + 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 Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +extern int __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len); +#define __posix_fallocate64_l64 static internal_fallocate64 +#include +#undef __posix_fallocate64_l64 + +#if !defined __ASSUME_FALLOCATE && defined __NR_fallocate +/* Defined in posix_fallocate.c. */ +extern int __have_fallocate attribute_hidden; +#endif + +extern int __fallocate64 (int fd, int mode, __off64_t offset, __off64_t len) + attribute_hidden; + +/* Reserve storage for the data of the file associated with FD. */ +int +__posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len) +{ +#ifdef __NR_fallocate +# ifndef __ASSUME_FALLOCATE + if (__builtin_expect (__have_fallocate >= 0, 1)) +# endif + { + int res = __fallocate64 (fd, 0, offset, len); + + if (! res) + return 0; + +# ifndef __ASSUME_FALLOCATE + if (__builtin_expect (res == ENOSYS, 0)) + __have_fallocate = -1; + else +# endif + if (res != EOPNOTSUPP) + return res; + } +#endif + + return internal_fallocate64 (fd, offset, len); +} Jakub From kkojima@rr.iij4u.or.jp Wed Aug 1 23:00:00 2007 From: kkojima@rr.iij4u.or.jp (Kaz Kojima) Date: Wed, 01 Aug 2007 23:00:00 -0000 Subject: [PATCH] lowlevellock.h cleanups, LLL_SHARED vs. LLL_PRIVATE on lll locks In-Reply-To: <20070731111453.GZ4603@sunsite.mff.cuni.cz> References: <20070725201502.GI4603@sunsite.mff.cuni.cz> <20070731111453.GZ4603@sunsite.mff.cuni.cz> Message-ID: <20070802.080027.08326116.kkojima@rr.iij4u.or.jp> Jakub Jelinek wrote: > Here is an updated patch against CVS trunk plus > http://sources.redhat.com/ml/libc-hacker/2007-07/msg00050.html > which changes all in-tree arches but SH (will leave that to Kaz) and > sparc sem_* stuff (will do when I find time for it). The attached patch is the SH portion for this change and a few other code cleanups. Regards, kaz -- 2007-08-01 Kaz Kojima * sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: Remove definitions for private futexes. * sysdeps/unix/sysv/linux/sh/lowlevellock.S: Include kernel-features.h and lowlevellock.h. Use private futexes if they are available. (__lll_lock_wait_private, __lll_unlock_wake_private): New. (__lll_mutex_lock_wait): Rename to (__lll_lock_wait): ... this. Don't compile in for libc.so. (__lll_mutex_timedlock_wait): Rename to ... (__lll_timedlock_wait): ... this. Use __NR_gettimeofday. Don't compile in for libc.so. (__lll_mutex_unlock_wake): Rename to ... (__lll_unlock_wake): ... this. Don't compile in for libc.so. (__lll_timedwait_tid): Use __NR_gettimeofday. * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Allow including the header from assembler. Renamed all lll_mutex_* resp. lll_robust_mutex_* macros to lll_* resp. lll_robust_*. Renamed all LLL_MUTEX_LOCK_* macros to LLL_LOCK_*. (FUTEX_CMP_REQUEUE, FUTEX_WAKE_OP, FUTEX_OP_CLEAR_WAKE_IF_GT_ONE): Define. (__lll_lock_wait_private): Add prototype. (__lll_lock_wait, __lll_timedlock_wait, __lll_robust_lock_wait, __lll_robust_timedlock_wait, __lll_unlock_wake_private, __lll_unlock_wake): Likewise. (lll_lock): Add private argument. Call __lll_lock_wait_private if private is constant LLL_PRIVATE. (lll_robust_lock, lll_cond_lock, lll_robust_cond_lock, lll_timedlock, lll_robust_timedlock): Add private argument. (lll_unlock): Add private argument. Call __lll_unlock_wake_private if private is constant LLL_PRIVATE. (lll_robust_unlock, lll_robust_dead): Add private argument. (lll_lock_t): Remove. (__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/sh/lowlevelrobustlock.S: Include kernel-features.h and lowlevellock.h. (SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove. (LOAD_FUTEX_WAIT): Define. (__lll_robust_mutex_lock_wait): Rename to ... (__lll_robust_lock_wait): ... this. Add private argument. Use LOAD_FUTEX_WAIT macro. (__lll_robust_mutex_timedlock_wait): Rename to ... (__lll_robust_timedlock_wait): ... this. Add private argument. Use __NR_gettimeofday. Use LOAD_FUTEX_WAIT macro. * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: Include lowlevellock.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove. (pthread_barrier_wait): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: Include lowlevellock.h and pthread-errnos.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, EINVAL): Remove. (__pthread_cond_broadcast): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: Include lowlevellock.h and pthread-errnos.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE, EINVAL): Remove. (__pthread_cond_signal): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Include lowlevellock.h. (SYS_futex, SYS_gettimeofday, FUTEX_WAIT, FUTEX_WAKE): Remove. (__pthread_cond_timedwait): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. Use __NR_gettimeofday. (__condvar_tw_cleanup): Likewise. * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Include lowlevellock.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE): Remove. (__pthread_cond_wait): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. ( __condvar_w_cleanup): Likewise. * sysdeps/unix/sysv/linux/sh/pthread_once.S: Include lowlevellock.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Include lowlevellock.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove. (__pthread_rwlock_rdlock): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Include lowlevellock.h. (SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove. (pthread_rwlock_timedrdlock): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. Use __NR_gettimeofday. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Include lowlevellock.h. (SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove. (pthread_rwlock_timedwrlock): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. Use __NR_gettimeofday. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Include lowlevellock.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove. (__pthread_rwlock_unlock): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Include lowlevellock.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove. (__pthread_rwlock_wrlock): Use __lll_{lock,unlock}_* instead of __lll_mutex_{lock,unlock}_*. * sysdeps/unix/sysv/linux/sh/sem_post.S: Include lowlevellock.h. (SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove. (__new_sem_post): Use standard initial exec code sequences. * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Include lowlevellock.h. (SYS_gettimeofday, SYS_futex, FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Remove. (sem_timedwait): Use __NR_gettimeofday. Use standard initial exec code sequences. * sysdeps/unix/sysv/linux/sh/sem_trywait.S: Include lowlevellock.h. (__new_sem_trywait): Use standard initial exec code sequences. * sysdeps/unix/sysv/linux/sh/sem_wait.S: Include lowlevellock.h. (__new_sem_wait): Use standard initial exec code sequences. diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S 2007-07-31 21:24:55.000000000 +0900 @@ -16,32 +16,4 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include - -/* All locks in libc are private. Use the kernel feature if possible. */ -#define FUTEX_PRIVATE_FLAG 128 -#ifdef __ASSUME_PRIVATE_FUTEX -# define FUTEX_WAIT (0 | FUTEX_PRIVATE_FLAG) -# define FUTEX_WAKE (1 | FUTEX_PRIVATE_FLAG) -#else -# define LOAD_FUTEX_WAIT(reg,tmp) \ - stc gbr, tmp ; \ - mov.w 99f, reg ; \ - add reg, tmp ; \ - bra 98f ; \ - mov.l @tmp, reg ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: - -# define LOAD_FUTEX_WAKE(reg,tmp) \ - stc gbr, tmp ; \ - mov.w 99f, reg ; \ - add reg, tmp ; \ - mov.l @tmp, reg ; \ - bra 98f ; \ - mov #FUTEX_WAKE, tmp ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: or tmp, reg -#endif - #include "lowlevellock.S" diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S 2007-08-01 13:28:04.000000000 +0900 @@ -18,45 +18,112 @@ #include #include +#include +#include #include "lowlevel-atomic.h" .text -#define SYS_gettimeofday __NR_gettimeofday -#define SYS_futex 240 -#ifndef FUTEX_WAIT -# define FUTEX_WAIT 0 -# define FUTEX_WAKE 1 -#endif - -#ifndef LOAD_FUTEX_WAIT +#ifdef __ASSUME_PRIVATE_FUTEX +# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \ + mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg; \ + extu.b reg, reg +# define LOAD_PRIVATE_FUTEX_WAKE(reg,tmp,tmp2) \ + mov #(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg; \ + extu.b reg, reg +# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ + mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \ + extu.b tmp, tmp; \ + xor tmp, reg +# define LOAD_FUTEX_WAKE(reg,tmp,tmp2) \ + mov #(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), tmp; \ + extu.b tmp, tmp; \ + xor tmp, reg +#else # if FUTEX_WAIT == 0 -# define LOAD_FUTEX_WAIT(reg,tmp) \ - xor reg, reg +# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \ + stc gbr, tmp ; \ + mov.w 99f, reg ; \ + add reg, tmp ; \ + bra 98f ; \ + mov.l @tmp, reg ; \ +99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ +98: # else -# define LOAD_FUTEX_WAIT(reg,tmp) \ - mov #FUTEX_WAIT, reg; \ - extu.b reg, reg +# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \ + stc gbr, tmp ; \ + mov.w 99f, reg ; \ + add reg, tmp ; \ + mov.l @tmp, reg ; \ + bra 98f ; \ + mov #FUTEX_WAIT, tmp ; \ +99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ +98: or tmp, reg +# endif +# define LOAD_PRIVATE_FUTEX_WAKE(reg,tmp,tmp2) \ + stc gbr, tmp ; \ + mov.w 99f, reg ; \ + add reg, tmp ; \ + mov.l @tmp, reg ; \ + bra 98f ; \ + mov #FUTEX_WAKE, tmp ; \ +99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ +98: or tmp, reg +# if FUTEX_WAIT == 0 +# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ + stc gbr, tmp ; \ + mov.w 99f, tmp2 ; \ + add tmp2, tmp ; \ + mov.l @tmp, tmp2 ; \ + bra 98f ; \ + mov #FUTEX_PRIVATE_FLAG, tmp +99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ +98: extu.b tmp, tmp ; \ + xor tmp, reg ; \ + and tmp2, reg +# else +# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ + stc gbr, tmp ; \ + mov.w 99f, tmp2 ; \ + add tmp2, tmp ; \ + mov.l @tmp, tmp2 ; \ + bra 98f ; \ + mov #FUTEX_PRIVATE_FLAG, tmp +99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ +98: extu.b tmp, tmp ; \ + xor tmp, reg ; \ + and tmp2, reg ; \ + mov #FUTEX_WAIT, tmp ; \ + or tmp, reg # endif # define LOAD_FUTEX_WAKE(reg,tmp) \ - mov #FUTEX_WAKE, reg; \ - extu.b reg, reg + stc gbr, tmp ; \ + mov.w 99f, tmp2 ; \ + add tmp2, tmp ; \ + mov.l @tmp, tmp2 ; \ + bra 98f ; \ + mov #FUTEX_PRIVATE_FLAG, tmp +99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ +98: extu.b tmp, tmp ; \ + xor tmp, reg ; \ + and tmp2, reg ; \ + mov #FUTEX_WAKE, tmp ; \ + or tmp, reg #endif - - .globl __lll_mutex_lock_wait - .type __lll_mutex_lock_wait,@function - .hidden __lll_mutex_lock_wait + .globl __lll_lock_wait_private + .type __lll_lock_wait_private,@function + .hidden __lll_lock_wait_private .align 5 cfi_startproc -__lll_mutex_lock_wait: +__lll_lock_wait_private: mov.l r8, @-r15 cfi_adjust_cfa_offset(4) cfi_rel_offset (r8, 0) mov r4, r6 mov r5, r8 mov #0, r7 /* No timeout. */ - LOAD_FUTEX_WAIT (r5, r0) + LOAD_PRIVATE_FUTEX_WAIT (r5, r0, r1) mov #2, r4 cmp/eq r4, r6 @@ -79,22 +146,67 @@ __lll_mutex_lock_wait: ret mov r2, r0 cfi_endproc - .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait - + .size __lll_lock_wait_private,.-__lll_lock_wait_private #ifdef NOT_IN_libc - .globl __lll_mutex_timedlock_wait - .type __lll_mutex_timedlock_wait,@function - .hidden __lll_mutex_timedlock_wait + .globl __lll_lock_wait + .type __lll_lock_wait,@function + .hidden __lll_lock_wait .align 5 cfi_startproc -__lll_mutex_timedlock_wait: +__lll_lock_wait: + mov.l r9, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r9, 0) + mov.l r8, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r8, 0) + mov r6, r9 + mov r4, r6 + mov r5, r8 + mov #0, r7 /* No timeout. */ + mov r9, r5 + LOAD_FUTEX_WAIT (r5, r0, r1) + + mov #2, r4 + cmp/eq r4, r6 + bf 2f + +1: + mov r8, r4 + mov #SYS_futex, r3 + extu.b r3, r3 + trapa #0x14 + SYSCALL_INST_PAD + +2: + mov #2, r6 + XCHG (r6, @r8, r2) + tst r2, r2 + bf 1b + + mov.l @r15+, r8 + mov.l @r15+, r9 + ret + mov r2, r0 + cfi_endproc + .size __lll_lock_wait,.-__lll_lock_wait + + .globl __lll_timedlock_wait + .type __lll_timedlock_wait,@function + .hidden __lll_timedlock_wait + .align 5 + cfi_startproc +__lll_timedlock_wait: /* Check for a valid timeout value. */ mov.l @(4,r6), r1 mov.l .L1g, r0 cmp/hs r0, r1 bt 3f + mov.l r11, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r11, 0) mov.l r10, @-r15 cfi_adjust_cfa_offset(4) cfi_rel_offset (r10, 0) @@ -104,6 +216,7 @@ __lll_mutex_timedlock_wait: mov.l r8, @-r15 cfi_adjust_cfa_offset(4) cfi_rel_offset (r8, 0) + mov r7, r11 mov r4, r10 mov r6, r9 mov r5, r8 @@ -116,7 +229,7 @@ __lll_mutex_timedlock_wait: /* Get current time. */ mov r15, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -149,7 +262,8 @@ __lll_mutex_timedlock_wait: bt 8f mov r8, r4 - LOAD_FUTEX_WAIT (r5, r0) + mov r11, r5 + LOAD_FUTEX_WAIT (r5, r0, r1) mov r10, r6 mov r15, r7 mov #SYS_futex, r3 @@ -169,8 +283,9 @@ __lll_mutex_timedlock_wait: add #8, r15 mov.l @r15+, r8 mov.l @r15+, r9 + mov.l @r15+, r10 rts - mov.l @r15+, r10 + mov.l @r15+, r11 7: /* Check whether the time expired. */ mov #-ETIMEDOUT, r1 @@ -198,17 +313,16 @@ __lll_mutex_timedlock_wait: .L1g: .long 1000000000 - .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait + .size __lll_timedlock_wait,.-__lll_timedlock_wait #endif - - .globl __lll_mutex_unlock_wake - .type __lll_mutex_unlock_wake,@function - .hidden __lll_mutex_unlock_wake + .globl __lll_unlock_wake_private + .type __lll_unlock_wake_private,@function + .hidden __lll_unlock_wake_private .align 5 cfi_startproc -__lll_mutex_unlock_wake: - LOAD_FUTEX_WAKE (r5, r0) +__lll_unlock_wake_private: + LOAD_PRIVATE_FUTEX_WAKE (r5, r0, r1) mov #1, r6 /* Wake one thread. */ mov #0, r7 mov.l r7, @r4 /* Stores 0. */ @@ -219,10 +333,28 @@ __lll_mutex_unlock_wake: rts nop cfi_endproc - .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake - + .size __lll_unlock_wake_private,.-__lll_unlock_wake_private #ifdef NOT_IN_libc + .globl __lll_unlock_wake + .type __lll_unlock_wake,@function + .hidden __lll_unlock_wake + .align 5 + cfi_startproc +__lll_unlock_wake: + LOAD_FUTEX_WAKE (r5, r0, r1) + mov #1, r6 /* Wake one thread. */ + mov #0, r7 + mov.l r7, @r4 /* Stores 0. */ + mov #SYS_futex, r3 + extu.b r3, r3 + trapa #0x14 + SYSCALL_INST_PAD + rts + nop + cfi_endproc + .size __lll_unlock_wake,.-__lll_unlock_wake + .globl __lll_timedwait_tid .type __lll_timedwait_tid,@function .hidden __lll_timedwait_tid @@ -246,7 +378,7 @@ __lll_timedwait_tid: /* Get current time. */ mov r15, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h 2007-07-31 20:25:06.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h 2007-08-01 15:41:56.000000000 +0900 @@ -19,19 +19,24 @@ #ifndef _LOWLEVELLOCK_H #define _LOWLEVELLOCK_H 1 +#ifndef __ASSEMBLER__ #include #include #include #include +#endif #define SYS_futex 240 #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 +#define FUTEX_CMP_REQUEUE 4 +#define FUTEX_WAKE_OP 5 #define FUTEX_LOCK_PI 6 #define FUTEX_UNLOCK_PI 7 #define FUTEX_TRYLOCK_PI 8 #define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) /* Values for 'private' parameter of locking macros. Yes, the definition seems to be backwards. But it is not. The bit will be @@ -64,20 +69,30 @@ # endif #endif +#ifndef __ASSEMBLER__ /* Initializer for compatibility lock. */ -#define LLL_MUTEX_LOCK_INITIALIZER (0) -#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1) -#define LLL_MUTEX_LOCK_INITIALIZER_WAITERS (2) - -extern int __lll_mutex_lock_wait (int val, int *__futex) attribute_hidden; -extern int __lll_mutex_timedlock_wait (int val, int *__futex, - const struct timespec *abstime) - attribute_hidden; -extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden; +#define LLL_LOCK_INITIALIZER (0) +#define LLL_LOCK_INITIALIZER_LOCKED (1) +#define LLL_LOCK_INITIALIZER_WAITERS (2) +extern int __lll_lock_wait_private (int val, int *__futex) + attribute_hidden; +extern int __lll_lock_wait (int val, int *__futex, int private) + attribute_hidden; +extern int __lll_timedlock_wait (int val, int *__futex, + const struct timespec *abstime, int private) + attribute_hidden; +extern int __lll_robust_lock_wait (int val, int *__futex, int private) + attribute_hidden; +extern int __lll_robust_timedlock_wait (int val, int *__futex, + const struct timespec *abstime, + int private) + attribute_hidden; +extern int __lll_unlock_wake_private (int *__futex) attribute_hidden; +extern int __lll_unlock_wake (int *__futex, int private) attribute_hidden; -#define lll_mutex_trylock(futex) \ +#define lll_trylock(futex) \ ({ unsigned char __result; \ __asm __volatile ("\ .align 2\n\ @@ -94,12 +109,12 @@ extern int __lll_mutex_unlock_wake (int negc %0,%0"\ : "=r" (__result) \ : "r" (&(futex)), \ - "r" (LLL_MUTEX_LOCK_INITIALIZER_LOCKED), \ - "r" (LLL_MUTEX_LOCK_INITIALIZER) \ + "r" (LLL_LOCK_INITIALIZER_LOCKED), \ + "r" (LLL_LOCK_INITIALIZER) \ : "r0", "r1", "r2", "t", "memory"); \ __result; }) -#define lll_robust_mutex_trylock(futex, id) \ +#define lll_robust_trylock(futex, id) \ ({ unsigned char __result; \ __asm __volatile ("\ .align 2\n\ @@ -117,11 +132,11 @@ extern int __lll_mutex_unlock_wake (int : "=r" (__result) \ : "r" (&(futex)), \ "r" (id), \ - "r" (LLL_MUTEX_LOCK_INITIALIZER) \ + "r" (LLL_LOCK_INITIALIZER) \ : "r0", "r1", "r2", "t", "memory"); \ __result; }) -#define lll_mutex_cond_trylock(futex) \ +#define lll_cond_trylock(futex) \ ({ unsigned char __result; \ __asm __volatile ("\ .align 2\n\ @@ -138,13 +153,13 @@ extern int __lll_mutex_unlock_wake (int negc %0,%0"\ : "=r" (__result) \ : "r" (&(futex)), \ - "r" (LLL_MUTEX_LOCK_INITIALIZER_WAITERS), \ - "r" (LLL_MUTEX_LOCK_INITIALIZER) \ + "r" (LLL_LOCK_INITIALIZER_WAITERS), \ + "r" (LLL_LOCK_INITIALIZER) \ : "r0", "r1", "r2", "t", "memory"); \ __result; }) -#define lll_mutex_lock(futex) \ - (void) ({ int __result, val, *__futex = &(futex); \ +#define lll_lock(futex, private) \ + (void) ({ int __result, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -159,10 +174,17 @@ extern int __lll_mutex_unlock_wake (int : "=&r" (__result) : "r" (1), "r" (__futex) \ : "r0", "r1", "t", "memory"); \ if (__result) \ - __lll_mutex_lock_wait (__result, __futex); }) + { \ + if (__builtin_constant_p (private) \ + && (private) == LLL_PRIVATE) \ + __lll_lock_wait_private (__result, __futex); \ + else \ + __lll_lock_wait (__result, __futex, (private)); \ + } \ + }) -#define lll_robust_mutex_lock(futex, id) \ - ({ int __result, val, *__futex = &(futex); \ +#define lll_robust_lock(futex, id, private) \ + ({ int __result, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -177,13 +199,13 @@ extern int __lll_mutex_unlock_wake (int : "=&r" (__result) : "r" (id), "r" (__futex) \ : "r0", "r1", "t", "memory"); \ if (__result) \ - __result = __lll_robust_mutex_lock_wait (__result, __futex); \ + __result = __lll_robust_lock_wait (__result, __futex, private); \ __result; }) /* Special version of lll_mutex_lock which causes the unlock function to always wakeup waiters. */ -#define lll_mutex_cond_lock(futex) \ - (void) ({ int __result, val, *__futex = &(futex); \ +#define lll_cond_lock(futex, private) \ + (void) ({ int __result, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -198,10 +220,10 @@ extern int __lll_mutex_unlock_wake (int : "=&r" (__result) : "r" (2), "r" (__futex) \ : "r0", "r1", "t", "memory"); \ if (__result) \ - __lll_mutex_lock_wait (__result, __futex); }) + __lll_lock_wait (__result, __futex, private); }) -#define lll_robust_mutex_cond_lock(futex, id) \ - ({ int __result, val, *__futex = &(futex); \ +#define lll_robust_cond_lock(futex, id, private) \ + ({ int __result, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -216,11 +238,11 @@ extern int __lll_mutex_unlock_wake (int : "=&r" (__result) : "r" (id | FUTEX_WAITERS), "r" (__futex) \ : "r0", "r1", "t", "memory"); \ if (__result) \ - __result = __lll_robust_mutex_lock_wait (__result, __futex); \ + __result = __lll_robust_lock_wait (__result, __futex, private); \ __result; }) -#define lll_mutex_timedlock(futex, timeout) \ - ({ int __result, val, *__futex = &(futex); \ +#define lll_timedlock(futex, timeout, private) \ + ({ int __result, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -235,11 +257,11 @@ extern int __lll_mutex_unlock_wake (int : "=&r" (__result) : "r" (1), "r" (__futex) \ : "r0", "r1", "t", "memory"); \ if (__result) \ - __result = __lll_mutex_timedlock_wait (__result, __futex, timeout); \ + __result = __lll_timedlock_wait (__result, __futex, timeout, private); \ __result; }) -#define lll_robust_mutex_timedlock(futex, timeout, id) \ - ({ int __result, val, *__futex = &(futex); \ +#define lll_robust_timedlock(futex, timeout, id, private) \ + ({ int __result, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -254,11 +276,11 @@ extern int __lll_mutex_unlock_wake (int : "=&r" (__result) : "r" (id), "r" (__futex) \ : "r0", "r1", "t", "memory"); \ if (__result) \ - __result = __lll_robust_mutex_timedlock_wait (__result, __futex, \ - timeout); \ + __result = __lll_robust_timedlock_wait (__result, __futex, \ + timeout, private); \ __result; }) -#define lll_mutex_unlock(futex) \ +#define lll_unlock(futex, private) \ (void) ({ int __result, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ @@ -272,9 +294,16 @@ extern int __lll_mutex_unlock_wake (int : "=&r" (__result) : "r" (__futex) \ : "r0", "r1", "memory"); \ if (__result) \ - __lll_mutex_unlock_wake (__futex); }) + { \ + if (__builtin_constant_p (private) \ + && (private) == LLL_PRIVATE) \ + __lll_unlock_wake_private (__futex); \ + else \ + __lll_unlock_wake (__futex, (private)); \ + } \ + }) -#define lll_robust_mutex_unlock(futex) \ +#define lll_robust_unlock(futex, private) \ (void) ({ int __result, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ @@ -288,9 +317,9 @@ extern int __lll_mutex_unlock_wake (int : "=&r" (__result) : "r" (__futex), "r" (FUTEX_WAITERS) \ : "r0", "r1", "memory"); \ if (__result) \ - __lll_mutex_unlock_wake (__futex); }) + __lll_unlock_wake (__futex, private); }) -#define lll_robust_mutex_dead(futex) \ +#define lll_robust_dead(futex, private) \ (void) ({ int __ignore, *__futex = &(futex); \ __asm __volatile ("\ .align 2\n\ @@ -303,22 +332,7 @@ extern int __lll_mutex_unlock_wake (int 1: mov r1,r15"\ : "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \ : "r0", "r1", "memory"); \ - lll_futex_wake (__futex, 1, LLL_SHARED); }) - -#define lll_mutex_islocked(futex) \ - (futex != 0) - - -/* We have a separate internal lock implementation which is not tied - to binary compatibility. */ - -/* Type for lock object. */ -typedef int lll_lock_t; - -/* Initializers for lock. */ -#define LLL_LOCK_INITIALIZER (0) -#define LLL_LOCK_INITIALIZER_LOCKED (1) - + lll_futex_wake (__futex, 1, private); }) # ifdef NEED_SYSCALL_INST_PAD # define SYSCALL_WITH_INST_PAD "\ @@ -367,25 +381,14 @@ typedef int lll_lock_t; } while (0) -/* The states of a lock are: - 0 - untaken - 1 - taken by one user - 2 - taken by more users */ - -#define lll_trylock(futex) lll_mutex_trylock (futex) -#define lll_lock(futex) lll_mutex_lock (futex) -#define lll_unlock(futex) lll_mutex_unlock (futex) - #define lll_islocked(futex) \ (futex != LLL_LOCK_INITIALIZER) - /* The kernel notifies a process with uses CLONE_CLEARTID via futex wakeup when the clone terminates. The memory location contains the thread ID while the clone is running and is reset to zero afterwards. */ -extern int __lll_wait_tid (int *tid) attribute_hidden; #define lll_wait_tid(tid) \ do { \ __typeof (tid) *__tid = &(tid); \ @@ -407,24 +410,6 @@ extern int __lll_timedwait_tid (int *tid } \ __result; }) - -/* 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 /* !__ASSEMBLER__ */ #endif /* lowlevellock.h */ diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S 2006-02-18 00:36:10.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S 2007-08-01 14:29:53.000000000 +0900 @@ -1,4 +1,5 @@ -/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2005, 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 @@ -18,31 +19,64 @@ #include #include +#include #include +#include #include "lowlevel-atomic.h" .text -#define SYS_gettimeofday __NR_gettimeofday -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 #define FUTEX_WAITERS 0x80000000 #define FUTEX_OWNER_DIED 0x40000000 - - .globl __lll_robust_mutex_lock_wait - .type __lll_robust_mutex_lock_wait,@function - .hidden __lll_robust_mutex_lock_wait +#ifdef __ASSUME_PRIVATE_FUTEX +# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ + mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \ + extu.b tmp, tmp; \ + xor tmp, reg +#else +# if FUTEX_WAIT == 0 +# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ + stc gbr, tmp ; \ + mov.w 99f, tmp2 ; \ + add tmp2, tmp ; \ + mov.l @tmp, tmp2 ; \ + bra 98f ; \ + mov #FUTEX_PRIVATE_FLAG, tmp +99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ +98: extu.b tmp, tmp ; \ + xor tmp, reg ; \ + and tmp2, reg +# else +# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ + stc gbr, tmp ; \ + mov.w 99f, tmp2 ; \ + add tmp2, tmp ; \ + mov.l @tmp, tmp2 ; \ + bra 98f ; \ + mov #FUTEX_PRIVATE_FLAG, tmp +99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ +98: extu.b tmp, tmp ; \ + xor tmp, reg ; \ + and tmp2, reg ; \ + mov #FUTEX_WAIT, tmp ; \ + or tmp, reg +# endif +#endif + + .globl __lll_robust_lock_wait + .type __lll_robust_lock_wait,@function + .hidden __lll_robust_lock_wait .align 5 cfi_startproc -__lll_robust_mutex_lock_wait: +__lll_robust_lock_wait: mov.l r8, @-r15 cfi_adjust_cfa_offset(4) cfi_rel_offset (r8, 0) mov r5, r8 mov #0, r7 /* No timeout. */ - mov #FUTEX_WAIT, r5 + mov r6, r5 + LOAD_FUTEX_WAIT (r5, r0, r1) 4: mov r4, r6 @@ -90,21 +124,24 @@ __lll_robust_mutex_lock_wait: .long FUTEX_WAITERS .Ltidoff: .word TID - TLS_PRE_TCB_SIZE - .size __lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait + .size __lll_robust_lock_wait,.-__lll_robust_lock_wait - .globl __lll_robust_mutex_timedlock_wait - .type __lll_robust_mutex_timedlock_wait,@function - .hidden __lll_robust_mutex_timedlock_wait + .globl __lll_robust_timedlock_wait + .type __lll_robust_timedlock_wait,@function + .hidden __lll_robust_timedlock_wait .align 5 cfi_startproc -__lll_robust_mutex_timedlock_wait: +__lll_robust_timedlock_wait: /* Check for a valid timeout value. */ mov.l @(4,r6), r1 mov.l .L1g, r0 cmp/hs r0, r1 bt 3f + mov.l r11, @-r15 + cfi_adjust_cfa_offset(4) + cfi_rel_offset (r11, 0) mov.l r10, @-r15 cfi_adjust_cfa_offset(4) cfi_rel_offset (r10, 0) @@ -114,6 +151,7 @@ __lll_robust_mutex_timedlock_wait: mov.l r8, @-r15 cfi_adjust_cfa_offset(4) cfi_rel_offset (r8, 0) + mov r7, r11 mov r4, r10 mov r6, r9 mov r5, r8 @@ -126,7 +164,7 @@ __lll_robust_mutex_timedlock_wait: /* Get current time. */ mov r15, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -167,7 +205,8 @@ __lll_robust_mutex_timedlock_wait: 2: mov r8, r4 - mov #FUTEX_WAIT, r5 + mov r11, r5 + LOAD_FUTEX_WAIT (r5, r0, r1) mov r10, r6 mov r15, r7 mov #SYS_futex, r3 @@ -196,8 +235,9 @@ __lll_robust_mutex_timedlock_wait: add #8, r15 mov.l @r15+, r8 mov.l @r15+, r9 + mov.l @r15+, r10 rts - mov.l @r15+, r10 + mov.l @r15+, r11 7: /* Check whether the time expired. */ @@ -221,4 +261,4 @@ __lll_robust_mutex_timedlock_wait: .word TID - TLS_PRE_TCB_SIZE .L1k: .word 1000 - .size __lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait + .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S 2007-08-01 09:38:20.000000000 +0900 @@ -17,14 +17,10 @@ 02111-1307 USA. */ #include +#include #include #include "lowlevel-atomic.h" -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 - - .text .globl pthread_barrier_wait @@ -152,6 +148,10 @@ pthread_barrier_wait: mov.l @r15+, r9 1: + mov.l @(PRIVATE,r8), r6 + mov #LLL_SHARED, r0 + extu.b r0, r0 + xor r0, r6 mov r2, r4 mov r8, r5 mov.l .Lwait0, r1 @@ -162,6 +162,10 @@ pthread_barrier_wait: nop 4: + mov.l @(PRIVATE,r8), r5 + mov #LLL_SHARED, r0 + extu.b r0, r0 + xor r0, r5 mov r8, r4 mov.l .Lwake0, r1 bsrf r1 @@ -172,6 +176,10 @@ pthread_barrier_wait: 6: mov r6, r9 + mov.l @(PRIVATE,r8), r5 + mov #LLL_SHARED, r0 + extu.b r0, r0 + xor r0, r5 mov r8, r4 mov.l .Lwake1, r1 bsrf r1 @@ -182,6 +190,10 @@ pthread_barrier_wait: 9: mov r6, r9 + mov.l @(PRIVATE,r8), r5 + mov #LLL_SHARED, r0 + extu.b r0, r0 + xor r0, r5 mov r8, r4 mov.l .Lwake2, r1 bsrf r1 @@ -194,11 +206,11 @@ pthread_barrier_wait: .Lall: .long 0x7fffffff .Lwait0: - .long __lll_mutex_lock_wait-.Lwait0b + .long __lll_lock_wait-.Lwait0b .Lwake0: - .long __lll_mutex_unlock_wake-.Lwake0b + .long __lll_unlock_wake-.Lwake0b .Lwake1: - .long __lll_mutex_unlock_wake-.Lwake1b + .long __lll_unlock_wake-.Lwake1b .Lwake2: - .long __lll_mutex_unlock_wake-.Lwake2b + .long __lll_unlock_wake-.Lwake2b .size pthread_barrier_wait,.-pthread_barrier_wait diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S 2006-09-18 06:49:04.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S 2007-08-01 09:49:37.000000000 +0900 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 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 @@ -18,19 +18,13 @@ #include #include +#include #include #include #include +#include #include "lowlevel-atomic.h" -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_REQUEUE 3 -#define FUTEX_CMP_REQUEUE 4 - -#define EINVAL 22 - .text /* int pthread_cond_broadcast (pthread_cond_t *cond) */ @@ -162,10 +156,12 @@ __pthread_cond_broadcast: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait5, r1 + mov #LLL_SHARED, r6 + extu.b r6, r6 + mov.l .Lwait5, r1 bsrf r1 mov r2, r4 -.Lmwait5b: +.Lwait5b: bra 2b nop @@ -175,10 +171,11 @@ __pthread_cond_broadcast: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake5, r1 + mov #LLL_SHARED, r5 + mov.l .Lwake5, r1 bsrf r1 - nop -.Lmwake5b: + extu.b r5, r5 +.Lwake5b: bra 6b nop @@ -188,10 +185,11 @@ __pthread_cond_broadcast: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake6, r1 + mov #LLL_SHARED, r5 + mov.l .Lwake6, r1 bsrf r1 - nop -.Lmwake6b: + extu.b r5, r5 +.Lwake6b: bra 8b nop @@ -208,12 +206,12 @@ __pthread_cond_broadcast: nop .align 2 -.Lmwait5: - .long __lll_mutex_lock_wait-.Lmwait5b -.Lmwake5: - .long __lll_mutex_unlock_wake-.Lmwake5b -.Lmwake6: - .long __lll_mutex_unlock_wake-.Lmwake6b +.Lwait5: + .long __lll_lock_wait-.Lwait5b +.Lwake5: + .long __lll_unlock_wake-.Lwake5b +.Lwake6: + .long __lll_unlock_wake-.Lwake6b .size __pthread_cond_broadcast, .-__pthread_cond_broadcast versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast, GLIBC_2_3_2) diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S 2004-06-18 08:55:56.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S 2007-08-01 09:52:30.000000000 +0900 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 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 @@ -18,17 +18,12 @@ #include #include +#include #include #include +#include #include "lowlevel-atomic.h" -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_REQUEUE 3 - -#define EINVAL 22 - .text /* int pthread_cond_signal (pthread_cond_t *cond) */ @@ -108,10 +103,12 @@ __pthread_cond_signal: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait4, r1 + mov #LLL_SHARED, r6 + extu.b r6, r6 + mov.l .Lwait4, r1 bsrf r1 mov r2, r4 -.Lmwait4b: +.Lwait4b: bra 2b nop @@ -121,18 +118,19 @@ __pthread_cond_signal: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake4, r1 + mov #LLL_SHARED, r5 + mov.l .Lwake4, r1 bsrf r1 - nop -.Lmwake4b: + extu.b r5, r5 +.Lwake4b: bra 6b nop .align 2 -.Lmwait4: - .long __lll_mutex_lock_wait-.Lmwait4b -.Lmwake4: - .long __lll_mutex_unlock_wake-.Lmwake4b +.Lwait4: + .long __lll_lock_wait-.Lwait4b +.Lwake4: + .long __lll_unlock_wake-.Lwake4b .size __pthread_cond_signal, .-__pthread_cond_signal versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal, GLIBC_2_3_2) diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S 2007-08-01 10:00:23.000000000 +0900 @@ -18,16 +18,11 @@ #include #include +#include #include #include #include "lowlevel-atomic.h" -#define SYS_gettimeofday __NR_gettimeofday -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 - - .text /* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, @@ -164,7 +159,7 @@ __pthread_cond_timedwait: mov r15, r4 add #16, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -182,7 +177,7 @@ __pthread_cond_timedwait: mov r15, r4 add #16, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -403,10 +398,12 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait2, r1 + mov #LLL_SHARED, r6 + extu.b r6, r6 + mov.l .Lwait2, r1 bsrf r1 mov r2, r4 -.Lmwait2b: +.Lwait2b: bra 2b nop @@ -416,10 +413,11 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake2, r1 + mov #LLL_SHARED, r5 + mov.l .Lmwait2, r1 bsrf r1 - nop -.Lmwake2b: + extu.b r5, r5 +.Lmwait2b: bra 4b nop @@ -429,10 +427,12 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait3, r1 + mov #LLL_SHARED, r6 + extu.b r6, r6 + mov.l .Lwait3, r1 bsrf r1 mov r2, r4 -.Lmwait3b: +.Lwait3b: bra 6b nop @@ -442,10 +442,11 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake3, r1 + mov #LLL_SHARED, r5 + mov.l .Lmwait3, r1 bsrf r1 - nop -.Lmwake3b: + extu.b r5, r5 +.Lmwait3b: bra 11b nop @@ -464,25 +465,26 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake4, r1 + mov #LLL_SHARED, r5 + mov.l .Lmwait4, r1 bsrf r1 - nop -.Lmwake4b: + extu.b r5, r5 +.Lmwait4b: 17: bra 18b mov.l @(24,r15), r0 .align 2 +.Lwait2: + .long __lll_lock_wait-.Lwait2b .Lmwait2: - .long __lll_mutex_lock_wait-.Lmwait2b -.Lmwake2: - .long __lll_mutex_unlock_wake-.Lmwake2b + .long __lll_unlock_wake-.Lmwait2b +.Lwait3: + .long __lll_lock_wait-.Lwait3b .Lmwait3: - .long __lll_mutex_lock_wait-.Lmwait3b -.Lmwake3: - .long __lll_mutex_unlock_wake-.Lmwake3b -.Lmwake4: - .long __lll_mutex_unlock_wake-.Lmwake4b + .long __lll_unlock_wake-.Lmwait3b +.Lmwait4: + .long __lll_unlock_wake-.Lmwait4b .size __pthread_cond_timedwait, .-__pthread_cond_timedwait versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait, GLIBC_2_3_2) @@ -507,10 +509,12 @@ __condvar_tw_cleanup: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait5, r1 + mov #LLL_SHARED, r6 + extu.b r6, r6 + mov.l .Lwait5, r1 bsrf r1 mov r2, r4 -.Lmwait5b: +.Lwait5b: 1: mov.l @(broadcast_seq,r8), r0 @@ -600,10 +604,11 @@ __condvar_tw_cleanup: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake5, r1 + mov #LLL_SHARED, r5 + mov.l .Lmwait5, r1 bsrf r1 - nop -.Lmwake5b: + extu.b r5, r5 +.Lmwait5b: 2: /* Wake up all waiters to make sure no signal gets lost. */ @@ -636,10 +641,10 @@ __condvar_tw_cleanup: sleep .align 2 +.Lwait5: + .long __lll_lock_wait-.Lwait5b .Lmwait5: - .long __lll_mutex_lock_wait-.Lmwait5b -.Lmwake5: - .long __lll_mutex_unlock_wake-.Lmwake5b + .long __lll_unlock_wake-.Lmwait5b .Lmlocki5: .long __pthread_mutex_cond_lock-.Lmlocki5b .Lresume: diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S 2007-08-01 10:04:30.000000000 +0900 @@ -18,14 +18,10 @@ #include #include +#include #include #include "lowlevel-atomic.h" -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 - - .text /* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */ @@ -267,10 +263,12 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait0, r1 + mov #LLL_SHARED, r6 + extu.b r6, r6 + mov.l .Lwait0, r1 bsrf r1 mov r2, r4 -.Lmwait0b: +.Lwait0b: bra 2b nop 3: @@ -279,10 +277,11 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake0, r1 + mov #LLL_SHARED, r5 + mov.l .Lwake0, r1 bsrf r1 - nop -.Lmwake0b: + extu.b r5, r5 +.Lwake0b: bra 4b nop @@ -292,10 +291,12 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait1, r1 + mov #LLL_SHARED, r6 + extu.b r6, r6 + mov.l .Lwait1, r1 bsrf r1 mov r2, r4 -.Lmwait1b: +.Lwait1b: bra 6b nop @@ -305,10 +306,11 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake1, r1 + mov #LLL_SHARED, r5 + mov.l .Lwake1, r1 bsrf r1 - nop -.Lmwake1b: + extu.b r5, r5 +.Lwake1b: bra 11b nop @@ -327,26 +329,27 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake2, r1 + mov #LLL_SHARED, r5 + mov.l .Lwake2, r1 bsrf r1 - nop -.Lmwake2b: + extu.b r5, r5 +.Lwake2b: 13: bra 14b mov.l @(12,r15), r0 .align 2 -.Lmwait0: - .long __lll_mutex_lock_wait-.Lmwait0b -.Lmwake0: - .long __lll_mutex_unlock_wake-.Lmwake0b -.Lmwait1: - .long __lll_mutex_lock_wait-.Lmwait1b -.Lmwake1: - .long __lll_mutex_unlock_wake-.Lmwake1b -.Lmwake2: - .long __lll_mutex_unlock_wake-.Lmwake2b +.Lwait0: + .long __lll_lock_wait-.Lwait0b +.Lwake0: + .long __lll_unlock_wake-.Lwake0b +.Lwait1: + .long __lll_lock_wait-.Lwait1b +.Lwake1: + .long __lll_unlock_wake-.Lwake1b +.Lwake2: + .long __lll_unlock_wake-.Lwake2b .size __pthread_cond_wait, .-__pthread_cond_wait versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait, GLIBC_2_3_2) @@ -371,10 +374,12 @@ __condvar_w_cleanup: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait3, r1 + mov #LLL_SHARED, r6 + extu.b r6, r6 + mov.l .Lwait3, r1 bsrf r1 mov r2, r4 -.Lmwait3b: +.Lwait3b: 1: mov.l @(broadcast_seq,r8), r0 @@ -464,10 +469,11 @@ __condvar_w_cleanup: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake3, r1 + mov #LLL_SHARED, r5 + mov.l .Lwake3, r1 bsrf r1 - nop -.Lmwake3b: + extu.b r5, r5 +.Lwake3b: 2: /* Wake up all waiters to make sure no signal gets lost. */ @@ -500,10 +506,10 @@ __condvar_w_cleanup: sleep .align 2 -.Lmwait3: - .long __lll_mutex_lock_wait-.Lmwait3b -.Lmwake3: - .long __lll_mutex_unlock_wake-.Lmwake3b +.Lwait3: + .long __lll_lock_wait-.Lwait3b +.Lwake3: + .long __lll_unlock_wake-.Lwake3b .Lmlocki3: .long __pthread_mutex_cond_lock-.Lmlocki3b .Lresume: diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S 2007-07-31 20:37:32.000000000 +0900 @@ -19,12 +19,9 @@ #include #include #include +#include #include "lowlevel-atomic.h" -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_PRIVATE_FLAG 128 .comm __fork_generation, 4, 4 diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S 2007-08-01 10:22:01.000000000 +0900 @@ -17,17 +17,13 @@ 02111-1307 USA. */ #include +#include #include #include #include #include #include "lowlevel-atomic.h" -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_PRIVATE_FLAG 128 - .text @@ -156,10 +152,12 @@ __pthread_rwlock_rdlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait0, r1 bsrf r1 - nop + mov r2, r4 .Lwait0b: bra 2b nop @@ -182,6 +180,9 @@ __pthread_rwlock_rdlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake0, r1 bsrf r1 nop @@ -210,6 +211,9 @@ __pthread_rwlock_rdlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake1, r1 bsrf r1 nop @@ -222,23 +226,25 @@ __pthread_rwlock_rdlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait1, r1 bsrf r1 - nop + mov r2, r4 .Lwait1b: bra 13b nop .align 2 .Lwait0: - .long __lll_mutex_lock_wait-.Lwait0b + .long __lll_lock_wait-.Lwait0b .Lwake0: - .long __lll_mutex_unlock_wake-.Lwake0b + .long __lll_unlock_wake-.Lwake0b .Lwait1: - .long __lll_mutex_lock_wait-.Lwait1b + .long __lll_lock_wait-.Lwait1b .Lwake1: - .long __lll_mutex_unlock_wake-.Lwake1b + .long __lll_unlock_wake-.Lwake1b .size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock .globl pthread_rwlock_rdlock diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S 2007-08-01 14:42:21.000000000 +0900 @@ -17,18 +17,13 @@ 02111-1307 USA. */ #include +#include #include #include #include #include #include "lowlevel-atomic.h" -#define SYS_gettimeofday __NR_gettimeofday -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_PRIVATE_FLAG 128 - .text @@ -92,7 +87,7 @@ pthread_rwlock_timedrdlock: /* Get current time. */ mov r15, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -213,10 +208,12 @@ pthread_rwlock_timedrdlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait2, r1 bsrf r1 - nop + mov r2, r4 .Lwait2b: bra 2b nop @@ -239,6 +236,9 @@ pthread_rwlock_timedrdlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake2, r1 bsrf r1 nop @@ -267,6 +267,9 @@ pthread_rwlock_timedrdlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake3, r1 bsrf r1 nop @@ -279,10 +282,12 @@ pthread_rwlock_timedrdlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait3, r1 bsrf r1 - nop + mov r2, r4 .Lwait3b: bra 13b nop @@ -297,11 +302,11 @@ pthread_rwlock_timedrdlock: .align 2 .Lwait2: - .long __lll_mutex_lock_wait-.Lwait2b + .long __lll_lock_wait-.Lwait2b .Lwake2: - .long __lll_mutex_unlock_wake-.Lwake2b + .long __lll_unlock_wake-.Lwake2b .Lwait3: - .long __lll_mutex_lock_wait-.Lwait3b + .long __lll_lock_wait-.Lwait3b .Lwake3: - .long __lll_mutex_unlock_wake-.Lwake3b + .long __lll_unlock_wake-.Lwake3b .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S 2007-08-01 10:28:41.000000000 +0900 @@ -17,18 +17,13 @@ 02111-1307 USA. */ #include +#include #include #include #include #include #include "lowlevel-atomic.h" -#define SYS_gettimeofday __NR_gettimeofday -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_PRIVATE_FLAG 128 - .text @@ -88,7 +83,7 @@ pthread_rwlock_timedwrlock: /* Get current time. */ mov r15, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -211,10 +206,12 @@ pthread_rwlock_timedwrlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait6, r1 bsrf r1 - nop + mov r2, r4 .Lwait6b: bra 2b nop @@ -232,6 +229,9 @@ pthread_rwlock_timedwrlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake6, r1 bsrf r1 nop @@ -255,6 +255,9 @@ pthread_rwlock_timedwrlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake7, r1 bsrf r1 nop @@ -267,10 +270,12 @@ pthread_rwlock_timedwrlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait7, r1 bsrf r1 - nop + mov r2, r4 .Lwait7b: bra 13b nop @@ -281,11 +286,11 @@ pthread_rwlock_timedwrlock: .align 2 .Lwait6: - .long __lll_mutex_lock_wait-.Lwait6b + .long __lll_lock_wait-.Lwait6b .Lwake6: - .long __lll_mutex_unlock_wake-.Lwake6b + .long __lll_unlock_wake-.Lwake6b .Lwait7: - .long __lll_mutex_lock_wait-.Lwait7b + .long __lll_lock_wait-.Lwait7b .Lwake7: - .long __lll_mutex_unlock_wake-.Lwake7b + .long __lll_unlock_wake-.Lwake7b .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S 2007-08-01 10:32:50.000000000 +0900 @@ -17,15 +17,11 @@ 02111-1307 USA. */ #include +#include #include #include #include "lowlevel-atomic.h" -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_PRIVATE_FLAG 128 - .text @@ -138,10 +134,12 @@ __pthread_rwlock_unlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait8, r1 bsrf r1 - nop + mov r2, r4 .Lwait8b: bra 2b nop @@ -150,6 +148,9 @@ __pthread_rwlock_unlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake8, r1 bsrf r1 nop @@ -164,6 +165,9 @@ __pthread_rwlock_unlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake9, r1 bsrf r1 nop @@ -179,11 +183,11 @@ __pthread_rwlock_unlock: #endif .align 2 .Lwait8: - .long __lll_mutex_lock_wait-.Lwait8b + .long __lll_lock_wait-.Lwait8b .Lwake8: - .long __lll_mutex_unlock_wake-.Lwake8b + .long __lll_unlock_wake-.Lwake8b .Lwake9: - .long __lll_mutex_unlock_wake-.Lwake9b + .long __lll_unlock_wake-.Lwake9b .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock .globl pthread_rwlock_unlock diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S 2007-08-01 10:36:18.000000000 +0900 @@ -17,17 +17,13 @@ 02111-1307 USA. */ #include +#include #include #include #include #include #include "lowlevel-atomic.h" -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define FUTEX_PRIVATE_FLAG 128 - .text @@ -145,10 +141,12 @@ __pthread_rwlock_wrlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait4, r1 bsrf r1 - nop + mov r2, r4 .Lwait4b: bra 2b nop @@ -166,6 +164,9 @@ __pthread_rwlock_wrlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake4, r1 bsrf r1 nop @@ -192,6 +193,9 @@ __pthread_rwlock_wrlock: #if MUTEX != 0 add #MUTEX, r4 #endif + mov #PSHARED, r0 + mov.b @(r0,r8), r5 + extu.b r5, r5 mov.l .Lwake5, r1 bsrf r1 nop @@ -204,23 +208,25 @@ __pthread_rwlock_wrlock: #if MUTEX != 0 add #MUTEX, r5 #endif - mov r2, r4 + mov #PSHARED, r0 + mov.b @(r0,r8), r6 + extu.b r6, r6 mov.l .Lwait5, r1 bsrf r1 - nop + mov r2, r4 .Lwait5b: bra 13b nop .align 2 .Lwait4: - .long __lll_mutex_lock_wait-.Lwait4b + .long __lll_lock_wait-.Lwait4b .Lwake4: - .long __lll_mutex_unlock_wake-.Lwake4b + .long __lll_unlock_wake-.Lwake4b .Lwait5: - .long __lll_mutex_lock_wait-.Lwait5b + .long __lll_lock_wait-.Lwait5b .Lwake5: - .long __lll_mutex_unlock_wake-.Lwake5b + .long __lll_unlock_wake-.Lwake5b .globl pthread_rwlock_wrlock pthread_rwlock_wrlock = __pthread_rwlock_wrlock diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S 2007-08-01 17:23:23.000000000 +0900 @@ -20,14 +20,10 @@ #include #include #include +#include #include "lowlevel-atomic.h" -#define SYS_gettimeofday __NR_gettimeofday -#define SYS_futex 240 -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 - .text .globl __new_sem_post @@ -65,7 +61,12 @@ __new_sem_post: mov.l .Lerrno3, r0 stc gbr, r1 mov.l @(r0, r12), r0 - add r1, r0 + bra .Lexit + add r1, r0 + .align 2 +.Lerrno3: + .long errno@GOTTPOFF +.Lexit: #else mov.l .Lerrloc3, r1 bsrf r1 @@ -81,10 +82,7 @@ __new_sem_post: .align 2 .Lgot3: .long _GLOBAL_OFFSET_TABLE_ -#if USE___THREAD -.Lerrno3: - .long errno@GOTTPOFF -#else +#if !USE___THREAD .Lerrloc3: .long __errno_location@PLT-(.Lerrloc3b-.) #endif diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S 2007-08-01 17:24:02.000000000 +0900 @@ -21,13 +21,10 @@ #include #include #include +#include #include "lowlevel-atomic.h" -#define SYS_gettimeofday __NR_gettimeofday -#define SYS_futex 240 -#define FUTEX_WAIT 0 - #if VALUE != 0 # error "code needs to be rewritten for VALUE != 0" #endif @@ -81,7 +78,7 @@ sem_timedwait: /* Compute relative timeout. */ mov r15, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -180,15 +177,19 @@ sem_timedwait: mov.l .Lerrno2, r0 stc gbr, r1 mov.l @(r0, r12), r0 - add r1, r0 - mov.l r10, @r0 + bra .Lexit + add r1, r0 + .align 2 +.Lerrno2: + .long errno@GOTTPOFF +.Lexit: #else mov.l .Lerrloc2, r1 bsrf r1 nop .Lerrloc2b: - mov.l r10, @r0 #endif + mov.l r10, @r0 DEC (@(NWAITERS,r8), r2) bra 10b mov #-1, r0 @@ -200,10 +201,7 @@ sem_timedwait: .long 1000000000 .Lgot2: .long _GLOBAL_OFFSET_TABLE_ -#if USE___THREAD -.Lerrno2: - .long errno@GOTTPOFF -#else +#if !USE___THREAD .Lerrloc2: .long __errno_location@PLT-(.Lerrloc2b-.) #endif diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S 2004-06-30 00:51:02.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S 2007-08-01 17:22:26.000000000 +0900 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 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 @@ -19,6 +19,7 @@ #include #include #include +#include #include "lowlevel-atomic.h" @@ -60,15 +61,19 @@ __new_sem_trywait: mov.l .Lerrno1, r0 stc gbr, r1 mov.l @(r0, r12), r0 - add r1, r0 - mov.l r8, @r0 + bra .Lexit + add r1, r0 + .align 2 +.Lerrno1: + .long errno@GOTTPOFF +.Lexit: #else mov.l .Lerrloc1, r1 bsrf r1 nop .Lerrloc1b: - mov.l r8, @r0 #endif + mov.l r8, @r0 lds.l @r15+, pr mov.l @r15+, r8 mov.l @r15+, r12 @@ -78,10 +83,7 @@ __new_sem_trywait: .align 2 .Lgot1: .long _GLOBAL_OFFSET_TABLE_ -#if USE___THREAD -.Lerrno1: - .long errno@GOTTPOFF -#else +#if !USE___THREAD .Lerrloc1: .long __errno_location@PLT-(.Lerrloc1b-.) #endif diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S 2007-06-18 09:03:43.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S 2007-08-01 17:21:55.000000000 +0900 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 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 @@ -21,13 +21,10 @@ #include #include #include +#include #include "lowlevel-atomic.h" -#define SYS_gettimeofday __NR_gettimeofday -#define SYS_futex 240 -#define FUTEX_WAIT 0 - #if VALUE != 0 # error "code needs to be rewritten for VALUE != 0" #endif @@ -138,24 +135,26 @@ __new_sem_wait: mov.l .Lerrno0, r0 stc gbr, r1 mov.l @(r0, r12), r0 - add r1, r0 - mov.l r8, @r0 + bra .Lexit + add r1, r0 + .align 2 +.Lerrno0: + .long errno@GOTTPOFF +.Lexit: #else mov.l .Lerrloc0, r1 bsrf r1 nop .Lerrloc0b: - mov.l r8, @r0 #endif + mov.l r8, @r0 bra 9b mov #-1, r0 + .align 2 .Lgot0: .long _GLOBAL_OFFSET_TABLE_ -#if USE___THREAD -.Lerrno0: - .long errno@GOTTPOFF -#else +#if !USE___THREAD .Lerrloc0: .long __errno_location@PLT-(.Lerrloc0b-.) #endif From jakub@redhat.com Fri Aug 3 10:58:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 03 Aug 2007 10:58:00 -0000 Subject: [PATCH] Add l with stroke transliteration Message-ID: <20070803110249.GD4603@sunsite.mff.cuni.cz> Hi! http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=250492 requests adding transliteration of Polish [lL] with stroke, which makes sense to me, e.g. Slovak [lL] with caron is already transliterated as [lL]. 2007-08-03 Jakub Jelinek * locales/translit_combining: Add U0141 and U0142. --- libc/localedata/locales/translit_combining.jj 2002-04-20 09:12:59.000000000 +0200 +++ libc/localedata/locales/translit_combining 2007-08-03 12:37:15.000000000 +0200 @@ -472,6 +472,10 @@ translit_start % LATIN SMALL LETTER L WITH CARON +% LATIN CAPITAL LETTER L WITH STROKE + +% LATIN SMALL LETTER L WITH STROKE + % LATIN CAPITAL LETTER N WITH ACUTE % LATIN SMALL LETTER N WITH ACUTE Jakub From jakub@redhat.com Fri Aug 3 11:56:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 03 Aug 2007 11:56:00 -0000 Subject: [PATCH] Memory leak fixes for gettext Message-ID: <20070803120122.GE4603@sunsite.mff.cuni.cz> Hi! Although we store strduped encoding in convd->encoding, when we return NULL because __gconv_open failed, we haven't yet done domain->nconversions++ and therefore that string will be definitely leaked. While testing this I also discovered that _nl_find_domain can leak memory on failure and so can dl-load. The patch below fixes the two spots in intl and one in dl-load.c, though I'm afraid there are many other places in ld.so which can leak memory, as _dl_signal_*error is used pretty heavily. E.g. when /* It's a new directory. Create an entry and add it. */ dirp = (struct r_search_path_elem *) malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status) + where_len + len + 1); if (dirp == NULL) _dl_signal_error (ENOMEM, NULL, NULL, N_("cannot create cache for search path")); in fillin_rpath calls _dl_signal_error, copy and result in decompose_rpath are leaked. 2007-08-03 Jakub Jelinek * intl/dcigettext.c (_nl_find_msg): Free encoding if __gconv_open failed. * intl/finddomain.c (_nl_find_domain): Free normalized_codeset on failure. * elf/dl-load.c (decompose_rpath): Free copy if result couldn't be allocated. --- libc/intl/dcigettext.c.jj 2007-07-29 11:45:13.000000000 +0200 +++ libc/intl/dcigettext.c 2007-08-03 13:27:24.000000000 +0200 @@ -949,7 +949,10 @@ _nl_find_msg (domain_file, domainbinding nothing to do. Otherwise do not use the translation at all. */ if (__builtin_expect (r != __GCONV_NULCONV, 1)) - return NULL; + { + free ((char *) encoding); + return NULL; + } convd->conv = (__gconv_t) -1; } --- libc/intl/finddomain.c.jj 2007-07-13 10:18:07.000000000 +0200 +++ libc/intl/finddomain.c 2007-08-03 13:32:27.000000000 +0200 @@ -143,7 +143,7 @@ _nl_find_domain (dirname, locale, domain if (retval == NULL) /* This means we are out of core. */ - return NULL; + goto out; if (retval->decided <= 0) _nl_load_domain (retval, domainbinding); @@ -159,6 +159,7 @@ _nl_find_domain (dirname, locale, domain } } +out: /* The space for normalized_codeset is dynamically allocated. Free it. */ if (mask & XPG_NORM_CODESET) free ((void *) normalized_codeset); --- libc/elf/dl-load.c.jj 2007-07-13 10:18:07.000000000 +0200 +++ libc/elf/dl-load.c 2007-08-03 13:39:18.000000000 +0200 @@ -578,6 +578,7 @@ decompose_rpath (struct r_search_path_st * sizeof (*result)); if (result == NULL) { + free (copy); errstring = N_("cannot create cache for search path"); signal_error: _dl_signal_error (ENOMEM, NULL, NULL, errstring); Jakub From drepper@redhat.com Fri Aug 3 15:48:00 2007 From: drepper@redhat.com (Ulrich Drepper) Date: Fri, 03 Aug 2007 15:48:00 -0000 Subject: [PATCH] lowlevellock.h cleanups, LLL_SHARED vs. LLL_PRIVATE on lll locks In-Reply-To: <20070802.080027.08326116.kkojima@rr.iij4u.or.jp> References: <20070725201502.GI4603@sunsite.mff.cuni.cz> <20070731111453.GZ4603@sunsite.mff.cuni.cz> <20070802.080027.08326116.kkojima@rr.iij4u.or.jp> Message-ID: <46B34E36.3050609@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Applied. - -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFGs0422ijCOnn/RHQRAjJ0AJ4kH4+GaJbXvsCKYnT418gmeKvTDQCfTgXS QZtQ8kPhh8CGRDJOot8JNbg= =dWBY -----END PGP SIGNATURE----- From jakub@redhat.com Fri Aug 3 16:34:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 03 Aug 2007 16:34:00 -0000 Subject: [PATCH] Return minus_zero for strtod ("-0", NULL) Message-ID: <20070803163849.GF4603@sunsite.mff.cuni.cz> Hi! Until recently strtod ("-0", NULL) returned -0.0, not because the code tried to handle it, but because of a bug: http://sourceware.org/cgi-bin/cvsweb.cgi/libc/stdlib/strtod_l.c.diff?cvsroot=glibc&r1=1.16&r2=1.18 When we don't take any of the shortpaths, round_and_return still return -0.0, so I think we should handle it even in the shortpaths. strtod ("-0.0", NULL) even in current glibc returns -0.0. 2007-08-03 Jakub Jelinek * stdlib/strtod_l.c (____STRTOF_INTERNAL): Properly handle -0. * stdlib/Makefile (tests): Add tst-strtod5. (tst-strtod5-ENV): New. * stdlib/tst-strtod5.c: New test. --- libc/stdlib/strtod_l.c.jj 2007-02-22 08:46:24.000000000 +0100 +++ libc/stdlib/strtod_l.c 2007-08-03 17:56:30.000000000 +0200 @@ -700,7 +700,8 @@ ____STRTOF_INTERNAL (nptr, endptr, group #endif /* If TP is at the start of the digits, there was no correctly grouped prefix of the string; so no number found. */ - RETURN (0.0, tp == start_of_digits ? (base == 16 ? cp - 1 : nptr) : tp); + RETURN (negative ? -0.0 : 0.0, + tp == start_of_digits ? (base == 16 ? cp - 1 : nptr) : tp); } /* Remember first significant digit and read following characters until the @@ -759,7 +760,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group if (tp < startp) /* The number is validly grouped, but consists only of zeroes. The whole value is zero. */ - RETURN (0.0, tp); + RETURN (negative ? -0.0 : 0.0, tp); /* Recompute DIG_NO so we won't read more digits than are properly grouped. */ @@ -862,7 +863,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group { /* Overflow or underflow. */ __set_errno (ERANGE); - result = (exp_negative ? 0.0 : + result = (exp_negative ? (negative ? -0.0 : 0.0) : negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL); } --- libc/stdlib/Makefile.jj 2007-01-15 23:25:30.000000000 +0100 +++ libc/stdlib/Makefile 2007-08-03 18:12:18.000000000 +0200 @@ -68,7 +68,7 @@ tests := tst-strtol tst-strtod testmb t tst-limits tst-rand48 bug-strtod tst-setcontext \ test-a64l tst-qsort tst-system testmb2 bug-strtod2 \ tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \ - tst-makecontext tst-strtod4 + tst-makecontext tst-strtod4 tst-strtod5 include ../Makeconfig @@ -115,6 +115,7 @@ test-canon-ARGS = --test-dir=${common-ob tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata tst-strtod3-ENV = LOCPATH=$(common-objpfx)localedata tst-strtod4-ENV = LOCPATH=$(common-objpfx)localedata +tst-strtod5-ENV = LOCPATH=$(common-objpfx)localedata testmb2-ENV = LOCPATH=$(common-objpfx)localedata # Run a test on the header files we use. --- libc/stdlib/tst-strtod5.c.jj 2007-08-03 18:03:43.000000000 +0200 +++ libc/stdlib/tst-strtod5.c 2007-08-03 18:21:37.000000000 +0200 @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include + +#define NBSP "\xc2\xa0" + +static const struct +{ + const char *in; + int group; + double expected; +} tests[] = + { + { "0", 0, 0.0 }, + { "000", 0, 0.0 }, + { "-0", 0, -0.0 }, + { "-000", 0, -0.0 }, + { "0,", 0, 0.0 }, + { "-0,", 0, -0.0 }, + { "0,0", 0, 0.0 }, + { "-0,0", 0, -0.0 }, + { "0e-10", 0, 0.0 }, + { "-0e-10", 0, -0.0 }, + { "0,e-10", 0, 0.0 }, + { "-0,e-10", 0, -0.0 }, + { "0,0e-10", 0, 0.0 }, + { "-0,0e-10", 0, -0.0 }, + { "0e-1000000", 0, 0.0 }, + { "-0e-1000000", 0, -0.0 }, + { "0,0e-1000000", 0, 0.0 }, + { "-0,0e-1000000", 0, -0.0 }, + { "0", 1, 0.0 }, + { "000", 1, 0.0 }, + { "-0", 1, -0.0 }, + { "-000", 1, -0.0 }, + { "0e-10", 1, 0.0 }, + { "-0e-10", 1, -0.0 }, + { "0e-1000000", 1, 0.0 }, + { "-0e-1000000", 1, -0.0 }, + { "000"NBSP"000"NBSP"000", 1, 0.0 }, + { "-000"NBSP"000"NBSP"000", 1, -0.0 } + }; +#define NTESTS (sizeof (tests) / sizeof (tests[0])) + + +static int +do_test (void) +{ + if (setlocale (LC_ALL, "cs_CZ.UTF-8") == NULL) + { + puts ("could not set locale"); + return 1; + } + + int status = 0; + + for (int i = 0; i < NTESTS; ++i) + { + char *ep; + double r; + + if (tests[i].group) + r = __strtod_internal (tests[i].in, &ep, 1); + else + r = strtod (tests[i].in, &ep); + + if (*ep != '\0') + { + printf ("%d: got rest string \"%s\", expected \"\"\n", i, ep); + status = 1; + } + + if (r != tests[i].expected + || copysign (10.0, r) != copysign (10.0, tests[i].expected)) + { + printf ("%d: got wrong results %g, expected %g\n", + i, r, tests[i].expected); + status = 1; + } + } + + return status; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" Jakub From kkojima@rr.iij4u.or.jp Sat Aug 4 01:38:00 2007 From: kkojima@rr.iij4u.or.jp (Kaz Kojima) Date: Sat, 04 Aug 2007 01:38:00 -0000 Subject: [PATCH] lowlevellock.h cleanups, LLL_SHARED vs. LLL_PRIVATE on lll locks In-Reply-To: <46B34E36.3050609@redhat.com> References: <20070731111453.GZ4603@sunsite.mff.cuni.cz> <20070802.080027.08326116.kkojima@rr.iij4u.or.jp> <46B34E36.3050609@redhat.com> Message-ID: <20070804.103741.95900246.kkojima@rr.iij4u.or.jp> Ulrich Drepper wrote: > Applied. Thanks! Regards, kaz From jakub@redhat.com Mon Aug 6 19:30:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 06 Aug 2007 19:30:00 -0000 Subject: [PATCH] private futex for pthread_mutex_* and pthread_cond_* Message-ID: <20070806193545.GH4603@sunsite.mff.cuni.cz> Hi! Only very lightly tested on ppc and x86_64, no asm implementation for i?86 nor sh. Robust mutexes still use non-private futexes, as kernel when waking up on thread exit uses FUTEX_WAKE, not FUTEX_WAKE|FUTEX_PRIVATE_FLAG. Similarly, FUTEX_CMP_REQUEUE can't be used if CV is private (we never did requeue for shared CVs) but the dep mutex is shared (I guess that's quite unlikely, so no big deal). 2007-08-06 Jakub Jelinek * pthreadP.h (PTHREAD_MUTEX_PSHARED_BIT): Define. (PTHREAD_MUTEX_TYPE): Mask __kind with 127. (PTHREAD_MUTEX_PSHARED): Define. * pthread_mutex_init.c (__pthread_mutex_init): Set PTHREAD_MUTEX_PSHARED_BIT for pshared or robust mutexes. * pthread_mutex_lock.c (LLL_MUTEX_LOCK): Take mutex as argument instead of its __data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument to lll_lock. (LLL_MUTEX_TRYLOCK): Take mutex as argument instead of its __data.__lock field. (LLL_ROBUST_MUTEX_LOCK): Take mutex as argument instead of its __data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument to lll_robust_lock. (__pthread_mutex_lock): Update LLL_MUTEX_LOCK, LLL_MUTEX_TRYLOCK, LLL_ROBUST_MUTEX_LOCK users, use PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind directly, pass PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock and lll_futex_wait. * pthread_mutex_trylock.c (__pthread_mutex_trylock): Use PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind directly, pass PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock. (pthread_mutex_timedlock): Pass PTHREAD_MUTEX_PSHARED (mutex) to lll_timedlock, lll_robust_timedlock, lll_unlock and lll_futex_timed_wait. Use PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind directly. * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Pass PTHREAD_MUTEX_PSHARED (mutex) to lll_timedlock, lll_robust_timedlock, lll_unlock and lll_futex_timed_wait. Use PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind directly. * pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt): Pass PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock, lll_robust_unlock and lll_futex_wake. * pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling): Pass PTHREAD_MUTEX_PSHARED (mutex) to lll_futex_wait and lll_futex_wake. Use PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind directly. * sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c (LLL_MUTEX_LOCK): Take mutex as argument instead of its __data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument to lll_cond_lock. (LLL_MUTEX_TRYLOCK): Take mutex as argument instead of its __data.__lock field. (LLL_ROBUST_MUTEX_LOCK): Take mutex as argument instead of its __data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument to lll_robust_cond_lock. * pthread_cond_broadcast.c (__pthread_cond_broadcast): Add pshared variable, pass it to lll_lock, lll_unlock, lll_futex_requeue and lll_futex_wake. Don't use lll_futex_requeue if dependent mutex has PTHREAD_MUTEX_PSHARED_BIT bit set in its __data.__kind. * pthread_cond_destroy.c (__pthread_cond_destroy): Add pshared variable, pass it to lll_lock, lll_unlock, lll_futex_wake and lll_futex_wait. * pthread_cond_signal.c (__pthread_cond_signal): Add pshared variable, pass it to lll_lock, lll_unlock, lll_futex_wake_unlock and lll_futex_wake. * pthread_cond_timedwait.c (__pthread_cond_wait): Add pshared variable, pass it to lll_lock, lll_unlock, lll_futex_timedwait and lll_futex_wake. * pthread_cond_wait.c (__condvar_cleanup, __pthread_cond_wait): Add pshared variable, pass it to lll_lock, lll_unlock, lll_futex_wait and lll_futex_wake. * sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_futex_requeue, lll_futex_wake_unlock): Add private argument, use __lll_private_flag macro. * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (lll_futex_requeue, lll_futex_wake_unlock): Likewise. * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (lll_futex_requeue): Likewise. * sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_futex_requeue, lll_futex_wake_unlock): Likewise. * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_futex_requeue): Likewise. * sysdeps/unix/sysv/linux/s390/lowlevellock.h (lll_futex_requeue, lll_futex_wake_unlock): Likewise. (lll_futex_wake): Fix a typo. * sysdeps/unix/sysv/linux/pthread-pi-defines.sym (PS_BIT): Add. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S (__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S (__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S (__pthread_cond_timedwait): Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: (__condvar_cleanup, __pthread_cond_wait): Likewise. --- libc/nptl/pthread_mutex_timedlock.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_mutex_timedlock.c 2007-08-06 15:50:10.000000000 +0200 @@ -57,7 +57,7 @@ pthread_mutex_timedlock (mutex, abstime) /* We have to get the mutex. */ result = lll_timedlock (mutex->__data.__lock, abstime, - /* XYZ */ LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); if (result != 0) goto out; @@ -78,7 +78,7 @@ pthread_mutex_timedlock (mutex, abstime) simple: /* Normal mutex. */ result = lll_timedlock (mutex->__data.__lock, abstime, - /* XYZ */ LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); break; case PTHREAD_MUTEX_ADAPTIVE_NP: @@ -95,7 +95,7 @@ pthread_mutex_timedlock (mutex, abstime) if (cnt++ >= max_cnt) { result = lll_timedlock (mutex->__data.__lock, abstime, - /* XYZ */ LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); break; } @@ -152,16 +152,15 @@ pthread_mutex_timedlock (mutex, abstime) /* Check whether we already hold the mutex. */ if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0)) { - if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + int kind = PTHREAD_MUTEX_TYPE (mutex); + if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) { THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return EDEADLK; } - if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) + if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) { THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); @@ -178,14 +177,14 @@ pthread_mutex_timedlock (mutex, abstime) } result = lll_robust_timedlock (mutex->__data.__lock, abstime, id, - /* XYZ */ LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); if (__builtin_expect (mutex->__data.__owner == PTHREAD_MUTEX_NOTRECOVERABLE, 0)) { /* This mutex is now not recoverable. */ mutex->__data.__count = 0; - lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)); THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return ENOTRECOVERABLE; } @@ -446,8 +445,7 @@ pthread_mutex_timedlock (mutex, abstime) lll_futex_timed_wait (&mutex->__data.__lock, ceilval | 2, &rt, - // XYZ check mutex flag - LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); } } while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, --- libc/nptl/pthread_mutex_unlock.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_mutex_unlock.c 2007-08-06 15:50:10.000000000 +0200 @@ -61,7 +61,7 @@ __pthread_mutex_unlock_usercnt (mutex, d --mutex->__data.__nusers; /* Unlock. */ - lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)); break; case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP: @@ -115,7 +115,7 @@ __pthread_mutex_unlock_usercnt (mutex, d --mutex->__data.__nusers; /* Unlock. */ - lll_robust_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED); + lll_robust_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)); THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); break; @@ -242,8 +242,7 @@ __pthread_mutex_unlock_usercnt (mutex, d if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1) lll_futex_wake (&mutex->__data.__lock, 1, - // XYZ check mutex flag - LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); int oldprio = newval >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT; return __pthread_tpp_change_priority (oldprio, -1); --- libc/nptl/pthread_cond_destroy.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_cond_destroy.c 2007-08-06 15:50:10.000000000 +0200 @@ -26,14 +26,17 @@ int __pthread_cond_destroy (cond) pthread_cond_t *cond; { + int pshared = (cond->__data.__mutex == (void *) ~0l) + ? LLL_SHARED : LLL_PRIVATE; + /* Make sure we are alone. */ - lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cond->__data.__lock, pshared); if (cond->__data.__total_seq > cond->__data.__wakeup_seq) { /* If there are still some waiters which have not been woken up, this is an application bug. */ - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); return EBUSY; } @@ -60,19 +63,16 @@ __pthread_cond_destroy (cond) { pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex; lll_futex_wake (&mut->__data.__lock, INT_MAX, - // XYZ check mutex flag - LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mut)); } do { - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); - lll_futex_wait (&cond->__data.__nwaiters, nwaiters, - // XYZ check mutex flag - LLL_SHARED); + lll_futex_wait (&cond->__data.__nwaiters, nwaiters, pshared); - lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cond->__data.__lock, pshared); nwaiters = cond->__data.__nwaiters; } --- libc/nptl/pthread_mutex_init.c.jj 2006-08-15 01:00:38.000000000 +0200 +++ libc/nptl/pthread_mutex_init.c 2007-08-06 15:50:10.000000000 +0200 @@ -1,4 +1,5 @@ -/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -120,6 +121,12 @@ __pthread_mutex_init (mutex, mutexattr) break; } + /* Kernel when waking robust mutexes on exit always uses + !FUTEX_PRIVATE_FLAG FUTEX_WAKE. */ + if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED + | PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0) + mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT; + /* Default values: mutex not used yet. */ // mutex->__count = 0; already done by memset // mutex->__owner = 0; already done by memset --- libc/nptl/pthread_cond_wait.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_cond_wait.c 2007-08-06 15:50:10.000000000 +0200 @@ -43,9 +43,11 @@ __condvar_cleanup (void *arg) struct _condvar_cleanup_buffer *cbuffer = (struct _condvar_cleanup_buffer *) arg; unsigned int destroying; + int pshared = (cbuffer->cond->__data.__mutex == (void *) ~0l) + ? LLL_SHARED : LLL_PRIVATE; /* We are going to modify shared data. */ - lll_lock (cbuffer->cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cbuffer->cond->__data.__lock, pshared); if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq) { @@ -71,20 +73,16 @@ __condvar_cleanup (void *arg) if (cbuffer->cond->__data.__total_seq == -1ULL && cbuffer->cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT)) { - lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1, - // XYZ check mutex flag - LLL_SHARED); + lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1, pshared); destroying = 1; } /* We are done. */ - lll_unlock (cbuffer->cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cbuffer->cond->__data.__lock, pshared); /* Wake everybody to make sure no condvar signal gets lost. */ if (! destroying) - lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, - // XYZ check mutex flag - LLL_SHARED); + lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, pshared); /* Get the mutex before returning unless asynchronous cancellation is in effect. */ @@ -100,15 +98,17 @@ __pthread_cond_wait (cond, mutex) struct _pthread_cleanup_buffer buffer; struct _condvar_cleanup_buffer cbuffer; int err; + int pshared = (cond->__data.__mutex == (void *) ~0l) + ? LLL_SHARED : LLL_PRIVATE; /* Make sure we are along. */ - lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cond->__data.__lock, pshared); /* Now we can release the mutex. */ err = __pthread_mutex_unlock_usercnt (mutex, 0); if (__builtin_expect (err, 0)) { - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); return err; } @@ -144,21 +144,19 @@ __pthread_cond_wait (cond, mutex) unsigned int futex_val = cond->__data.__futex; /* Prepare to wait. Release the condvar futex. */ - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); /* Enable asynchronous cancellation. Required by the standard. */ cbuffer.oldtype = __pthread_enable_asynccancel (); /* Wait until woken by signal or broadcast. */ - lll_futex_wait (&cond->__data.__futex, futex_val, - // XYZ check mutex flag - LLL_SHARED); + lll_futex_wait (&cond->__data.__futex, futex_val, pshared); /* Disable asynchronous cancellation. */ __pthread_disable_asynccancel (cbuffer.oldtype); /* We are going to look at shared data again, so get the lock. */ - lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cond->__data.__lock, pshared); /* If a broadcast happened, we are done. */ if (cbuffer.bc_seq != cond->__data.__broadcast_seq) @@ -181,12 +179,10 @@ __pthread_cond_wait (cond, mutex) and it can be successfully destroyed. */ if (cond->__data.__total_seq == -1ULL && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT)) - lll_futex_wake (&cond->__data.__nwaiters, 1, - // XYZ check mutex flag - LLL_SHARED); + lll_futex_wake (&cond->__data.__nwaiters, 1, pshared); /* We are done with the condvar. */ - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); /* The cancellation handling is back to normal, remove the handler. */ __pthread_cleanup_pop (&buffer, 0); --- libc/nptl/pthread_cond_broadcast.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_cond_broadcast.c 2007-08-06 15:50:10.000000000 +0200 @@ -32,8 +32,10 @@ int __pthread_cond_broadcast (cond) pthread_cond_t *cond; { + int pshared = (cond->__data.__mutex == (void *) ~0l) + ? LLL_SHARED : LLL_PRIVATE; /* Make sure we are alone. */ - lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cond->__data.__lock, pshared); /* Are there any waiters to be woken? */ if (cond->__data.__total_seq > cond->__data.__wakeup_seq) @@ -47,7 +49,7 @@ __pthread_cond_broadcast (cond) ++cond->__data.__broadcast_seq; /* We are done. */ - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); /* Do not use requeue for pshared condvars. */ if (cond->__data.__mutex == (void *) ~0l) @@ -57,21 +59,22 @@ __pthread_cond_broadcast (cond) pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex; /* XXX: Kernel so far doesn't support requeue to PI futex. */ - if (__builtin_expect (mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP, - 0)) + /* XXX: Kernel so far can only requeue to the same type of futex, + in this case private (we don't requeue for pshared condvars). */ + if (__builtin_expect (mut->__data.__kind + & (PTHREAD_MUTEX_PRIO_INHERIT_NP + | PTHREAD_MUTEX_PSHARED_BIT), 0)) goto wake_all; /* lll_futex_requeue returns 0 for success and non-zero for errors. */ if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1, INT_MAX, &mut->__data.__lock, - futex_val), 0)) + futex_val, LLL_PRIVATE), 0)) { /* The requeue functionality is not available. */ wake_all: - lll_futex_wake (&cond->__data.__futex, INT_MAX, - // XYZ check mutex flag - LLL_SHARED); + lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared); } /* That's all. */ @@ -79,7 +82,7 @@ __pthread_cond_broadcast (cond) } /* We are done. */ - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); return 0; } --- libc/nptl/pthreadP.h.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthreadP.h 2007-08-06 15:50:10.000000000 +0200 @@ -96,9 +96,18 @@ enum PTHREAD_MUTEX_PP_ADAPTIVE_NP = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP }; +#define PTHREAD_MUTEX_PSHARED_BIT 128 #define PTHREAD_MUTEX_TYPE(m) \ - ((m)->__data.__kind) + ((m)->__data.__kind & 127) + +#if LLL_PRIVATE == 0 && LLL_SHARED == 128 +# define PTHREAD_MUTEX_PSHARED(m) \ + ((m)->__data.__kind & 128) +#else +# define PTHREAD_MUTEX_PSHARED(m) \ + (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE) +#endif /* Ceiling in __data.__lock. __data.__lock is signed, so don't use the MSB bit in there, but in the mask also include that bit, --- libc/nptl/pthread_cond_timedwait.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_cond_timedwait.c 2007-08-06 15:50:10.000000000 +0200 @@ -53,14 +53,17 @@ __pthread_cond_timedwait (cond, mutex, a if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) return EINVAL; + int pshared = (cond->__data.__mutex == (void *) ~0l) + ? LLL_SHARED : LLL_PRIVATE; + /* Make sure we are along. */ - lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cond->__data.__lock, pshared); /* Now we can release the mutex. */ int err = __pthread_mutex_unlock_usercnt (mutex, 0); if (err) { - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); return err; } @@ -146,22 +149,20 @@ __pthread_cond_timedwait (cond, mutex, a unsigned int futex_val = cond->__data.__futex; /* Prepare to wait. Release the condvar futex. */ - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); /* Enable asynchronous cancellation. Required by the standard. */ cbuffer.oldtype = __pthread_enable_asynccancel (); /* Wait until woken by signal or broadcast. */ err = lll_futex_timed_wait (&cond->__data.__futex, - futex_val, &rt, - // XYZ check mutex flag - LLL_SHARED); + futex_val, &rt, pshared); /* Disable asynchronous cancellation. */ __pthread_disable_asynccancel (cbuffer.oldtype); /* We are going to look at shared data again, so get the lock. */ - lll_lock(cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cond->__data.__lock, pshared); /* If a broadcast happened, we are done. */ if (cbuffer.bc_seq != cond->__data.__broadcast_seq) @@ -198,12 +199,10 @@ __pthread_cond_timedwait (cond, mutex, a and it can be successfully destroyed. */ if (cond->__data.__total_seq == -1ULL && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT)) - lll_futex_wake (&cond->__data.__nwaiters, 1, - // XYZ check mutex flag - LLL_SHARED); + lll_futex_wake (&cond->__data.__nwaiters, 1, pshared); /* We are done with the condvar. */ - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); /* The cancellation handling is back to normal, remove the handler. */ __pthread_cleanup_pop (&buffer, 0); --- libc/nptl/pthread_mutex_setprioceiling.c.jj 2007-06-08 09:13:50.000000000 +0200 +++ libc/nptl/pthread_mutex_setprioceiling.c 2007-08-06 15:50:10.000000000 +0200 @@ -47,12 +47,13 @@ pthread_mutex_setprioceiling (mutex, pri /* Check whether we already hold the mutex. */ bool locked = false; + int kind = PTHREAD_MUTEX_TYPE (mutex); if (mutex->__data.__owner == THREAD_GETMEM (THREAD_SELF, tid)) { - if (mutex->__data.__kind == PTHREAD_MUTEX_PP_ERRORCHECK_NP) + if (kind == PTHREAD_MUTEX_PP_ERRORCHECK_NP) return EDEADLK; - if (mutex->__data.__kind == PTHREAD_MUTEX_PP_RECURSIVE_NP) + if (kind == PTHREAD_MUTEX_PP_RECURSIVE_NP) locked = true; } @@ -81,8 +82,7 @@ pthread_mutex_setprioceiling (mutex, pri if (oldval != ceilval) lll_futex_wait (&mutex->__data.__lock, ceilval | 2, - // XYZ check mutex flag - LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); } while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, ceilval | 2, ceilval) @@ -113,8 +113,7 @@ pthread_mutex_setprioceiling (mutex, pri atomic_full_barrier (); lll_futex_wake (&mutex->__data.__lock, INT_MAX, - // XYZ check mutex flag - LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); return 0; } --- libc/nptl/pthread_cond_signal.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_cond_signal.c 2007-08-06 15:50:10.000000000 +0200 @@ -32,8 +32,11 @@ int __pthread_cond_signal (cond) pthread_cond_t *cond; { + int pshared = (cond->__data.__mutex == (void *) ~0l) + ? LLL_SHARED : LLL_PRIVATE; + /* Make sure we are alone. */ - lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_lock (cond->__data.__lock, pshared); /* Are there any waiters to be woken? */ if (cond->__data.__total_seq > cond->__data.__wakeup_seq) @@ -45,18 +48,14 @@ __pthread_cond_signal (cond) /* Wake one. */ if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1, 1, &cond->__data.__lock, - // XYZ check mutex flag - LLL_SHARED), - 0)) + pshared), 0)) return 0; - lll_futex_wake (&cond->__data.__futex, 1, - // XYZ check mutex flag - LLL_SHARED); + lll_futex_wake (&cond->__data.__futex, 1, pshared); } /* We are done. */ - lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (cond->__data.__lock, pshared); return 0; } --- libc/nptl/pthread_mutex_lock.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_mutex_lock.c 2007-08-06 15:50:10.000000000 +0200 @@ -27,9 +27,12 @@ #ifndef LLL_MUTEX_LOCK -# define LLL_MUTEX_LOCK(mutex) lll_lock (mutex, /* XYZ */ LLL_SHARED) -# define LLL_MUTEX_TRYLOCK(mutex) lll_trylock (mutex) -# define LLL_ROBUST_MUTEX_LOCK(mutex, id) lll_robust_lock (mutex, id, /* XYZ */ LLL_SHARED) +# define LLL_MUTEX_LOCK(mutex) \ + lll_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)) +# define LLL_MUTEX_TRYLOCK(mutex) \ + lll_trylock ((mutex)->__data.__lock) +# define LLL_ROBUST_MUTEX_LOCK(mutex, id) \ + lll_robust_lock ((mutex)->__data.__lock, id, PTHREAD_MUTEX_PSHARED (mutex)) #endif @@ -62,7 +65,7 @@ __pthread_mutex_lock (mutex) } /* We have to get the mutex. */ - LLL_MUTEX_LOCK (mutex->__data.__lock); + LLL_MUTEX_LOCK (mutex); assert (mutex->__data.__owner == 0); mutex->__data.__count = 1; @@ -79,7 +82,7 @@ __pthread_mutex_lock (mutex) case PTHREAD_MUTEX_TIMED_NP: simple: /* Normal mutex. */ - LLL_MUTEX_LOCK (mutex->__data.__lock); + LLL_MUTEX_LOCK (mutex); assert (mutex->__data.__owner == 0); break; @@ -87,7 +90,7 @@ __pthread_mutex_lock (mutex) if (! __is_smp) goto simple; - if (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0) + if (LLL_MUTEX_TRYLOCK (mutex) != 0) { int cnt = 0; int max_cnt = MIN (MAX_ADAPTIVE_COUNT, @@ -96,7 +99,7 @@ __pthread_mutex_lock (mutex) { if (cnt++ >= max_cnt) { - LLL_MUTEX_LOCK (mutex->__data.__lock); + LLL_MUTEX_LOCK (mutex); break; } @@ -104,7 +107,7 @@ __pthread_mutex_lock (mutex) BUSY_WAIT_NOP; #endif } - while (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0); + while (LLL_MUTEX_TRYLOCK (mutex) != 0); mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8; } @@ -166,16 +169,15 @@ __pthread_mutex_lock (mutex) /* Check whether we already hold the mutex. */ if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0)) { - if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + int kind = PTHREAD_MUTEX_TYPE (mutex); + if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) { THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return EDEADLK; } - if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) + if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) { THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); @@ -191,14 +193,14 @@ __pthread_mutex_lock (mutex) } } - oldval = LLL_ROBUST_MUTEX_LOCK (mutex->__data.__lock, id); + oldval = LLL_ROBUST_MUTEX_LOCK (mutex, id); if (__builtin_expect (mutex->__data.__owner == PTHREAD_MUTEX_NOTRECOVERABLE, 0)) { /* This mutex is now not recoverable. */ mutex->__data.__count = 0; - lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)); THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return ENOTRECOVERABLE; } @@ -410,8 +412,7 @@ __pthread_mutex_lock (mutex) if (oldval != ceilval) lll_futex_wait (&mutex->__data.__lock, ceilval | 2, - // XYZ check mutex flag - LLL_SHARED); + PTHREAD_MUTEX_PSHARED (mutex)); } while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, ceilval | 2, ceilval) --- libc/nptl/pthread_mutex_trylock.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_mutex_trylock.c 2007-08-06 15:50:10.000000000 +0200 @@ -115,16 +115,15 @@ __pthread_mutex_trylock (mutex) /* Check whether we already hold the mutex. */ if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0)) { - if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) + int kind = PTHREAD_MUTEX_TYPE (mutex); + if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP) { THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return EDEADLK; } - if (mutex->__data.__kind - == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) + if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP) { THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); @@ -154,7 +153,8 @@ __pthread_mutex_trylock (mutex) /* This mutex is now not recoverable. */ mutex->__data.__count = 0; if (oldval == id) - lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED); + lll_unlock (mutex->__data.__lock, + PTHREAD_MUTEX_PSHARED (mutex)); THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL); return ENOTRECOVERABLE; } --- libc/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h 2007-08-06 15:50:10.000000000 +0200 @@ -103,24 +103,24 @@ while (0) /* 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); \ long int __ret; \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \ - (nr_move), (mutex), (val)); \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) /* 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; \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_WAKE_OP, (nr_wake), \ - (nr_wake2), (futexp2), \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_WAKE_OP, private), \ + (nr_wake), (nr_wake2), (futexp2), \ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) --- libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h 2007-08-06 15:50:10.000000000 +0200 @@ -103,18 +103,20 @@ do \ while (0) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val) \ +#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val, private) \ ({ \ - DO_INLINE_SYSCALL(futex, 6, (long) (ftx), FUTEX_CMP_REQUEUE, \ + DO_INLINE_SYSCALL(futex, 6, (long) (ftx), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private), \ (int) (nr_wake), (int) (nr_move), (long) (mutex), \ (int) val); \ _r10 == -1; \ }) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_wake_unlock(ftx, nr_wake, nr_wake2, ftx2) \ +#define lll_futex_wake_unlock(ftx, nr_wake, nr_wake2, ftx2, private) \ ({ \ - DO_INLINE_SYSCALL(futex, 6, (long) (ftx), FUTEX_WAKE_OP, \ + DO_INLINE_SYSCALL(futex, 6, (long) (ftx), \ + __lll_private_flag (FUTEX_WAKE_OP, private), \ (int) (nr_wake), (int) (nr_wake2), (long) (ftx2), \ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ _r10 == -1; \ --- libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h 2007-08-06 15:50:10.000000000 +0200 @@ -93,7 +93,7 @@ ({ \ register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \ register unsigned long int __r3 asm ("3") \ - __lll_private_flag (FUTEX_WAKE, private); \ + = __lll_private_flag (FUTEX_WAKE, private); \ register unsigned long int __r4 asm ("4") = (unsigned long int) (nr); \ register unsigned long int __result asm ("2"); \ \ @@ -117,10 +117,11 @@ /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_requeue(futex, nr_wake, nr_move, mutex, val) \ +#define lll_futex_requeue(futex, nr_wake, nr_move, mutex, val, private) \ ({ \ register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \ - register unsigned long int __r3 asm ("3") = FUTEX_CMP_REQUEUE; \ + register unsigned long int __r3 asm ("3") \ + = __lll_private_flag (FUTEX_CMP_REQUEUE, private); \ register unsigned long int __r4 asm ("4") = (long int) (nr_wake); \ register unsigned long int __r5 asm ("5") = (long int) (nr_move); \ register unsigned long int __r6 asm ("6") = (unsigned long int) (mutex); \ @@ -137,10 +138,11 @@ /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_wake_unlock(futex, nr_wake, nr_wake2, futex2) \ +#define lll_futex_wake_unlock(futex, nr_wake, nr_wake2, futex2, private) \ ({ \ register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \ - register unsigned long int __r3 asm ("3") = FUTEX_WAKE_OP; \ + register unsigned long int __r3 asm ("3") \ + = __lll_private_flag (FUTEX_WAKE_OP, private); \ register unsigned long int __r4 asm ("4") = (long int) (nr_wake); \ register unsigned long int __r5 asm ("5") = (long int) (nr_wake2); \ register unsigned long int __r6 asm ("6") = (unsigned long int) (futex2); \ --- libc/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym.jj 2006-07-29 06:33:20.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym 2007-08-06 20:43:29.000000000 +0200 @@ -4,3 +4,4 @@ MUTEX_KIND offsetof (pthread_mutex_t, __data.__kind) PI_BIT PTHREAD_MUTEX_PRIO_INHERIT_NP +PS_BIT PTHREAD_MUTEX_PSHARED_BIT --- libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h 2007-08-06 15:50:10.000000000 +0200 @@ -107,14 +107,14 @@ while (0) /* 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); \ long int __ret; \ \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \ - (nr_move), (mutex), (val)); \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) --- libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S 2007-08-06 20:35:12.000000000 +0200 @@ -71,11 +71,18 @@ __pthread_cond_broadcast: je 9f /* XXX: The kernel so far doesn't support requeue to PI futex. */ - testl $PI_BIT, MUTEX_KIND(%r8) + /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same + type of futex (private resp. shared). */ + testl $(PI_BIT | PS_BIT), MUTEX_KIND(%r8) jne 9f /* Wake up all threads. */ - movl $FUTEX_CMP_REQUEUE, %esi +#ifdef __ASSUME_PRIVATE_FUTEX + movl $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %esi +#else + movl %fs:PRIVATE_FUTEX, %esi + orl $FUTEX_CMP_REQUEUE, %esi +#endif movl $SYS_futex, %eax movl $1, %edx movl $0x7fffffff, %r10d @@ -104,8 +111,10 @@ __pthread_cond_broadcast: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_lock_wait #if cond_lock != 0 subq $cond_lock, %rdi @@ -114,22 +123,36 @@ __pthread_cond_broadcast: /* Unlock in loop requires wakeup. */ 5: addq $cond_lock-cond_futex, %rdi - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake jmp 6b /* Unlock in loop requires wakeup. */ 7: addq $cond_lock-cond_futex, %rdi - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake subq $cond_lock-cond_futex, %rdi jmp 8b 9: /* The futex requeue functionality is not available. */ + cmpq $-1, dep_mutex-cond_futex(%rdi) movl $0x7fffffff, %edx - movl $FUTEX_WAKE, %esi +#ifdef __ASSUME_PRIVATE_FUTEX + movl $FUTEX_WAKE, %eax + movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi + cmove %eax, %esi +#else + movl $FUTEX_WAKE, %eax + movl %fs:PRIVATE_FUTEX, %esi + cmove %eax, %esi + orl $FUTEX_WAKE, %esi +#endif movl $SYS_futex, %eax syscall jmp 10b --- libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S 2007-08-06 20:36:13.000000000 +0200 @@ -49,8 +49,10 @@ __condvar_cleanup: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_lock_wait #if cond_lock != 0 subq $cond_lock, %rdi @@ -81,9 +83,19 @@ __condvar_cleanup: jne 4f addq $cond_nwaiters, %rdi - movl $SYS_futex, %eax - movl $FUTEX_WAKE, %esi + cmpq $-1, dep_mutex-cond_nwaiters(%rdi) movl $1, %edx +#ifdef __ASSUME_PRIVATE_FUTEX + movl $FUTEX_WAKE, %eax + movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi + cmove %eax, %esi +#else + movl $FUTEX_WAKE, %eax + movl %fs:PRIVATE_FUTEX, %esi + cmove %eax, %esi + orl $FUTEX_WAKE, %esi +#endif + movl $SYS_futex, %eax syscall subq $cond_nwaiters, %rdi movl $1, %r12d @@ -98,16 +110,28 @@ __condvar_cleanup: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake /* Wake up all waiters to make sure no signal gets lost. */ 2: testq %r12, %r12 jnz 5f addq $cond_futex, %rdi - movl $FUTEX_WAKE, %esi + cmpq $-1, dep_mutex-cond_futex(%rdi) movl $0x7fffffff, %edx +#ifdef __ASSUME_PRIVATE_FUTEX + movl $FUTEX_WAKE, %eax + movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi + cmove %eax, %esi +#else + movl $FUTEX_WAKE, %eax + movl %fs:PRIVATE_FUTEX, %esi + cmove %eax, %esi + orl $FUTEX_WAKE, %esi +#endif movl $SYS_futex, %eax syscall @@ -216,12 +240,20 @@ __pthread_cond_wait: xorq %r10, %r10 movq %r12, %rdx addq $cond_futex-cond_lock, %rdi - movl $SYS_futex, %eax -#if FUTEX_WAIT == 0 - xorl %esi, %esi + cmpq $-1, dep_mutex-cond_futex(%rdi) +#ifdef __ASSUME_PRIVATE_FUTEX + movl $FUTEX_WAIT, %eax + movl $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi + cmove %eax, %esi #else - movl $FUTEX_WAIT, %esi + movl $FUTEX_WAIT, %eax + movl %fs:PRIVATE_FUTEX, %esi + cmove %eax, %esi +# if FUTEX_WAIT != 0 + orl $FUTEX_WAIT, %esi +# endif #endif + movl $SYS_futex, %eax syscall movl (%rsp), %edi @@ -267,9 +299,19 @@ __pthread_cond_wait: jne 17f addq $cond_nwaiters, %rdi - movl $SYS_futex, %eax - movl $FUTEX_WAKE, %esi + cmpq $-1, dep_mutex-cond_nwaiters(%rdi) movl $1, %edx +#ifdef __ASSUME_PRIVATE_FUTEX + movl $FUTEX_WAKE, %eax + movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi + cmove %eax, %esi +#else + movl $FUTEX_WAKE, %eax + movl %fs:PRIVATE_FUTEX, %esi + cmove %eax, %esi + orl $FUTEX_WAKE, %esi +#endif + movl $SYS_futex, %eax syscall subq $cond_nwaiters, %rdi @@ -302,8 +344,10 @@ __pthread_cond_wait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_lock_wait jmp 2b @@ -312,8 +356,10 @@ __pthread_cond_wait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake jmp 4b @@ -322,8 +368,10 @@ __pthread_cond_wait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_lock_wait #if cond_lock != 0 subq $cond_lock, %rdi @@ -335,8 +383,10 @@ __pthread_cond_wait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake jmp 11b @@ -354,8 +404,10 @@ __pthread_cond_wait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake 13: movq %r10, %rax --- libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S 2007-08-06 20:35:38.000000000 +0200 @@ -55,10 +55,20 @@ __pthread_cond_signal: addl $1, (%rdi) /* Wake up one thread. */ - movl $FUTEX_WAKE_OP, %esi - movl $SYS_futex, %eax + cmpq $-1, dep_mutex(%r8) movl $1, %edx +#ifdef __ASSUME_PRIVATE_FUTEX + movl $FUTEX_WAKE_OP, %eax + movl $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi + cmove %eax, %esi +#else + movl $FUTEX_WAKE_OP, %eax + movl %fs:PRIVATE_FUTEX, %esi + cmove %eax, %esi + orl $FUTEX_WAKE_OP, %esi +#endif movl $1, %r10d + movl $SYS_futex, %eax #if cond_lock != 0 addq $cond_lock, %r8 #endif @@ -75,7 +85,9 @@ __pthread_cond_signal: xorl %eax, %eax retq -7: movl $FUTEX_WAKE, %esi +7: /* %esi should be either FUTEX_WAKE_OP or + FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */ + xorl $(FUTEX_WAKE | FUTEX_WAKE_OP), %esi movl $SYS_futex, %eax /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall. movl $1, %edx */ @@ -98,8 +110,10 @@ __pthread_cond_signal: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_lock_wait #if cond_lock != 0 subq $cond_lock, %rdi @@ -109,8 +123,13 @@ __pthread_cond_signal: /* Unlock in loop requires wakeup. */ 5: movq %r8, %rdi - /* XYZ */ +#if cond_lock != 0 + addq $cond_lock, %rdi +#endif + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake jmp 6b .size __pthread_cond_signal, .-__pthread_cond_signal --- libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h 2007-08-06 15:50:10.000000000 +0200 @@ -533,7 +533,7 @@ LLL_STUB_UNWIND_INFO_END while (0) /* Returns non-zero if error happened, zero if success. */ -#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val) \ +#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val, private) \ ({ int __res; \ register int __nr_move __asm ("r10") = nr_move; \ register void *__mutex __asm ("r8") = mutex; \ @@ -541,7 +541,8 @@ LLL_STUB_UNWIND_INFO_END __asm __volatile ("syscall" \ : "=a" (__res) \ : "0" (__NR_futex), "D" ((void *) ftx), \ - "S" (FUTEX_CMP_REQUEUE), "d" (nr_wake), \ + "S" (__lll_private_flag (FUTEX_CMP_REQUEUE, \ + private)), "d" (nr_wake), \ "r" (__nr_move), "r" (__mutex), "r" (__val) \ : "cx", "r11", "cc", "memory"); \ __res < 0; }) --- libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S 2007-08-06 20:40:18.000000000 +0200 @@ -186,12 +186,20 @@ __pthread_cond_timedwait: movl %eax, (%rsp) leaq 24(%rsp), %r10 -#if FUTEX_WAIT == 0 - xorl %esi, %esi + cmpq $-1, dep_mutex(%rdi) + movq %r12, %rdx +#ifdef __ASSUME_PRIVATE_FUTEX + movl $FUTEX_WAIT, %eax + movl $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi + cmove %eax, %esi #else - movl $FUTEX_WAIT, %esi + movl $FUTEX_WAIT, %eax + movl %fs:PRIVATE_FUTEX, %esi + cmove %eax, %esi +# if FUTEX_WAIT != 0 + orl $FUTEX_WAIT, %esi +# endif #endif - movq %r12, %rdx addq $cond_futex, %rdi movl $SYS_futex, %eax syscall @@ -251,9 +259,19 @@ __pthread_cond_timedwait: jne 25f addq $cond_nwaiters, %rdi - movl $SYS_futex, %eax - movl $FUTEX_WAKE, %esi + cmpq $-1, dep_mutex-cond_nwaiters(%rdi) movl $1, %edx +#ifdef __ASSUME_PRIVATE_FUTEX + movl $FUTEX_WAKE, %eax + movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi + cmove %eax, %esi +#else + movl $FUTEX_WAKE, %eax + movl %fs:PRIVATE_FUTEX, %esi + cmove %eax, %esi + orl $FUTEX_WAKE, %esi +#endif + movl $SYS_futex, %eax syscall subq $cond_nwaiters, %rdi @@ -292,8 +310,10 @@ __pthread_cond_timedwait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_lock_wait jmp 2b @@ -302,8 +322,10 @@ __pthread_cond_timedwait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake jmp 4b @@ -312,8 +334,10 @@ __pthread_cond_timedwait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_lock_wait #if cond_lock != 0 subq $cond_lock, %rdi @@ -325,8 +349,10 @@ __pthread_cond_timedwait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake jmp 11b @@ -344,8 +370,10 @@ __pthread_cond_timedwait: #if cond_lock != 0 addq $cond_lock, %rdi #endif - /* XYZ */ + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi + cmovne %eax, %esi callq __lll_unlock_wake 17: movq (%rsp), %rax --- libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h 2007-08-06 15:50:10.000000000 +0200 @@ -96,14 +96,14 @@ }) /* 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); \ long int __ret; \ \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \ - (nr_move), (mutex), (val)); \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) @@ -121,14 +121,14 @@ /* Avoid FUTEX_WAKE_OP if supporting pre-v9 CPUs. */ # define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) 1 #else -# 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; \ \ - __ret = INTERNAL_SYSCALL (futex, __err, 6, \ - (futexp), FUTEX_WAKE_OP, (nr_wake), \ - (nr_wake2), (futexp2), \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_WAKE_OP, private), \ + (nr_wake), (nr_wake2), (futexp2), \ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) --- libc/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c 2007-08-06 15:50:10.000000000 +0200 @@ -1,8 +1,12 @@ #include -#define LLL_MUTEX_LOCK(mutex) lll_cond_lock (mutex, /* XYZ */ LLL_SHARED) -#define LLL_MUTEX_TRYLOCK(mutex) lll_cond_trylock (mutex) -#define LLL_ROBUST_MUTEX_LOCK(mutex, id) lll_robust_cond_lock (mutex, id, /* XYZ */ LLL_SHARED) +#define LLL_MUTEX_LOCK(mutex) \ + lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)) +#define LLL_MUTEX_TRYLOCK(mutex) \ + lll_cond_trylock ((mutex)->__data.__lock) +#define LLL_ROBUST_MUTEX_LOCK(mutex, id) \ + lll_robust_cond_lock ((mutex)->__data.__lock, id, \ + PTHREAD_MUTEX_PSHARED (mutex)) #define __pthread_mutex_lock __pthread_mutex_cond_lock #define NO_INCR Jakub From drepper@redhat.com Sat Aug 11 18:53:00 2007 From: drepper@redhat.com (Ulrich Drepper) Date: Sat, 11 Aug 2007 18:53:00 -0000 Subject: [PATCH] private futex for pthread_mutex_* and pthread_cond_* In-Reply-To: <20070806193545.GH4603@sunsite.mff.cuni.cz> References: <20070806193545.GH4603@sunsite.mff.cuni.cz> Message-ID: <46BE059E.70404@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Looks good. I've made a few additional little changes but the code was correct. - -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFGvgWe2ijCOnn/RHQRAkJoAJwP5eJStTYur8RoFAZG/9n9Hrg/BgCdF5Ss vEAOfTkUz5+7YgXoPn16VpM= =AC6y -----END PGP SIGNATURE----- From jakub@redhat.com Sun Aug 12 08:31:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Sun, 12 Aug 2007 08:31:00 -0000 Subject: [PATCH] ia64 build fixes Message-ID: <20070812083711.GI4603@sunsite.mff.cuni.cz> Hi! This was needed to build glibc trunk on ia64. An obvious typo in lowlevellock.h, missing pthread_rwlock_t changes on many arches and ia64's bits/sigcontext.h including bits/sigstack.h (which needs size_t). On all other arches, bits/sigstack.h is only included from signal.h, after #define __need_size_t #include , but on ia64 it is also included from bits/sigcontext.h (not a ISO C nor POSIX violation IMHO), which is included from signal.h (but earlier than the stddef.h include - could be fixed by moving that stddef.h include earlier) but also from sys/ucontext.h (where we'd need to add __need_size_t stddef.h include too). In the patch below ia64's bits/sigcontext.h does that, as it is the only arch that needs this. 2007-08-12 Jakub Jelinek * sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h: Include stddef.h with __need_size_t. nptl/ * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h [__WORDSIZE=32] (pthread_rwlock_t): Split __flags element into four byte elements. One of them is the new __shared element. [__WORDSIZE=64] (pthread_rwlock_t): Renamed __pad1 element to __shared, adjust names of other padding elements. * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h [__WORDSIZE=32] (pthread_rwlock_t): Split __flags element into four byte elements. One of them is the new __shared element. [__WORDSIZE=64] (pthread_rwlock_t): Renamed __pad1 element to __shared, adjust names of other padding elements. * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h (pthread_rwlock_t): Renamed __pad1 element to __shared, adjust names of other padding elements. * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h (pthread_rwlock_t): Likewise. * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_lock): Fix a typo. --- libc/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h.jj 2006-02-15 12:14:34.000000000 -0500 +++ libc/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h 2007-08-11 13:19:41.000000000 -0400 @@ -1,5 +1,5 @@ /* Machine-specific pthread type layouts. SPARC version. - Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2003. @@ -160,9 +160,9 @@ typedef union unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; int __writer; - int __pad1; + int __shared; + unsigned long int __pad1; unsigned long int __pad2; - unsigned long int __pad3; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ unsigned int __flags; @@ -176,9 +176,12 @@ typedef union unsigned int __writer_wakeup; unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; + unsigned char __pad1; + unsigned char __pad2; + unsigned char __shared; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ - unsigned int __flags; + unsigned char __flags; int __writer; } __data; # endif --- libc/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h.jj 2006-02-15 12:13:30.000000000 -0500 +++ libc/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h 2007-08-11 13:14:49.000000000 -0400 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2003. @@ -126,9 +126,9 @@ typedef union unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; int __writer; - int __pad1; + int __shared; + unsigned long int __pad1; unsigned long int __pad2; - unsigned long int __pad3; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ unsigned int __flags; --- libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h.jj 2007-08-11 10:53:10.000000000 -0400 +++ libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h 2007-08-11 12:09:43.000000000 -0400 @@ -154,6 +154,7 @@ extern int __lll_robust_lock_wait (int * __lll_lock_wait_private (__futex); \ else \ __lll_lock_wait (__futex, private); \ + } \ })) #define lll_lock(futex, private) __lll_lock (&(futex), private) --- libc/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h.jj 2006-02-15 12:13:30.000000000 -0500 +++ libc/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h 2007-08-11 13:18:18.000000000 -0400 @@ -1,5 +1,5 @@ /* Machine-specific pthread type layouts. Alpha version. - Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 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 @@ -126,9 +126,9 @@ typedef union unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; int __writer; - int __pad1; + int __shared; + unsigned long int __pad1; unsigned long int __pad2; - unsigned long int __pad3; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ unsigned int __flags; --- libc/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h.jj 2006-02-15 12:14:33.000000000 -0500 +++ libc/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h 2007-08-11 13:17:31.000000000 -0400 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky , 2003. @@ -159,9 +159,9 @@ typedef union unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; int __writer; - int __pad1; + int __shared; + unsigned long int __pad1; unsigned long int __pad2; - unsigned long int __pad3; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ unsigned int __flags; @@ -175,9 +175,12 @@ typedef union unsigned int __writer_wakeup; unsigned int __nr_readers_queued; unsigned int __nr_writers_queued; + unsigned char __pad1; + unsigned char __pad2; + unsigned char __shared; /* FLAGS must stay at this position in the structure to maintain binary compatibility. */ - unsigned int __flags; + unsigned char __flags; int __writer; } __data; # endif --- libc/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h.jj 2004-10-13 22:22:38.000000000 -0400 +++ libc/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h 2007-08-11 12:50:21.000000000 -0400 @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004 +/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jes Sorensen , July 2000 @@ -25,6 +25,8 @@ #ifndef _BITS_SIGCONTEXT_H #define _BITS_SIGCONTEXT_H 1 +#define __need_size_t +#include #include struct ia64_fpreg Jakub From jakub@redhat.com Sun Aug 12 19:52:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Sun, 12 Aug 2007 19:52:00 -0000 Subject: [PATCH] ldconfig speedup In-Reply-To: <20070727183626.GQ4603@sunsite.mff.cuni.cz> References: <876455cgf1.fsf@mid.deneb.enyo.de> <20070703112849.GE4603@sunsite.mff.cuni.cz> <468AB559.2030801@redhat.com> <20070727121434.GO4603@sunsite.mff.cuni.cz> <20070727165326.GP4603@sunsite.mff.cuni.cz> <20070727183626.GQ4603@sunsite.mff.cuni.cz> Message-ID: <20070812195735.GK4603@sunsite.mff.cuni.cz> On Fri, Jul 27, 2007 at 08:36:26PM +0200, Jakub Jelinek wrote: > On Fri, Jul 27, 2007 at 07:08:55PM +0200, Andreas Jaeger wrote: > > > > What kind of testing have you done? I compared the /etc/ld.so.cache > > From the old ldconfig with the new one - and run the new ldconfig > > without the aux cache and then several times with the new one. I first > > had a bug where the results were not exactly the same and I lost some > > entries. ;-( > > Yeah, that's exactly what I tested, compare /etc/ld.so.cache generated > by non-patched ldconfig with patched ldconfig when > /var/cache/ldconfig/aux-cache was missing, then with the cache, then with > -i. I also looked at strace output to see how the caching was effective. > When working on the patch I had a buglet in it too which caused all > SONAMEs returned from the aux cache contain unitialized memory data, > it created wonderful symlinks all over my */lib{,64} directories. > But the version I posted seemed to work well. During testing we found problems with the error messages and non-zero exit when some problem was detected during aux-cache creation, e.g. when ldconfig is ran in some chroot etc. The aux-cache is only an optimization, so if anything fails during creation of the aux-cache, it shouldn't be fatal nor we should output any diagnostics. The following updated patch does that and we are successfully using it in Fedora development for almost a fortnight. 2007-08-01 Andreas Jaeger Jakub Jelinek * elf/ldconfig.c (opt_ignore_aux_cache): Add new option. (options): Add option. (parse_opt): Handle option. (manual_link): Adjust process_file caller. Call implicit_soname. (search_dir): Formatting. Use and populate auxiliary cache. (main): Load and save auxiliary cache. * elf/readlib.c (process_file): Add stat_buf argument. Pass struct stat64 from fstat64 to caller. (implicit_soname): New function. * elf/readelflib.c (process_elf_file): If DT_SONAME is not present, leave *soname as NULL. * elf/cache.c: Include libgen.h. (print_entry, print_cache, compare, save_cache, add_to_cache): Formatting and cleanups. (aux_cache_entry_id, aux_cache_entry, aux_cache_file_entry, aux_cache_file): New structures. (AUX_CACHEMAGIC): Define. (primes): New array. (aux_hash_size, aux_hash): New variables. (aux_cache_entry_id_hash, nextprime, init_aux_cache, search_aux_cache, insert_to_aux_cache, add_to_aux_cache, load_aux_cache, save_aux_cache): New functions. * sysdeps/generic/ldconfig.h (_PATH_LDCONFIG_AUX_CACHE): Define. (init_aux_cache, search_aux_cache, add_to_aux_cache, load_aux_cache, save_aux_cache, implicit_soname): New prototypes. (process_file): Adjust prototype. --- libc/elf/ldconfig.c.jj 2007-07-16 09:58:46.000000000 +0200 +++ libc/elf/ldconfig.c 2007-08-01 18:54:26.000000000 +0200 @@ -112,6 +112,9 @@ static char *opt_chroot; /* Manually link given shared libraries. */ static int opt_manual_link; +/* Should we ignore an old auxiliary cache file? */ +static int opt_ignore_aux_cache; + /* Cache file to use. */ static char *cache_file; @@ -142,6 +145,7 @@ static const struct argp_option options[ { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0}, { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0}, { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new, old or compat (default)"), 0}, + { "ignore-aux-cache", 'i', NULL, 0, N_("Ignore auxiliary cache file"), 0}, { NULL, 0, NULL, 0, NULL, 0 } }; @@ -238,10 +242,15 @@ parse_opt (int key, char *arg, struct ar { case 'C': cache_file = arg; + /* Ignore auxiliary cache since we use non-standard cache. */ + opt_ignore_aux_cache = 1; break; case 'f': config_file = arg; break; + case 'i': + opt_ignore_aux_cache = 1; + break; case 'l': opt_manual_link = 1; break; @@ -518,7 +527,7 @@ manual_link (char *library) if (libname) { /* Successfully split names. Check if path is just "/" to avoid - an empty path. */ + an empty path. */ if (libname == path) { libname = library + 1; @@ -572,14 +581,17 @@ manual_link (char *library) free (path); return; } + if (process_file (real_library, library, libname, &flag, &osversion, - &soname, 0)) + &soname, 0, &stat_buf)) { error (0, 0, _("No link created since soname could not be found for %s"), library); free (path); return; } + if (soname == NULL) + soname = implicit_soname (libname, flag); create_links (real_path, path, libname, soname); free (soname); free (path); @@ -625,23 +637,7 @@ struct dlib_entry static void search_dir (const struct dir_entry *entry) { - DIR *dir; - struct dirent64 *direntry; - char *file_name, *dir_name, *real_file_name, *real_name; - int file_name_len, real_file_name_len, len; - char *soname; - struct dlib_entry *dlibs; - struct dlib_entry *dlib_ptr; - struct stat64 lstat_buf, stat_buf; - int is_link, is_dir; uint64_t hwcap = path_hwcap (entry->path); - unsigned int osversion; - - file_name_len = PATH_MAX; - file_name = alloca (file_name_len); - - dlibs = NULL; - if (opt_verbose) { if (hwcap != 0) @@ -650,6 +646,11 @@ search_dir (const struct dir_entry *entr printf ("%s:\n", entry->path); } + char *dir_name; + char *real_file_name; + size_t real_file_name_len; + size_t file_name_len = PATH_MAX; + char *file_name = alloca (file_name_len); if (opt_chroot) { dir_name = chroot_canon (opt_chroot, entry->path); @@ -663,6 +664,7 @@ search_dir (const struct dir_entry *entr real_file_name = file_name; } + DIR *dir; if (dir_name == NULL || (dir = opendir (dir_name)) == NULL) { if (opt_verbose) @@ -672,6 +674,8 @@ search_dir (const struct dir_entry *entr return; } + struct dirent64 *direntry; + struct dlib_entry *dlibs = NULL; while ((direntry = readdir64 (dir)) != NULL) { int flag; @@ -695,7 +699,8 @@ search_dir (const struct dir_entry *entr #endif !is_hwcap_platform (direntry->d_name))) continue; - len = strlen (direntry->d_name); + + size_t len = strlen (direntry->d_name); /* Skip temporary files created by the prelink program. Files with names like these are never really DSOs we want to look at. */ if (len >= sizeof (".#prelink#") - 1) @@ -727,7 +732,10 @@ search_dir (const struct dir_entry *entr } sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name); } + + struct stat64 lstat_buf; #ifdef _DIRENT_HAVE_D_TYPE + /* We optimize and try to do the lstat call only if needed. */ if (direntry->d_type != DT_UNKNOWN) lstat_buf.st_mode = DTTOIF (direntry->d_type); else @@ -738,9 +746,11 @@ search_dir (const struct dir_entry *entr continue; } - is_link = S_ISLNK (lstat_buf.st_mode); + struct stat64 stat_buf; + int is_dir; + int is_link = S_ISLNK (lstat_buf.st_mode); if (is_link) - { + { /* In case of symlink, we check if the symlink refers to a directory. */ if (__builtin_expect (stat64 (real_file_name, &stat_buf), 0)) @@ -754,6 +764,12 @@ search_dir (const struct dir_entry *entr continue; } is_dir = S_ISDIR (stat_buf.st_mode); + + /* lstat_buf is later stored, update contents. */ + lstat_buf.st_dev = stat_buf.st_dev; + lstat_buf.st_ino = stat_buf.st_ino; + lstat_buf.st_size = stat_buf.st_size; + lstat_buf.st_ctime = stat_buf.st_ctime; } else is_dir = S_ISDIR (lstat_buf.st_mode); @@ -767,36 +783,28 @@ search_dir (const struct dir_entry *entr new_entry->path = xstrdup (file_name); new_entry->flag = entry->flag; new_entry->next = NULL; - if (is_link) +#ifdef _DIRENT_HAVE_D_TYPE + /* We have filled in lstat only #ifndef + _DIRENT_HAVE_D_TYPE. Fill it in if needed. */ + if (!is_link + && direntry->d_type != DT_UNKNOWN + && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0)) { - new_entry->ino = stat_buf.st_ino; - new_entry->dev = stat_buf.st_dev; + error (0, errno, _("Cannot lstat %s"), file_name); + free (new_entry->path); + free (new_entry); + continue; } - else - { -#ifdef _DIRENT_HAVE_D_TYPE - /* We have filled in lstat only #ifndef - _DIRENT_HAVE_D_TYPE. Fill it in if needed. */ - if (direntry->d_type != DT_UNKNOWN - && __builtin_expect (lstat64 (real_file_name, &lstat_buf), - 0)) - { - error (0, errno, _("Cannot lstat %s"), file_name); - free (new_entry->path); - free (new_entry); - continue; - } #endif - - new_entry->ino = lstat_buf.st_ino; - new_entry->dev = lstat_buf.st_dev; - } + new_entry->ino = lstat_buf.st_ino; + new_entry->dev = lstat_buf.st_dev; add_single_dir (new_entry, 0); continue; } else if (!S_ISREG (lstat_buf.st_mode) && !is_link) continue; + char *real_name; if (opt_chroot && is_link) { real_name = chroot_canon (opt_chroot, file_name); @@ -810,14 +818,36 @@ search_dir (const struct dir_entry *entr else real_name = real_file_name; - if (process_file (real_name, file_name, direntry->d_name, &flag, - &osversion, &soname, is_link)) +#ifdef _DIRENT_HAVE_D_TYPE + /* Call lstat64 if not done yet. */ + if (!is_link + && direntry->d_type != DT_UNKNOWN + && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0)) { - if (real_name != real_file_name) - free (real_name); + error (0, errno, _("Cannot lstat %s"), file_name); continue; } +#endif + + /* First search whether the auxiliary cache contains this + library already and it's not changed. */ + char *soname; + unsigned int osversion; + if (!search_aux_cache (&lstat_buf, &flag, &osversion, &soname)) + { + if (process_file (real_name, file_name, direntry->d_name, &flag, + &osversion, &soname, is_link, &lstat_buf)) + { + if (real_name != real_file_name) + free (real_name); + continue; + } + else if (opt_build_cache) + add_to_aux_cache (&lstat_buf, flag, osversion, soname); + } + if (soname == NULL) + soname = implicit_soname (direntry->d_name, flag); /* A link may just point to itself. */ if (is_link) @@ -834,7 +864,7 @@ search_dir (const struct dir_entry *entr || strncmp (real_base_name, soname, len) != 0) is_link = 0; } - } + } if (real_name != real_file_name) free (real_name); @@ -849,6 +879,7 @@ search_dir (const struct dir_entry *entr && (entry->flag == FLAG_ELF_LIBC5 || entry->flag == FLAG_ELF_LIBC6)) flag = entry->flag; + /* Some sanity checks to print warnings. */ if (opt_verbose) { @@ -864,6 +895,7 @@ search_dir (const struct dir_entry *entr } /* Add library to list. */ + struct dlib_entry *dlib_ptr; for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next) { /* Is soname already in list? */ @@ -888,12 +920,13 @@ search_dir (const struct dir_entry *entr dlib_ptr->flag = flag; else error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."), - dlib_ptr->name, direntry->d_name, entry->path); + dlib_ptr->name, direntry->d_name, + entry->path); } free (dlib_ptr->name); - dlib_ptr->osversion = osversion; dlib_ptr->name = xstrdup (direntry->d_name); dlib_ptr->is_link = is_link; + dlib_ptr->osversion = osversion; } /* Don't add this library, abort loop. */ /* Also free soname, since it's dynamically allocated. */ @@ -906,10 +939,10 @@ search_dir (const struct dir_entry *entr { dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry)); dlib_ptr->name = xstrdup (direntry->d_name); - dlib_ptr->flag = flag; - dlib_ptr->osversion = osversion; dlib_ptr->soname = soname; + dlib_ptr->flag = flag; dlib_ptr->is_link = is_link; + dlib_ptr->osversion = osversion; /* Add at head of list. */ dlib_ptr->next = dlibs; dlibs = dlib_ptr; @@ -920,6 +953,7 @@ search_dir (const struct dir_entry *entr /* Now dlibs contains a list of all libs - add those to the cache and created all symbolic links. */ + struct dlib_entry *dlib_ptr; for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next) { /* Don't create links to links. */ @@ -1246,7 +1280,7 @@ main (int argc, char **argv) if (opt_chroot) { /* Canonicalize the directory name of cache_file, not cache_file, - because we'll rename a temporary cache file to it. */ + because we'll rename a temporary cache file to it. */ char *p = strrchr (cache_file, '/'); char *canon = chroot_canon (opt_chroot, p ? (*p = '\0', cache_file) : "/"); @@ -1293,10 +1327,18 @@ main (int argc, char **argv) add_system_dir (LIBDIR); } + if (! opt_ignore_aux_cache) + load_aux_cache (_PATH_LDCONFIG_AUX_CACHE); + else + init_aux_cache (); + search_dirs (); if (opt_build_cache) - save_cache (cache_file); + { + save_cache (cache_file); + save_aux_cache (_PATH_LDCONFIG_AUX_CACHE); + } return 0; } --- libc/elf/readlib.c.jj 2007-07-16 09:58:46.000000000 +0200 +++ libc/elf/readlib.c 2007-08-01 18:54:26.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1999-2003, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger , 1999 and Jakub Jelinek , 1999. @@ -69,7 +69,7 @@ static struct known_names known_libs[] = int process_file (const char *real_file_name, const char *file_name, const char *lib, int *flag, unsigned int *osversion, - char **soname, int is_link) + char **soname, int is_link, struct stat64 *stat_buf) { FILE *file; struct stat64 statbuf; @@ -135,7 +135,7 @@ process_file (const char *real_file_name ) { /* Aout files don't have a soname, just return the name - including the major number. */ + including the major number. */ char *copy, *major, *dot; copy = xstrdup (lib); major = strstr (copy, ".so."); @@ -175,8 +175,31 @@ process_file (const char *real_file_name munmap (file_contents, statbuf.st_size); fclose (file); + *stat_buf = statbuf; return ret; } +/* Returns made up soname if lib doesn't have explicit DT_SONAME. */ + +char * +implicit_soname (const char *lib, int flag) +{ + char *soname = xstrdup (lib); + + if ((flag & FLAG_TYPE_MASK) != FLAG_LIBC4) + return soname; + + /* Aout files don't have a soname, just return the name + including the major number. */ + char *major = strstr (soname, ".so."); + if (major) + { + char *dot = strstr (major + 4, "."); + if (dot) + *dot = '\0'; + } + return soname; +} + /* Get architecture specific version of process_elf_file. */ #include --- libc/elf/readelflib.c.jj 2007-07-03 12:36:59.000000000 +0200 +++ libc/elf/readelflib.c 2007-08-01 18:54:26.000000000 +0200 @@ -231,11 +231,5 @@ process_elf_file (const char *file_name, } } - /* We reach this point only if the file doesn't contain a DT_SONAME - or if we can't classify the library. If it doesn't have a - soname, return the name of the library. */ - if (*soname == NULL) - *soname = xstrdup (lib); - return 0; } --- libc/elf/cache.c.jj 2007-07-16 09:58:46.000000000 +0200 +++ libc/elf/cache.c 2007-08-01 19:00:30.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2003,2005,2006 Free Software Foundation, Inc. +/* Copyright (C) 1999-2003,2005,2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger , 1999. @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -80,16 +81,16 @@ print_entry (const char *lib, int flag, fputs (",x86-64", stdout); break; case FLAG_S390_LIB64: - fputs(",64bit", stdout); + fputs (",64bit", stdout); break; case FLAG_POWERPC_LIB64: - fputs(",64bit", stdout); + fputs (",64bit", stdout); break; case FLAG_MIPS64_LIBN32: - fputs(",N32", stdout); + fputs (",N32", stdout); break; case FLAG_MIPS64_LIBN64: - fputs(",64bit", stdout); + fputs (",64bit", stdout); case 0: break; default: @@ -128,19 +129,11 @@ print_entry (const char *lib, int flag, void print_cache (const char *cache_name) { - size_t cache_size; - struct stat64 st; - int fd; - unsigned int i; - struct cache_file *cache; - struct cache_file_new *cache_new = NULL; - const char *cache_data; - int format = 0; - - fd = open (cache_name, O_RDONLY); + int fd = open (cache_name, O_RDONLY); if (fd < 0) error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name); + struct stat64 st; if (fstat64 (fd, &st) < 0 /* No need to map the file if it is empty. */ || st.st_size == 0) @@ -149,14 +142,19 @@ print_cache (const char *cache_name) return; } - cache = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + struct cache_file *cache + = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (cache == MAP_FAILED) error (EXIT_FAILURE, errno, _("mmap of cache file failed.\n")); - cache_size = st.st_size; + size_t cache_size = st.st_size; if (cache_size < sizeof (struct cache_file)) error (EXIT_FAILURE, 0, _("File is not a cache file.\n")); + struct cache_file_new *cache_new = NULL; + const char *cache_data; + int format = 0; + if (memcmp (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1)) { /* This can only be the new format without the old one. */ @@ -201,7 +199,7 @@ print_cache (const char *cache_name) printf (_("%d libs found in cache `%s'\n"), cache->nlibs, cache_name); /* Print everything. */ - for (i = 0; i < cache->nlibs; i++) + for (unsigned int i = 0; i < cache->nlibs; i++) print_entry (cache_data + cache->libs[i].key, cache->libs[i].flags, 0, 0, cache_data + cache->libs[i].value); @@ -212,7 +210,7 @@ print_cache (const char *cache_name) cache_new->nlibs, cache_name); /* Print everything. */ - for (i = 0; i < cache_new->nlibs; i++) + for (unsigned int i = 0; i < cache_new->nlibs; i++) print_entry (cache_data + cache_new->libs[i].key, cache_new->libs[i].flags, cache_new->libs[i].osversion, @@ -231,15 +229,11 @@ init_cache (void) entries = NULL; } - - -static -int compare (const struct cache_entry *e1, const struct cache_entry *e2) +static int +compare (const struct cache_entry *e1, const struct cache_entry *e2) { - int res; - /* We need to swap entries here to get the correct sort order. */ - res = _dl_cache_libcmp (e2->lib, e1->lib); + int res = _dl_cache_libcmp (e2->lib, e1->lib); if (res == 0) { if (e1->flags < e2->flags) @@ -267,29 +261,19 @@ int compare (const struct cache_entry *e void save_cache (const char *cache_name) { - struct cache_entry *entry; - int fd, idx_old, idx_new; - size_t total_strlen, len; - char *strings, *str, *temp_name; - struct cache_file *file_entries = NULL; - struct cache_file_new *file_entries_new = NULL; - size_t file_entries_size = 0; - size_t file_entries_new_size = 0; - unsigned int str_offset; - /* Number of cache entries. */ - int cache_entry_count = 0; - /* Number of normal cache entries. */ - int cache_entry_old_count = 0; - /* Pad for alignment of cache_file_new. */ - size_t pad; - /* The cache entries are sorted already, save them in this order. */ /* Count the length of all strings. */ /* The old format doesn't contain hwcap entries and doesn't contain libraries in subdirectories with hwcaps entries. Count therefore also all entries with hwcap == 0. */ - total_strlen = 0; + size_t total_strlen = 0; + struct cache_entry *entry; + /* Number of cache entries. */ + int cache_entry_count = 0; + /* Number of normal cache entries. */ + int cache_entry_old_count = 0; + for (entry = entries; entry != NULL; entry = entry->next) { /* Account the final NULs. */ @@ -300,8 +284,8 @@ save_cache (const char *cache_name) } /* Create the on disk cache structure. */ - /* First an array for all strings. */ - strings = (char *)xmalloc (total_strlen); + struct cache_file *file_entries = NULL; + size_t file_entries_size = 0; if (opt_format != 2) { @@ -315,25 +299,27 @@ save_cache (const char *cache_name) /* And the list of all entries in the old format. */ file_entries_size = sizeof (struct cache_file) + cache_entry_old_count * sizeof (struct file_entry); - file_entries = (struct cache_file *) xmalloc (file_entries_size); + file_entries = xmalloc (file_entries_size); /* Fill in the header. */ - memset (file_entries, 0, sizeof (struct cache_file)); + memset (file_entries, '\0', sizeof (struct cache_file)); memcpy (file_entries->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1); file_entries->nlibs = cache_entry_old_count; } + struct cache_file_new *file_entries_new = NULL; + size_t file_entries_new_size = 0; + if (opt_format != 0) { /* And the list of all entries in the new format. */ file_entries_new_size = sizeof (struct cache_file_new) + cache_entry_count * sizeof (struct file_entry_new); - file_entries_new = - (struct cache_file_new *) xmalloc (file_entries_new_size); + file_entries_new = xmalloc (file_entries_new_size); /* Fill in the header. */ - memset (file_entries_new, 0, sizeof (struct cache_file_new)); + memset (file_entries_new, '\0', sizeof (struct cache_file_new)); memcpy (file_entries_new->magic, CACHEMAGIC_NEW, sizeof CACHEMAGIC_NEW - 1); memcpy (file_entries_new->version, CACHE_VERSION, @@ -343,17 +329,24 @@ save_cache (const char *cache_name) file_entries_new->len_strings = total_strlen; } - pad = ALIGN_CACHE (file_entries_size) - file_entries_size; + /* Pad for alignment of cache_file_new. */ + size_t pad = ALIGN_CACHE (file_entries_size) - file_entries_size; /* If we have both formats, we hide the new format in the strings table, we have to adjust all string indices for this so that old libc5/glibc 2 dynamic linkers just ignore them. */ + unsigned int str_offset; if (opt_format != 0) str_offset = file_entries_new_size; else str_offset = 0; - str = strings; + /* An array for all strings. */ + char *strings = xmalloc (total_strlen); + char *str = strings; + int idx_old; + int idx_new; + for (idx_old = 0, idx_new = 0, entry = entries; entry != NULL; entry = entry->next, ++idx_new) { @@ -375,21 +368,18 @@ save_cache (const char *cache_name) file_entries_new->libs[idx_new].hwcap = entry->hwcap; file_entries_new->libs[idx_new].key = str_offset; } - len = strlen (entry->lib); - str = stpcpy (str, entry->lib); - /* Account the final NUL. */ - ++str; - str_offset += len + 1; + + size_t len = strlen (entry->lib) + 1; + str = mempcpy (str, entry->lib, len); + str_offset += len; /* Then the path. */ if (opt_format != 2 && entry->hwcap == 0) file_entries->libs[idx_old].value = str_offset + pad; if (opt_format != 0) file_entries_new->libs[idx_new].value = str_offset; - len = strlen (entry->path); - str = stpcpy (str, entry->path); - /* Account the final NUL. */ - ++str; - str_offset += len + 1; + len = strlen (entry->path) + 1; + str = mempcpy (str, entry->path, len); + str_offset += len; /* Ignore entries with hwcap for old format. */ if (entry->hwcap == 0) ++idx_old; @@ -403,16 +393,12 @@ save_cache (const char *cache_name) /* Write out the cache. */ /* Write cache first to a temporary file and rename it later. */ - temp_name = xmalloc (strlen (cache_name) + 2); + char *temp_name = xmalloc (strlen (cache_name) + 2); sprintf (temp_name, "%s~", cache_name); - /* First remove an old copy if it exists. */ - if (unlink (temp_name) && errno != ENOENT) - error (EXIT_FAILURE, errno, _("Can't remove old temporary cache file %s"), - temp_name); /* Create file. */ - fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, - S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR); + int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, + S_IRUSR|S_IWUSR); if (fd < 0) error (EXIT_FAILURE, errno, _("Can't create temporary cache file %s"), temp_name); @@ -439,11 +425,10 @@ save_cache (const char *cache_name) error (EXIT_FAILURE, errno, _("Writing of cache data failed")); } - if (write (fd, strings, total_strlen) != (ssize_t) total_strlen) + if (write (fd, strings, total_strlen) != (ssize_t) total_strlen + || close (fd)) error (EXIT_FAILURE, errno, _("Writing of cache data failed")); - close (fd); - /* Make sure user can always read cache file */ if (chmod (temp_name, S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR)) error (EXIT_FAILURE, errno, @@ -463,8 +448,6 @@ save_cache (const char *cache_name) while (entries) { entry = entries; - free (entry->path); - free (entry->lib); entries = entries->next; free (entry); } @@ -476,33 +459,29 @@ void add_to_cache (const char *path, const char *lib, int flags, unsigned int osversion, uint64_t hwcap) { - struct cache_entry *new_entry, *ptr, *prev; - char *full_path; - size_t len, i; - - new_entry = (struct cache_entry *) xmalloc (sizeof (struct cache_entry)); - - len = strlen (lib) + strlen (path) + 2; - - full_path = (char *) xmalloc (len); - snprintf (full_path, len, "%s/%s", path, lib); - - new_entry->lib = xstrdup (lib); - new_entry->path = full_path; + size_t liblen = strlen (lib) + 1; + size_t len = liblen + strlen (path) + 1; + struct cache_entry *new_entry + = xmalloc (sizeof (struct cache_entry) + liblen + len); + + new_entry->lib = memcpy ((char *) (new_entry + 1), lib, liblen); + new_entry->path = new_entry->lib + liblen; + snprintf (new_entry->path, len, "%s/%s", path, lib); new_entry->flags = flags; new_entry->osversion = osversion; new_entry->hwcap = hwcap; new_entry->bits_hwcap = 0; /* Count the number of bits set in the masked value. */ - for (i = 0; (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i) + for (size_t i = 0; + (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i) if ((hwcap & (1ULL << i)) != 0) ++new_entry->bits_hwcap; /* Keep the list sorted - search for right place to insert. */ - ptr = entries; - prev = entries; + struct cache_entry *ptr = entries; + struct cache_entry *prev = entries; while (ptr != NULL) { if (compare (ptr, new_entry) > 0) @@ -522,3 +501,304 @@ add_to_cache (const char *path, const ch prev->next = new_entry; } } + + +/* Auxiliary cache. */ + +struct aux_cache_entry_id +{ + uint64_t ino; + uint64_t ctime; + uint64_t size; + uint64_t dev; +}; + +struct aux_cache_entry +{ + struct aux_cache_entry_id id; + int flags; + unsigned int osversion; + int used; + char *soname; + struct aux_cache_entry *next; +}; + +#define AUX_CACHEMAGIC "glibc-ld.so.auxcache-1.0" + +struct aux_cache_file_entry +{ + struct aux_cache_entry_id id; /* Unique id of entry. */ + int32_t flags; /* This is 1 for an ELF library. */ + uint32_t soname; /* String table indice. */ + uint32_t osversion; /* Required OS version. */ + int32_t pad; +}; + +/* ldconfig maintains an auxiliary cache file that allows + only reading those libraries that have changed since the last iteration. + For this for each library some information is cached in the auxiliary + cache. */ +struct aux_cache_file +{ + char magic[sizeof AUX_CACHEMAGIC - 1]; + uint32_t nlibs; /* Number of entries. */ + uint32_t len_strings; /* Size of string table. */ + struct aux_cache_file_entry libs[0]; /* Entries describing libraries. */ + /* After this the string table of size len_strings is found. */ +}; + +static unsigned int primes[] = +{ + 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, + 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, + 67108859, 134217689, 268435399, 536870909, 1073741789, 2147483647 +}; + +static size_t aux_hash_size; +static struct aux_cache_entry **aux_hash; + +/* Simplistic hash function for aux_cache_entry_id. */ +static unsigned int +aux_cache_entry_id_hash (struct aux_cache_entry_id *id) +{ + uint64_t ret = ((id->ino * 11 + id->ctime) * 11 + id->size) * 11 + id->dev; + return ret ^ (ret >> 32); +} + +static size_t nextprime (size_t x) +{ + for (unsigned int i = 0; i < sizeof (primes) / sizeof (primes[0]); ++i) + if (primes[i] >= x) + return primes[i]; + return x; +} + +void +init_aux_cache (void) +{ + aux_hash_size = primes[3]; + aux_hash = xcalloc (aux_hash_size, sizeof (struct aux_cache_entry *)); +} + +int +search_aux_cache (struct stat64 *stat_buf, int *flags, + unsigned int *osversion, char **soname) +{ + struct aux_cache_entry_id id; + id.ino = (uint64_t) stat_buf->st_ino; + id.ctime = (uint64_t) stat_buf->st_ctime; + id.size = (uint64_t) stat_buf->st_size; + id.dev = (uint64_t) stat_buf->st_dev; + + unsigned int hash = aux_cache_entry_id_hash (&id); + struct aux_cache_entry *entry; + for (entry = aux_hash[hash % aux_hash_size]; entry; entry = entry->next) + if (id.ino == entry->id.ino + && id.ctime == entry->id.ctime + && id.size == entry->id.size + && id.dev == entry->id.dev) + { + *flags = entry->flags; + *osversion = entry->osversion; + if (entry->soname != NULL) + *soname = xstrdup (entry->soname); + else + *soname = NULL; + entry->used = 1; + return 1; + } + + return 0; +} + +static void +insert_to_aux_cache (struct aux_cache_entry_id *id, int flags, + unsigned int osversion, const char *soname, int used) +{ + size_t hash = aux_cache_entry_id_hash (id) % aux_hash_size; + struct aux_cache_entry *entry; + for (entry = aux_hash[hash]; entry; entry = entry->next) + if (id->ino == entry->id.ino + && id->ctime == entry->id.ctime + && id->size == entry->id.size + && id->dev == entry->id.dev) + abort (); + + size_t len = soname ? strlen (soname) + 1 : 0; + entry = xmalloc (sizeof (struct aux_cache_entry) + len); + entry->id = *id; + entry->flags = flags; + entry->osversion = osversion; + entry->used = used; + if (soname != NULL) + entry->soname = memcpy ((char *) (entry + 1), soname, len); + else + entry->soname = NULL; + entry->next = aux_hash[hash]; + aux_hash[hash] = entry; +} + +void +add_to_aux_cache (struct stat64 *stat_buf, int flags, + unsigned int osversion, const char *soname) +{ + struct aux_cache_entry_id id; + id.ino = (uint64_t) stat_buf->st_ino; + id.ctime = (uint64_t) stat_buf->st_ctime; + id.size = (uint64_t) stat_buf->st_size; + id.dev = (uint64_t) stat_buf->st_dev; + insert_to_aux_cache (&id, flags, osversion, soname, 1); +} + +/* Load auxiliary cache to search for unchanged entries. */ +void +load_aux_cache (const char *aux_cache_name) +{ + int fd = open (aux_cache_name, O_RDONLY); + if (fd < 0) + { + init_aux_cache (); + return; + } + + struct stat64 st; + if (fstat64 (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file)) + { + close (fd); + init_aux_cache (); + return; + } + + size_t aux_cache_size = st.st_size; + struct aux_cache_file *aux_cache + = mmap (NULL, aux_cache_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (aux_cache == MAP_FAILED + || aux_cache_size < sizeof (struct aux_cache_file) + || memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1) + || aux_cache->nlibs < 0 + || aux_cache->nlibs >= aux_cache_size) + { + close (fd); + init_aux_cache (); + return; + } + + aux_hash_size = nextprime (aux_cache->nlibs); + aux_hash = xcalloc (aux_hash_size, sizeof (struct aux_cache_entry *)); + + const char *aux_cache_data + = (const char *) &aux_cache->libs[aux_cache->nlibs]; + for (unsigned int i = 0; i < aux_cache->nlibs; ++i) + insert_to_aux_cache (&aux_cache->libs[i].id, + aux_cache->libs[i].flags, + aux_cache->libs[i].osversion, + aux_cache->libs[i].soname == 0 + ? NULL : aux_cache_data + aux_cache->libs[i].soname, + 0); + + munmap (aux_cache, aux_cache_size); + close (fd); +} + +/* Save the contents of the auxiliary cache. */ +void +save_aux_cache (const char *aux_cache_name) +{ + /* Count the length of all sonames. We start with empty string. */ + size_t total_strlen = 1; + /* Number of cache entries. */ + int cache_entry_count = 0; + + for (size_t i = 0; i < aux_hash_size; ++i) + for (struct aux_cache_entry *entry = aux_hash[i]; + entry != NULL; entry = entry->next) + if (entry->used) + { + ++cache_entry_count; + if (entry->soname != NULL) + total_strlen += strlen (entry->soname) + 1; + } + + /* Auxiliary cache. */ + size_t file_entries_size + = sizeof (struct aux_cache_file) + + cache_entry_count * sizeof (struct aux_cache_file_entry); + struct aux_cache_file *file_entries + = xmalloc (file_entries_size + total_strlen); + + /* Fill in the header of the auxiliary cache. */ + memset (file_entries, '\0', sizeof (struct aux_cache_file)); + memcpy (file_entries->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1); + + file_entries->nlibs = cache_entry_count; + file_entries->len_strings = total_strlen; + + /* Initial String offset for auxiliary cache is always after the + special empty string. */ + unsigned int str_offset = 1; + + /* An array for all strings. */ + char *str = (char *) file_entries + file_entries_size; + *str++ = '\0'; + + size_t idx = 0; + for (size_t i = 0; i < aux_hash_size; ++i) + for (struct aux_cache_entry *entry = aux_hash[i]; + entry != NULL; entry = entry->next) + if (entry->used) + { + file_entries->libs[idx].id = entry->id; + file_entries->libs[idx].flags = entry->flags; + if (entry->soname == NULL) + file_entries->libs[idx].soname = 0; + else + { + file_entries->libs[idx].soname = str_offset; + + size_t len = strlen (entry->soname) + 1; + str = mempcpy (str, entry->soname, len); + str_offset += len; + } + file_entries->libs[idx].osversion = entry->osversion; + file_entries->libs[idx++].pad = 0; + } + + /* Write out auxiliary cache file. */ + /* Write auxiliary cache first to a temporary file and rename it later. */ + + char *temp_name = xmalloc (strlen (aux_cache_name) + 2); + sprintf (temp_name, "%s~", aux_cache_name); + + /* Check that directory exists and create if needed. */ + char *dir = strdupa (aux_cache_name); + dir = dirname (dir); + + struct stat64 st; + if (stat64 (dir, &st) < 0) + { + if (mkdir (dir, 0700) < 0) + goto out_fail; + } + + /* Create file. */ + int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, + S_IRUSR|S_IWUSR); + if (fd < 0) + goto out_fail; + + if (write (fd, file_entries, file_entries_size + total_strlen) + != (ssize_t) (file_entries_size + total_strlen) + || close (fd)) + { + unlink (temp_name); + goto out_fail; + } + + /* Move temporary to its final location. */ + if (rename (temp_name, aux_cache_name)) + unlink (temp_name); + +out_fail: + /* Free allocated memory. */ + free (file_entries); +} --- libc/sysdeps/generic/ldconfig.h.jj 2003-03-14 06:32:49.000000000 +0100 +++ libc/sysdeps/generic/ldconfig.h 2007-08-01 18:54:26.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger , 1999. @@ -35,6 +35,9 @@ #define FLAG_MIPS64_LIBN32 0x0600 #define FLAG_MIPS64_LIBN64 0x0700 +/* Name of auxiliary cache. */ +#define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache" + /* Declared in cache.c. */ extern void print_cache (const char *cache_name); @@ -45,10 +48,24 @@ extern void save_cache (const char *cach extern void add_to_cache (const char *path, const char *lib, int flags, unsigned int osversion, uint64_t hwcap); +extern void init_aux_cache (void); + +extern void load_aux_cache (const char *aux_cache_name); + +extern int search_aux_cache (struct stat64 *stat_buf, int *flags, + unsigned int *osversion, char **soname); + +extern void add_to_aux_cache (struct stat64 *stat_buf, int flags, + unsigned int osversion, const char *soname); + +extern void save_aux_cache (const char *aux_cache_name); + /* Declared in readlib.c. */ extern int process_file (const char *real_file_name, const char *file_name, const char *lib, int *flag, unsigned int *osversion, - char **soname, int is_link); + char **soname, int is_link, struct stat64 *stat_buf); + +extern char *implicit_soname (const char *lib, int flag); /* Declared in readelflib.c. */ extern int process_elf_file (const char *file_name, const char *lib, int *flag, Jakub From roland@redhat.com Sun Aug 12 22:55:00 2007 From: roland@redhat.com (Roland McGrath) Date: Sun, 12 Aug 2007 22:55:00 -0000 Subject: [PATCH] ldconfig speedup In-Reply-To: Jakub Jelinek's message of Sunday, 12 August 2007 21:57:35 +0200 <20070812195735.GK4603@sunsite.mff.cuni.cz> Message-ID: <20070812225508.BB75D4D057D@magilla.localdomain> > +static unsigned int primes[] = const Otherwise, I think this is ready to go in now. Thanks, Roland From jakub@redhat.com Mon Aug 13 13:39:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 13 Aug 2007 13:39:00 -0000 Subject: [PATCH] Some #include additions Message-ID: <20070813134002.GL4603@sunsite.mff.cuni.cz> Hi! The following sources use __ASSUME_* macros but don't include kernel-features.h. Although some of them might get that header indirectly, some don't and IMHO it is better to be able to check for this easily. Most .c/.h files that use __ASSUME_* include kernel-features.h explicitly. 2007-08-13 Jakub Jelinek * nscd/servicescache.c: Include kernel-features.h. * nscd/gai.c: Likewise. * sysdeps/unix/sysv/linux/statfs64.c: Likewise. * sysdeps/unix/sysv/linux/fstatfs64.c: Likewise. * sysdeps/unix/sysv/linux/fxstatat.c: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/mmap.S: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S: Likewise. * sysdeps/unix/sysv/linux/xstatconv.c: Likewise. * sysdeps/unix/sysv/linux/if_index.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c: Likewise. * sysdeps/unix/sysv/linux/ifaddrs.c: Likewise. nptl/ * allocatestack.c: Include kernel-features.h. * pthread_create.c: Likewise. * pthread_mutex_init.c: Likewise. * init.c: Likewise. * pthread_cond_timedwait.c: Likewise. * sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S: Likewise. * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise. * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise. --- libc/nscd/servicescache.c.jj 2007-07-16 09:58:46.000000000 +0200 +++ libc/nscd/servicescache.c 2007-08-13 08:52:56.000000000 +0200 @@ -24,6 +24,7 @@ #include #include #include +#include #include "nscd.h" #include "dbg_log.h" --- libc/nscd/gai.c.jj 2007-07-16 09:58:46.000000000 +0200 +++ libc/nscd/gai.c 2007-08-13 08:53:17.000000000 +0200 @@ -17,6 +17,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include /* This file uses the getaddrinfo code but it compiles it without NSCD support. We just need a few symbol renames. */ #define __inet_aton inet_aton --- libc/nptl/allocatestack.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/allocatestack.c 2007-08-13 08:54:16.000000000 +0200 @@ -28,6 +28,7 @@ #include #include #include +#include #ifndef NEED_SEPARATE_REGISTER_STACK --- libc/nptl/pthread_create.c.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/pthread_create.c 2007-08-13 08:53:57.000000000 +0200 @@ -27,6 +27,7 @@ #include #include #include +#include #include --- libc/nptl/pthread_mutex_init.c.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/pthread_mutex_init.c 2007-08-13 08:53:45.000000000 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include #include "pthreadP.h" static const struct pthread_mutexattr default_attr = --- libc/nptl/init.c.jj 2007-07-29 11:45:14.000000000 +0200 +++ libc/nptl/init.c 2007-08-13 08:54:07.000000000 +0200 @@ -33,6 +33,7 @@ #include #include #include +#include /* Size and alignment of static TLS block. */ --- libc/nptl/pthread_cond_timedwait.c.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/pthread_cond_timedwait.c 2007-08-13 08:53:36.000000000 +0200 @@ -23,6 +23,7 @@ #include #include #include +#include #include --- libc/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h 2007-08-13 08:54:24.000000000 +0200 @@ -24,6 +24,7 @@ #include #include #include +#include #define __NR_futex 394 --- libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h 2007-08-13 08:54:32.000000000 +0200 @@ -25,6 +25,7 @@ #include #include #include +#include #define __NR_futex 1230 #define FUTEX_WAIT 0 --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S 2007-08-13 08:55:03.000000000 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include .text --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S 2007-08-13 08:55:18.000000000 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include .text --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S 2007-08-13 08:54:48.000000000 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include .text --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S 2007-08-13 08:54:40.000000000 +0200 @@ -20,6 +20,7 @@ #include #include #include +#include .text --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S 2007-08-13 08:54:56.000000000 +0200 @@ -22,6 +22,7 @@ #include #include #include +#include .text --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S 2007-08-13 08:55:11.000000000 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include .text --- libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h 2007-08-13 08:55:26.000000000 +0200 @@ -24,6 +24,7 @@ #include #include #include +#include #define SYS_futex 238 #define FUTEX_WAIT 0 --- libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h 2007-08-13 08:55:34.000000000 +0200 @@ -24,6 +24,7 @@ #include #include #include +#include #ifndef __NR_futex # define __NR_futex 221 --- libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h 2007-08-13 08:55:42.000000000 +0200 @@ -24,6 +24,7 @@ #include #include #include +#include #define FUTEX_WAIT 0 --- libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S.jj 2007-08-04 21:42:29.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S 2007-08-13 08:55:50.000000000 +0200 @@ -22,6 +22,7 @@ #include #include #include "lowlevel-atomic.h" +#include .text --- libc/sysdeps/unix/sysv/linux/statfs64.c.jj 2004-04-03 09:47:05.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/statfs64.c 2007-08-13 08:58:19.000000000 +0200 @@ -1,5 +1,5 @@ /* Return information about the filesystem on which FILE resides. - Copyright (C) 1996-2000,2003,2004 Free Software Foundation, Inc. + Copyright (C) 1996-2000,2003,2004,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 @@ -22,6 +22,7 @@ #include #include #include +#include # if __ASSUME_STATFS64 == 0 --- libc/sysdeps/unix/sysv/linux/fstatfs64.c.jj 2003-06-24 20:58:15.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/fstatfs64.c 2007-08-13 08:58:47.000000000 +0200 @@ -1,5 +1,6 @@ /* Return information about the filesystem on which FD resides. - Copyright (C) 1996,1997,1998,1999,2000,2003 Free Software Foundation, Inc. + Copyright (C) 1996,1997,1998,1999,2000,2003,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 @@ -22,6 +23,7 @@ #include #include #include +#include /* Defined in statfs64.c. */ extern int __no_statfs64 attribute_hidden; --- libc/sysdeps/unix/sysv/linux/fxstatat.c.jj 2006-02-12 22:32:08.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/fxstatat.c 2007-08-13 08:58:12.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2005, 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 @@ -30,6 +30,7 @@ #include #include #include +#include #include --- libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S.jj 2003-12-06 01:18:40.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S 2007-08-13 08:58:24.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -18,6 +18,7 @@ 02111-1307 USA. */ #include +#include #define EINVAL 22 --- libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S.jj 2003-12-06 01:18:40.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S 2007-08-13 08:58:29.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -18,6 +18,7 @@ 02111-1307 USA. */ #include +#include #define EINVAL 22 #define ENOSYS 38 --- libc/sysdeps/unix/sysv/linux/xstatconv.c.jj 2003-06-16 19:02:55.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/xstatconv.c 2007-08-13 08:58:06.000000000 +0200 @@ -1,5 +1,6 @@ /* Convert between the kernel's `struct stat' format, and libc's. - Copyright (C) 1991,1995-1997,2000,2002,2003 Free Software Foundation, Inc. + Copyright (C) 1991,1995-1997,2000,2002,2003,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 @@ -20,6 +21,7 @@ #include #include #include +#include #ifdef STAT_IS_KERNEL_STAT --- libc/sysdeps/unix/sysv/linux/if_index.c.jj 2005-06-14 01:55:23.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/if_index.c 2007-08-13 08:58:32.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005 +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -28,6 +28,7 @@ #include #include #include +#include #include "netlinkaccess.h" --- libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c.jj 2006-01-09 20:44:10.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c 2007-08-13 08:57:14.000000000 +0200 @@ -1,3 +1,5 @@ +#include + #include "../../i386/xstat.c" #ifdef __NR_stat64 --- libc/sysdeps/unix/sysv/linux/ifaddrs.c.jj 2007-03-16 11:33:57.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/ifaddrs.c 2007-08-13 08:57:34.000000000 +0200 @@ -33,6 +33,7 @@ #include #include #include +#include #include "netlinkaccess.h" Jakub From jakub@redhat.com Mon Aug 13 13:52:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 13 Aug 2007 13:52:00 -0000 Subject: [PATCH] i?86 fixes Message-ID: <20070813135741.GM4603@sunsite.mff.cuni.cz> Hi! The patch I sent last Monday didn't adjust i[456]86 pthread_cond_*.S so i?86 port was broken on kernels with private futex. The following should fix that together with other issues I found when building --enable-kernel=2.6.9 and --enable-kernel=2.6.22 i686 and x86_64 glibcs. The x86_64 pthread_cond_broadcast change is just an optimization, the dep_mutex(cvptr) value is already loaded in %r8, so it is faster to compare just the register. The x86_64 pthread_cond_signal change is a real bugfix, by xoring FUTEX_WAKE_OP resp. FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG with (FUTEX_WAKE_OP|FUTEX_WAKE) we would do FUTEX_WAIT resp. FUTEX_WAIT|FUTEX_PRIVATE_FLAG rather than the desired FUTEX_WAKE (or private wake). It would be best to rewrite the hardcoded .eh_frame into .cfi_* directives, but that can wait for later, in the mean time using DW_CFA_advance_loc4 is safe no matter how many insns were inserted (had to debug weird failures because some DW_CFA_advance_loc opcode embedded args grew over 0x3f) and gas optimizes it into DW_CFA_advance_loc{,1,2} when the value is small enough (unlike explicit DW_CFA_advance_loc{,1,2} which is never optimized by gas). 2007-08-13 Jakub Jelinek * sysdeps/unix/sysv/linux/i386/lowlevellock.h (__lll_private_flag): Fix a pasto. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S (__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S (__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Include kernel-features.h. (__pthread_cond_wait, __condvar_w_cleanup): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. Switch DW_CFA_advance_loc1 and some DW_CFA_advance_loc .eh_frame opcodes to DW_CFA_advance_loc4. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S (__pthread_cond_timedwait, __condvar_tw_cleanup): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. Switch DW_CFA_advance_loc{1,2} and some DW_CFA_advance_loc .eh_frame opcodes to DW_CFA_advance_loc4. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Use #ifdef __ASSUME_PRIVATE_FUTEX instead of #if __ASSUME_PRIVATE_FUTEX. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S (__pthread_cond_broadcast): Compare %r8 instead of dep_mutex-cond_*(%rdi) with $-1. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S (__pthread_cond_signal): Xor FUTEX_WAKE_OP with FUTEX_WAKE instead of oring. --- libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h 2007-08-13 14:20:47.000000000 +0200 @@ -83,7 +83,7 @@ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \ : (fl)) \ : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \ - asm ("andl %%fs:%P1, %0" : "+r" (__fl) \ + asm ("andl %%gs:%P1, %0" : "+r" (__fl) \ : "i" (offsetof (struct pthread, header.private_futex))); \ __fl | (fl); })) # endif --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S 2007-08-13 14:05:05.000000000 +0200 @@ -22,6 +22,7 @@ #include #include #include +#include .text @@ -100,7 +101,20 @@ __pthread_cond_wait: 4: call __pthread_enable_asynccancel movl %eax, (%esp) - movl %esi, %ecx /* movl $FUTEX_WAIT, %ecx */ +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif +#if FUTEX_WAIT != 0 + addl $FUTEX_WAIT, %ecx +#endif movl %edi, %edx addl $cond_futex, %ebx .Ladd_cond_futex: @@ -161,7 +175,18 @@ __pthread_cond_wait: addl $cond_nwaiters, %ebx movl $SYS_futex, %eax - movl $FUTEX_WAKE, %ecx +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_nwaiters(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif + addl $FUTEX_WAKE, %ecx movl $1, %edx ENTER_KERNEL subl $cond_nwaiters, %ebx @@ -197,8 +222,16 @@ __pthread_cond_wait: #else leal cond_lock(%ebx), %edx #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_lock_wait jmp 2b @@ -210,8 +243,16 @@ __pthread_cond_wait: #else leal cond_lock(%ebx), %eax #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake jmp 4b @@ -222,8 +263,16 @@ __pthread_cond_wait: #else leal cond_lock(%ebx), %edx #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_lock_wait jmp 6b @@ -234,8 +283,16 @@ __pthread_cond_wait: #else leal cond_lock(%ebx), %eax #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake jmp 11b @@ -256,8 +313,16 @@ __pthread_cond_wait: #else leal cond_lock(%ebx), %eax #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake movl %esi, %eax @@ -292,8 +357,16 @@ __condvar_w_cleanup: #else leal cond_lock(%ebx), %edx #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_lock_wait 1: movl broadcast_seq(%ebx), %eax @@ -332,7 +405,18 @@ __condvar_w_cleanup: addl $cond_nwaiters, %ebx movl $SYS_futex, %eax - movl $FUTEX_WAKE, %ecx +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_nwaiters(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif + addl $FUTEX_WAKE, %ecx movl $1, %edx ENTER_KERNEL subl $cond_nwaiters, %ebx @@ -351,15 +435,34 @@ __condvar_w_cleanup: #else leal cond_lock(%ebx), %eax #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake /* Wake up all waiters to make sure no signal gets lost. */ 2: testl %edi, %edi jnz 5f addl $cond_futex, %ebx - movl $FUTEX_WAKE, %ecx +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_futex(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif + addl $FUTEX_WAKE, %ecx movl $SYS_futex, %eax movl $0x7fffffff, %edx ENTER_KERNEL @@ -473,12 +576,12 @@ __condvar_w_cleanup: .uleb128 16 .byte 0x83 # DW_CFA_offset %ebx .uleb128 4 - .byte 2 # DW_CFA_advance_loc1 - .byte .Lsubl-.Lpush_ebx + .byte 4 # DW_CFA_advance_loc4 + .4byte .Lsubl-.Lpush_ebx .byte 14 # DW_CFA_def_cfa_offset .uleb128 16+FRAME_SIZE - .byte 2 # DW_CFA_advance_loc1 - .byte .Laddl-.Lsubl + .byte 4 # DW_CFA_advance_loc4 + .4byte .Laddl-.Lsubl .byte 14 # DW_CFA_def_cfa_offset .uleb128 16 .byte 0x40+ .Lpop_ebx-.Laddl # DW_CFA_advance_loc+N @@ -502,13 +605,16 @@ __condvar_w_cleanup: .uleb128 3 .byte 0x83 # DW_CFA_offset %ebx .uleb128 4 - .byte 0x40+.LSbl2-.LSbl1 # DW_CFA_advance_loc+N + .byte 4 # DW_CFA_advance_loc4 + .4byte .LSbl2-.LSbl1 .byte 14 # DW_CFA_def_cfa_offset .uleb128 16+FRAME_SIZE - .byte 0x40+.LSbl3-.LSbl2 # DW_CFA_advance_loc+N + .byte 4 # DW_CFA_advance_loc4 + .4byte .LSbl3-.LSbl2 .byte 14 # DW_CFA_def_cfa_offset .uleb128 16 - .byte 0x40+.LSbl4-.LSbl3 # DW_CFA_advance_loc+N + .byte 4 # DW_CFA_advance_loc4 + .4byte .LSbl4-.LSbl3 .byte 14 # DW_CFA_def_cfa_offset .uleb128 16+FRAME_SIZE .align 4 --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S.jj 2007-08-13 08:54:48.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S 2007-08-13 10:44:59.000000000 +0200 @@ -69,7 +69,7 @@ __pthread_rwlock_rdlock: jne 10f 11: -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX movzbl PSHARED(%ebx), %ecx xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx #else --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S.jj 2007-08-13 08:55:11.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S 2007-08-13 10:45:08.000000000 +0200 @@ -98,7 +98,7 @@ pthread_rwlock_timedwrlock: movl %edx, 4(%esp) movl %esi, %edx -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX movzbl PSHARED(%ebp), %ecx xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx #else --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S.jj 2007-08-13 08:54:40.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S 2007-08-13 10:44:55.000000000 +0200 @@ -74,7 +74,7 @@ __pthread_rwlock_unlock: jne 7f 8: -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX movzbl PSHARED(%edi), %ecx xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx #else --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S.jj 2007-08-13 08:55:18.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S 2007-08-13 10:45:12.000000000 +0200 @@ -67,7 +67,7 @@ __pthread_rwlock_wrlock: jne 10f 11: -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX movzbl PSHARED(%ebx), %ecx xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx #else --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S.jj 2007-08-13 08:55:03.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S 2007-08-13 10:45:03.000000000 +0200 @@ -100,7 +100,7 @@ pthread_rwlock_timedrdlock: movl %edx, 4(%esp) movl %esi, %edx -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX movzbl PSHARED(%ebp), %ecx xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx #else --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S 2007-08-13 10:43:10.000000000 +0200 @@ -83,11 +83,18 @@ __pthread_cond_broadcast: je 9f /* XXX: The kernel so far doesn't support requeue to PI futex. */ - testl $PI_BIT, MUTEX_KIND(%edi) + /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same + type of futex (private resp. shared). */ + testl $(PI_BIT | PS_BIT), MUTEX_KIND(%edi) jne 9f /* Wake up all threads. */ - movl $FUTEX_CMP_REQUEUE, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + movl $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %ecx +#else + movl %gs:PRIVATE_FUTEX, %ecx + orl $FUTEX_CMP_REQUEUE, %ecx +#endif movl $SYS_futex, %eax movl $0x7fffffff, %esi movl $1, %edx @@ -132,28 +139,63 @@ __pthread_cond_broadcast: #else leal cond_lock(%ebx), %edx #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_lock_wait jmp 2b /* Unlock in loop requires waekup. */ 5: leal cond_lock-cond_futex(%ebx), %eax - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_futex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake jmp 6b /* Unlock in loop requires waekup. */ 7: leal cond_lock-cond_futex(%ebx), %eax - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_futex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake jmp 8b 9: /* The futex requeue functionality is not available. */ movl $0x7fffffff, %edx - movl $FUTEX_WAKE, %ecx +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_futex(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif + addl $FUTEX_WAKE, %ecx movl $SYS_futex, %eax ENTER_KERNEL jmp 10b --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S.jj 2007-08-01 10:50:19.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S 2007-08-13 10:43:20.000000000 +0200 @@ -70,7 +70,18 @@ __pthread_cond_signal: /* Wake up one thread. */ pushl %esi pushl %ebp - movl $FUTEX_WAKE_OP, %ecx +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_futex(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif + addl $FUTEX_WAKE_OP, %ecx movl $SYS_futex, %eax movl $1, %edx movl $1, %esi @@ -92,7 +103,9 @@ __pthread_cond_signal: popl %ebx ret -7: movl $FUTEX_WAKE, %ecx +7: /* %ecx should be either FUTEX_WAKE_OP or + FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */ + xorl $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %ecx movl $SYS_futex, %eax /* %edx should be 1 already from $FUTEX_WAKE_OP syscall. movl $1, %edx */ @@ -106,8 +119,16 @@ __pthread_cond_signal: /* Unlock in loop requires wakeup. */ 5: movl %edi, %eax - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_futex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake jmp 6b @@ -118,8 +139,16 @@ __pthread_cond_signal: #else leal cond_lock(%edi), %edx #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%edi) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_lock_wait jmp 2b --- libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S.jj 2007-08-13 08:54:56.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S 2007-08-13 14:12:17.000000000 +0200 @@ -158,7 +158,20 @@ __pthread_cond_timedwait: movl %eax, (%esp) leal 4(%esp), %esi - xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */ +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif +#if FUTEX_WAIT != 0 + addl $FUTEX_WAIT, %ecx +#endif movl %edi, %edx addl $cond_futex, %ebx .Ladd_cond_futex: @@ -232,7 +245,18 @@ __pthread_cond_timedwait: addl $cond_nwaiters, %ebx movl $SYS_futex, %eax - movl $FUTEX_WAKE, %ecx +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_nwaiters(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif + addl $FUTEX_WAKE, %ecx movl $1, %edx ENTER_KERNEL subl $cond_nwaiters, %ebx @@ -280,8 +304,16 @@ __pthread_cond_timedwait: #else leal cond_lock(%ebx), %edx #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_lock_wait jmp 2b @@ -293,8 +325,16 @@ __pthread_cond_timedwait: #else leal cond_lock(%ebx), %eax #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake jmp 4b @@ -305,8 +345,16 @@ __pthread_cond_timedwait: #else leal cond_lock(%ebx), %edx #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_lock_wait jmp 6b @@ -317,8 +365,16 @@ __pthread_cond_timedwait: #else leal cond_lock(%ebx), %eax #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake jmp 11b @@ -339,8 +395,16 @@ __pthread_cond_timedwait: #else leal cond_lock(%ebx), %eax #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake movl %esi, %eax @@ -401,8 +465,16 @@ __condvar_tw_cleanup: #else leal cond_lock(%ebx), %edx #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_lock_wait 1: movl broadcast_seq(%ebx), %eax @@ -441,7 +513,18 @@ __condvar_tw_cleanup: addl $cond_nwaiters, %ebx movl $SYS_futex, %eax - movl $FUTEX_WAKE, %ecx +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_nwaiters(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif + addl $FUTEX_WAKE, %ecx movl $1, %edx ENTER_KERNEL subl $cond_nwaiters, %ebx @@ -460,15 +543,34 @@ __condvar_tw_cleanup: #else leal cond_lock(%ebx), %eax #endif - /* XYZ */ - movl $LLL_SHARED, %ecx +#if (LLL_SHARED-LLL_PRIVATE) > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex(%ebx) + setne %cl + subl $1, %ecx + andl $(LLL_SHARED-LLL_PRIVATE), %ecx +#if LLL_PRIVATE != 0 + addl $LLL_PRIVATE, %ecx +#endif call __lll_unlock_wake /* Wake up all waiters to make sure no signal gets lost. */ 2: testl %edi, %edi jnz 5f addl $cond_futex, %ebx - movl $FUTEX_WAKE, %ecx +#if FUTEX_PRIVATE_FLAG > 255 + xorl %ecx, %ecx +#endif + cmpl $-1, dep_mutex-cond_futex(%ebx) + sete %cl + subl $1, %ecx +#ifdef __ASSUME_PRIVATE_FUTEX + andl $FUTEX_PRIVATE_FLAG, %ecx +#else + andl %gs:PRIVATE_FUTEX, %ecx +#endif + addl $FUTEX_WAKE, %ecx movl $SYS_futex, %eax movl $0x7fffffff, %edx ENTER_KERNEL @@ -588,12 +690,12 @@ __condvar_tw_cleanup: .uleb128 20 .byte 0x83 # DW_CFA_offset %ebx .uleb128 5 - .byte 2 # DW_CFA_advance_loc1 - .byte .Lsubl-.Lpush_ebx + .byte 4 # DW_CFA_advance_loc4 + .4byte .Lsubl-.Lpush_ebx .byte 14 # DW_CFA_def_cfa_offset .uleb128 20+FRAME_SIZE - .byte 3 # DW_CFA_advance_loc2 - .2byte .Laddl-.Lsubl + .byte 4 # DW_CFA_advance_loc4 + .4byte .Laddl-.Lsubl .byte 14 # DW_CFA_def_cfa_offset .uleb128 20 .byte 0x40+.Lpop_ebx-.Laddl # DW_CFA_advance_loc+N @@ -615,7 +717,8 @@ __condvar_tw_cleanup: .byte 0x40+.LSbl1-.Lpop_edi # DW_CFA_advance_loc+N .byte 14 # DW_CFA_def_cfa_offset .uleb128 20 - .byte 0x40+.LSbl2-.LSbl1 # DW_CFA_advance_loc+N + .byte 4 # DW_CFA_advance_loc4 + .4byte .LSbl2-.LSbl1 .byte 14 # DW_CFA_def_cfa_offset .uleb128 20+FRAME_SIZE .byte 0x85 # DW_CFA_offset %ebp @@ -626,14 +729,15 @@ __condvar_tw_cleanup: .uleb128 4 .byte 0x83 # DW_CFA_offset %ebx .uleb128 5 - .byte 0x40+.LSbl3-.LSbl2 # DW_CFA_advance_loc+N + .byte 4 # DW_CFA_advance_loc4 + .4byte .LSbl3-.LSbl2 .byte 14 # DW_CFA_def_cfa_offset .uleb128 20 + .byte 4 # DW_CFA_advance_loc4 #if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS - .byte 0x40+.LSbl4-.LSbl3 # DW_CFA_advance_loc+N + .4byte .LSbl4-.LSbl3 #else - .byte 4 # DW_CFA_advance_loc4 - .long .LSbl5-.LSbl3 + .4byte .LSbl5-.LSbl3 #endif .byte 14 # DW_CFA_def_cfa_offset .uleb128 20+FRAME_SIZE --- libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S 2007-08-13 09:50:33.000000000 +0200 @@ -132,7 +132,7 @@ __pthread_cond_broadcast: /* Unlock in loop requires wakeup. */ 7: addq $cond_lock-cond_futex, %rdi - cmpq $-1, dep_mutex-cond_lock(%rdi) + cmpq $-1, %r8 movl $LLL_PRIVATE, %eax movl $LLL_SHARED, %esi cmovne %eax, %esi @@ -141,7 +141,7 @@ __pthread_cond_broadcast: jmp 8b 9: /* The futex requeue functionality is not available. */ - cmpq $-1, dep_mutex-cond_futex(%rdi) + cmpq $-1, %r8 movl $0x7fffffff, %edx #ifdef __ASSUME_PRIVATE_FUTEX movl $FUTEX_WAKE, %eax --- libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S.jj 2007-08-13 08:35:02.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S 2007-08-13 10:04:35.000000000 +0200 @@ -87,7 +87,7 @@ __pthread_cond_signal: 7: /* %esi should be either FUTEX_WAKE_OP or FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */ - xorl $(FUTEX_WAKE | FUTEX_WAKE_OP), %esi + xorl $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %esi movl $SYS_futex, %eax /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall. movl $1, %edx */ Jakub From jakub@redhat.com Mon Aug 13 14:04:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 13 Aug 2007 14:04:00 -0000 Subject: [PATCH] Some warning fixes from --enable-kernel=2.6.22 build Message-ID: <20070813141031.GN4603@sunsite.mff.cuni.cz> Hi! Fixes static function defined resp. declared, but never used warnings in dl-vdso*, pselect*, ppoll* and clock_settime and redefinition of ROUND in dl-sysdep.c. 2007-08-13 Jakub Jelinek * sysdeps/unix/sysv/linux/dl-vdso.c: Don't include dl-hash.h. * sysdeps/unix/sysv/linux/dl-vdso.h: Don't include dl-hash.h if NDEBUG. (CHECK_HASH): New macro. (PREPARE_VERSION): Use it. * sysdeps/unix/sysv/linux/pselect.c (__generic_pselect): Only provide prototype if not __ASSUME_PSELECT. * sysdeps/unix/sysv/linux/ppoll.c (__generic_ppoll): Only provide prototype if not __ASSUME_PPOLL. * sysdeps/unix/sysv/linux/dl-osinfo.h (ROUND): #undef after use. * sysdeps/unix/clock_settime.c (freq, __pthread_clock_settime, hp_timing_settime): Don't define or declare if HANDLED_CPUTIME is defined. --- libc/sysdeps/unix/sysv/linux/dl-vdso.c.jj 2007-08-12 21:33:14.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/dl-vdso.c 2007-08-13 12:11:02.000000000 +0200 @@ -18,7 +18,6 @@ 02111-1307 USA. */ #include "config.h" -#include #include --- libc/sysdeps/unix/sysv/linux/dl-vdso.h.jj 2007-08-12 21:33:23.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/dl-vdso.h 2007-08-13 12:14:12.000000000 +0200 @@ -21,9 +21,14 @@ #define _DL_VDSO_H 1 #include -#include #include +#ifdef NDEBUG +# define CHECK_HASH(var) do {} while (0) +#else +# include +# define CHECK_HASH(var) assert (var.hash == _dl_elf_hash (var.name)) +#endif /* Create version number record for lookup. */ #define PREPARE_VERSION(var, vname, vhash) \ @@ -31,7 +36,7 @@ var.name = vname; \ var.hidden = 1; \ var.hash = vhash; \ - assert (var.hash == _dl_elf_hash (vname)); \ + CHECK_HASH (var); \ /* We don't have a specific file where the symbol can be found. */ \ var.filename = NULL --- libc/sysdeps/unix/sysv/linux/pselect.c.jj 2006-01-21 09:15:36.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/pselect.c 2007-08-13 15:06:00.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 Free Software Foundation, Inc. +/* Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2006. @@ -26,10 +26,12 @@ #ifdef __NR_pselect6 +# ifndef __ASSUME_PSELECT static int __generic_pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask); +# endif int --- libc/sysdeps/unix/sysv/linux/dl-osinfo.h.jj 2007-08-10 15:31:54.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/dl-osinfo.h 2007-08-13 12:15:37.000000000 +0200 @@ -71,6 +71,7 @@ _dl_discover_osversion (void) #define ROUND(len) (((len) + sizeof note->n_type - 1) & -sizeof note->n_type) note = ((const void *) (note + 1) + ROUND (note->n_namesz) + ROUND (note->n_descsz)); +#undef ROUND } } } --- libc/sysdeps/unix/sysv/linux/ppoll.c.jj 2006-01-20 07:54:43.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/ppoll.c 2007-08-13 15:05:01.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 Free Software Foundation, Inc. +/* Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2006. @@ -26,9 +26,11 @@ #ifdef __NR_ppoll +# ifndef __ASSUME_PPOLL static int __generic_ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask); +# endif int --- libc/sysdeps/unix/clock_settime.c.jj 2006-08-13 10:06:21.000000000 +0200 +++ libc/sysdeps/unix/clock_settime.c 2007-08-13 15:28:28.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1999-2004, 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 @@ -23,7 +23,7 @@ #include -#if HP_TIMING_AVAIL +#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME /* Clock frequency of the processor. We make it a 64-bit variable because some jokers are already playing with processors with more than 4GHz. */ @@ -33,10 +33,8 @@ static hp_timing_t freq; /* This function is defined in the thread library. */ extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset) __attribute__ ((__weak__)); -#endif -#if HP_TIMING_AVAIL static int hp_timing_settime (clockid_t clock_id, const struct timespec *tp) { Jakub From kkojima@rr.iij4u.or.jp Mon Aug 13 14:56:00 2007 From: kkojima@rr.iij4u.or.jp (Kaz Kojima) Date: Mon, 13 Aug 2007 14:56:00 -0000 Subject: About stdlib/strto* change Message-ID: <20070813.235606.54189794.kkojima@rr.iij4u.or.jp> Hi, There is a build failure for SH during compiling stdlib/strtold_l.c: strtold_l.c:61: error: 'strtold_l' aliased to undefined symbol '__strtold_l' In Aug 6 Roland's change, libc_hidden_proto (__strtold_l) is added to include/stdlib.h and weak_alias (__STRTOLD, STRTOLD) is added to stdlib/strtold_l.c. It seems that libc_hedden_def is needed also for __strtold_l just before the above weak_alias statement. Is it right? x86 uses sysdeps/ieee754/ldbl-96/strtold_l.c which includes stdlib/strtod_l.c instead of stdlib/strtold_l.c and the corresponding libc_hedden_def was added to stdlib/strtod_l.c at that time. The attached patch works for me, though I suspect that I've missed something. Regards, kaz -- * stdlib/strtold.c: Add libc_hidden_def. --- ORIG/libc/stdlib/strtold_l.c 2005-12-14 20:14:13.000000000 +0900 +++ LOCAL/libc/stdlib/strtold_l.c 2007-08-13 20:43:24.000000000 +0900 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2002, 2004, 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 @@ -55,4 +55,7 @@ __STRTOLD (const STRING_TYPE *nptr, STRI { return INTERNAL (__STRTOD) (nptr, endptr, 0, loc); } +#if defined _LIBC && !defined USE_WIDE_CHAR +libc_hidden_def (__STRTOLD) +#endif weak_alias (__STRTOLD, STRTOLD) From jakub@redhat.com Mon Aug 13 15:22:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 13 Aug 2007 15:22:00 -0000 Subject: [PATCH] kernel-features.h updates Message-ID: <20070813152747.GO4603@sunsite.mff.cuni.cz> Hi! After noticing that even --enable-kernel=2.6.22 x86_64 glibc doesn't assume ppoll/pselect6 syscalls, I decided to skim recent patch-2.6.NN.bz2 and patch-2.6.NN-rc1.bz2 asm-*/unistd.h additions to see when exactly were recent syscalls introduced. 2007-08-13 Jakub Jelinek * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_PSELECT, __ASSUME_PPOLL, __ASSUME_ATFCTS, __ASSUME_SET_ROBUST_LIST, __ASSUME_UTIMENSAT, __ASSUME_FALLOCATE): Update per-arch conditions when each feature was introduced. --- libc/sysdeps/unix/sysv/linux/kernel-features.h.jj 2007-07-24 10:50:57.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/kernel-features.h 2007-08-13 17:11:29.000000000 +0200 @@ -428,29 +428,37 @@ # define __ASSUME_TMPFS_NAME 1 #endif -/* pselect was introduced just after 2.6.16-rc1. Due to the way the - kernel versions are advertised we can only rely on 2.6.17 to have - the code. */ -#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__ +/* pselect/ppoll were introduced just after 2.6.16-rc1. Due to the way + the kernel versions are advertised we can only rely on 2.6.17 to have + the code. On x86_64 and SH this appeared first in 2.6.19-rc1, + on ia64 in 2.6.22-rc1 and on alpha just after 2.6.22-rc1. */ +#if __LINUX_KERNEL_VERSION >= 0x020611 \ + && ((!defined __x86_64__ && !defined __sh__ && !defined __ia64__ \ + && !defined __alpha__) \ + || (__LINUX_KERNEL_VERSION >= 0x020613 \ + && (defined __x86_64__ || defined __sh__)) \ + || (__LINUX_KERNEL_VERSION >= 0x020616 && defined __ia64__) \ + || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__)) # define __ASSUME_PSELECT 1 -#endif - -/* ppoll was introduced just after 2.6.16-rc1. Due to the way the - kernel versions are advertised we can only rely on 2.6.17 to have - the code. */ -#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__ -# define __ASSUME_PPOLL 1 +# define __ASSUME_PPOLL 1 #endif /* The *at syscalls were introduced just after 2.6.16-rc1. Due to the way the kernel versions are advertised we can only rely on 2.6.17 to have - the code. */ -#if __LINUX_KERNEL_VERSION >= 0x020611 + the code. On PPC they were introduced in 2.6.17-rc1, on SH in 2.6.19-rc1 + and on Alpha just after 2.6.22-rc1. */ +#if __LINUX_KERNEL_VERSION >= 0x020611 \ + && ((!defined __sh__ && !defined __alpha__) \ + || (__LINUX_KERNEL_VERSION >= 0x020613 && defined __sh__) \ + || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__)) # define __ASSUME_ATFCTS 1 #endif /* Support for inter-process robust mutexes was added in 2.6.17. */ -#if __LINUX_KERNEL_VERSION >= 0x020611 +#if __LINUX_KERNEL_VERSION >= 0x020611 \ + && ((!defined __sh__ && !defined __alpha__) \ + || (__LINUX_KERNEL_VERSION >= 0x020613 && defined __sh__) \ + || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__)) # define __ASSUME_SET_ROBUST_LIST 1 #endif @@ -459,8 +467,11 @@ # define __ASSUME_FUTEX_LOCK_PI 1 #endif -/* Support for utimensat syscall was added in 2.6.22. */ -#if __LINUX_KERNEL_VERSION >= 0x020616 +/* Support for utimensat syscall was added in 2.6.22, on alpha and s390 + only after 2.6.22-rc1. */ +#if __LINUX_KERNEL_VERSION >= 0x020616 \ + && ((!defined __sh__ && !defined __alpha__) \ + || __LINUX_KERNEL_VERSION >= 0x020617) # define __ASSUME_UTIMENSAT 1 #endif @@ -469,7 +480,10 @@ # define __ASSUME_PRIVATE_FUTEX 1 #endif -/* Support for fallocate was added in 2.6.23. */ -#if __LINUX_KERNEL_VERSION >= 0x020617 +/* Support for fallocate was added in 2.6.23, on s390 + only after 2.6.23-rc1. */ +#if __LINUX_KERNEL_VERSION >= 0x020617 \ + && ((!defined __s390__ && !defined __alpha__) \ + || (__LINUX_KERNEL_VERSION >= 0x020618 && defined __s390__)) # define __ASSUME_FALLOCATE 1 #endif Jakub From jakub@redhat.com Mon Aug 13 15:28:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 13 Aug 2007 15:28:00 -0000 Subject: About stdlib/strto* change In-Reply-To: <20070813.235606.54189794.kkojima@rr.iij4u.or.jp> References: <20070813.235606.54189794.kkojima@rr.iij4u.or.jp> Message-ID: <20070813153353.GP4603@sunsite.mff.cuni.cz> On Mon, Aug 13, 2007 at 11:56:06PM +0900, Kaz Kojima wrote: > There is a build failure for SH during compiling stdlib/strtold_l.c: > > strtold_l.c:61: error: 'strtold_l' aliased to undefined symbol '__strtold_l' > > In Aug 6 Roland's change, libc_hidden_proto (__strtold_l) is added > to include/stdlib.h and weak_alias (__STRTOLD, STRTOLD) is added to > stdlib/strtold_l.c. It seems that libc_hedden_def is needed also > for __strtold_l just before the above weak_alias statement. Is it > right? x86 uses sysdeps/ieee754/ldbl-96/strtold_l.c which includes > stdlib/strtod_l.c instead of stdlib/strtold_l.c and the corresponding > libc_hedden_def was added to stdlib/strtod_l.c at that time. > The attached patch works for me, though I suspect that I've missed > something. I believe you should match what has been added to strtod_l.c, i.e.: { return INTERNAL (__STRTOD) (nptr, endptr, 0, loc); } +#if defined _LIBC +libc_hidden_def (__STRTOLD) +libc_hidden_ver (__STRTOLD, STRTOLD) +#endif weak_alias (__STRTOLD, STRTOLD) otherwise calls to strtold_l from within libc.so will go through PLT. stdlib/strtold_l.c is only used on sizeof (double) == sizeof (long double) arches, which I'm afraid I don't have access to any. Jakub From kkojima@rr.iij4u.or.jp Mon Aug 13 15:45:00 2007 From: kkojima@rr.iij4u.or.jp (Kaz Kojima) Date: Mon, 13 Aug 2007 15:45:00 -0000 Subject: About stdlib/strto* change In-Reply-To: <20070813153353.GP4603@sunsite.mff.cuni.cz> References: <20070813.235606.54189794.kkojima@rr.iij4u.or.jp> <20070813153353.GP4603@sunsite.mff.cuni.cz> Message-ID: <20070814.004445.35509960.kkojima@rr.iij4u.or.jp> Jakub Jelinek wrote: > I believe you should match what has been added to strtod_l.c, i.e.: > { > return INTERNAL (__STRTOD) (nptr, endptr, 0, loc); > } > +#if defined _LIBC > +libc_hidden_def (__STRTOLD) > +libc_hidden_ver (__STRTOLD, STRTOLD) > +#endif > weak_alias (__STRTOLD, STRTOLD) > > otherwise calls to strtold_l from within libc.so will go through > PLT. stdlib/strtold_l.c is only used on > sizeof (double) == sizeof (long double) arches, which I'm afraid > I don't have access to any. I've tried your patch and got In file included from wcstold_l.c:32: ../stdlib/strtold_l.c:60: error: 'wcstold_l' undeclared here (not in a function)../stdlib/strtold_l.c:60: warning: type defaults to 'int' in declaration of '__EI_wcstold_l' ../stdlib/strtold_l.c:60: warning: type defaults to 'int' in declaration of '__EI_wcstold_l' So perhaps, is the patch { return INTERNAL (__STRTOD) (nptr, endptr, 0, loc); } +#if defined _LIBC && !defined USE_WIDE_CHAR +libc_hidden_def (__STRTOLD) +libc_hidden_ver (__STRTOLD, STRTOLD) +#endif weak_alias (__STRTOLD, STRTOLD) ok? Regards, kaz From jakub@redhat.com Mon Aug 13 15:54:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 13 Aug 2007 15:54:00 -0000 Subject: About stdlib/strto* change In-Reply-To: <20070814.004445.35509960.kkojima@rr.iij4u.or.jp> References: <20070813.235606.54189794.kkojima@rr.iij4u.or.jp> <20070813153353.GP4603@sunsite.mff.cuni.cz> <20070814.004445.35509960.kkojima@rr.iij4u.or.jp> Message-ID: <20070813160013.GQ4603@sunsite.mff.cuni.cz> On Tue, Aug 14, 2007 at 12:44:45AM +0900, Kaz Kojima wrote: > Jakub Jelinek wrote: > > I believe you should match what has been added to strtod_l.c, i.e.: > > { > > return INTERNAL (__STRTOD) (nptr, endptr, 0, loc); > > } > > +#if defined _LIBC > > +libc_hidden_def (__STRTOLD) > > +libc_hidden_ver (__STRTOLD, STRTOLD) > > +#endif > > weak_alias (__STRTOLD, STRTOLD) > > > > otherwise calls to strtold_l from within libc.so will go through > > PLT. stdlib/strtold_l.c is only used on > > sizeof (double) == sizeof (long double) arches, which I'm afraid > > I don't have access to any. > > I've tried your patch and got > > In file included from wcstold_l.c:32: > ../stdlib/strtold_l.c:60: error: 'wcstold_l' undeclared here (not in a function)../stdlib/strtold_l.c:60: warning: type defaults to 'int' in declaration of '__EI_wcstold_l' > ../stdlib/strtold_l.c:60: warning: type defaults to 'int' in declaration of '__EI_wcstold_l' Either stdlib/strtold_l.c, or wcsmbs/wcstold_l.c then needs to #include Jakub From drepper@redhat.com Mon Aug 13 18:34:00 2007 From: drepper@redhat.com (Ulrich Drepper) Date: Mon, 13 Aug 2007 18:34:00 -0000 Subject: [PATCH] Some #include additions In-Reply-To: <20070813134002.GL4603@sunsite.mff.cuni.cz> References: <20070813134002.GL4603@sunsite.mff.cuni.cz> Message-ID: <46C0A416.9030000@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Jelinek wrote: > The following sources use __ASSUME_* macros but don't include > kernel-features.h. OK, but only because it allows to automate test for this in future. - -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFGwKQV2ijCOnn/RHQRAklFAKCXZ6rq/QAkFjiQbkF3ga0n7OYpSACggq5u vN/Hlzehb+3dw64N434jswg= =7ahj -----END PGP SIGNATURE----- From kkojima@rr.iij4u.or.jp Mon Aug 13 22:11:00 2007 From: kkojima@rr.iij4u.or.jp (Kaz Kojima) Date: Mon, 13 Aug 2007 22:11:00 -0000 Subject: About stdlib/strto* change In-Reply-To: <20070813160013.GQ4603@sunsite.mff.cuni.cz> References: <20070813153353.GP4603@sunsite.mff.cuni.cz> <20070814.004445.35509960.kkojima@rr.iij4u.or.jp> <20070813160013.GQ4603@sunsite.mff.cuni.cz> Message-ID: <20070814.071111.71554587.kkojima@rr.iij4u.or.jp> Jakub Jelinek wrote: >> In file included from wcstold_l.c:32: >> ../stdlib/strtold_l.c:60: error: 'wcstold_l' undeclared here (not in a function)../stdlib/strtold_l.c:60: warning: type defaults to 'int' in declaration of '__EI_wcstold_l' >> ../stdlib/strtold_l.c:60: warning: type defaults to 'int' in declaration of '__EI_wcstold_l' > > Either stdlib/strtold_l.c, or wcsmbs/wcstold_l.c then needs to > #include Ah, I see. With copying #if defined _LIBC || defined HAVE_WCHAR_H # include #endif lines from stdlib/strtod_l.c to strtold_l.c, the error went away. Thanks for your suggenstions! The attached patch is the revised one. Uli, does it look Ok? -- 2007-08-13 Kaz Kojima * stdlib/strtold_l.c: Include wchar.h if needed. Add libc_hidden_def. --- ORIG/libc/stdlib/strtold_l.c 2005-12-14 20:14:13.000000000 +0900 +++ LOCAL/libc/stdlib/strtold_l.c 2007-08-14 06:50:14.000000000 +0900 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2002, 2004, 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 @@ -20,6 +20,10 @@ #include #include +#if defined _LIBC || defined HAVE_WCHAR_H +# include +#endif + #ifdef USE_WIDE_CHAR # define STRING_TYPE wchar_t # define STRTOLD wcstold_l @@ -55,4 +59,8 @@ __STRTOLD (const STRING_TYPE *nptr, STRI { return INTERNAL (__STRTOD) (nptr, endptr, 0, loc); } +#if defined _LIBC +libc_hidden_def (__STRTOLD) +libc_hidden_ver (__STRTOLD, STRTOLD) +#endif weak_alias (__STRTOLD, STRTOLD) From drepper@redhat.com Tue Aug 14 14:37:00 2007 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 14 Aug 2007 14:37:00 -0000 Subject: About stdlib/strto* change In-Reply-To: <20070814.071111.71554587.kkojima@rr.iij4u.or.jp> References: <20070813153353.GP4603@sunsite.mff.cuni.cz> <20070814.004445.35509960.kkojima@rr.iij4u.or.jp> <20070813160013.GQ4603@sunsite.mff.cuni.cz> <20070814.071111.71554587.kkojima@rr.iij4u.or.jp> Message-ID: <46C1BE2C.3090708@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Applied. - -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFGwb4s2ijCOnn/RHQRArtHAJ9KWI4+X5oO/TirMK9JRL6FD2fEbgCdFn+8 /tOQCgNqxDKw5d5TYAEILQ0= =RrDT -----END PGP SIGNATURE----- From kkojima@rr.iij4u.or.jp Tue Aug 14 23:23:00 2007 From: kkojima@rr.iij4u.or.jp (Kaz Kojima) Date: Tue, 14 Aug 2007 23:23:00 -0000 Subject: [PATCH] SH nptl fixes Message-ID: <20070815.082324.123975822.kkojima@rr.iij4u.or.jp> Hi, Here is a patch for SH to sync with the recent Jakub's nptl changes. Regards, kaz -- 2007-08-14 Kaz Kojima * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S (__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private. * sysdeps/unix/sysv/linux/shpthread_cond_signal.S (__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. Use FUTEX_WAKE_OP. * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Include kernel-features.h and tcb-offsets.h. (__pthread_cond_wait, __condvar_w_cleanup): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Include tcb-offsets.h. (__pthread_cond_timedwait, __condvar_tw_cleanup): Pass LLL_PRIVATE to lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private. * sysdeps/unix/sysv/linux/sh/pthread_once.S: Use #ifdef __ASSUME_PRIVATE_FUTEX instead of #if __ASSUME_PRIVATE_FUTEX. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Likewise. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: Likewise. * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise. diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S 2007-08-04 09:57:13.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S 2007-08-14 08:04:24.000000000 +0900 @@ -93,13 +93,24 @@ __pthread_cond_broadcast: bt/s 9f add #cond_futex, r4 - /* XXX: The kernel so far doesn't support requeue to PI futex. */ + /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same + type of futex (private resp. shared). */ mov.l @(MUTEX_KIND,r9), r0 - tst #PI_BIT, r0 + tst #(PI_BIT|PS_BIT), r0 bf 9f /* Wake up all threads. */ - mov #FUTEX_CMP_REQUEUE, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_CMP_REQUEUE, r0 + or r0, r5 +#endif mov #1, r6 mov #-1, r7 shlr r7 /* r7 = 0x7fffffff */ @@ -156,7 +167,12 @@ __pthread_cond_broadcast: #if cond_lock != 0 add #cond_lock, r5 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 mov #LLL_SHARED, r6 +99: extu.b r6, r6 mov.l .Lwait5, r1 bsrf r1 @@ -171,7 +187,12 @@ __pthread_cond_broadcast: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lwake5, r1 bsrf r1 extu.b r5, r5 @@ -185,7 +206,12 @@ __pthread_cond_broadcast: #if cond_lock != 0 add #cond_lock, r4 #endif + mov #-1, r0 + cmp/eq r0, r9 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lwake6, r1 bsrf r1 extu.b r5, r5 @@ -194,7 +220,22 @@ __pthread_cond_broadcast: nop 9: - mov #FUTEX_WAKE, r5 + mov #-1, r0 + cmp/eq r0, r9 + bt/s 99f + mov #FUTEX_WAKE, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAKE, r0 + or r0, r5 +#endif +99: mov #-1, r6 shlr r6 /* r6 = 0x7fffffff */ mov #0, r7 @@ -205,6 +246,11 @@ __pthread_cond_broadcast: bra 10b nop +#ifndef __ASSUME_PRIVATE_FUTEX +.Lpfoff: + .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE +#endif + .align 2 .Lwait5: .long __lll_lock_wait-.Lwait5b diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S 2007-08-04 09:57:13.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S 2007-08-14 08:04:24.000000000 +0900 @@ -74,14 +74,63 @@ __pthread_cond_signal: /* Wake up one thread. */ mov r8, r4 add #cond_futex, r4 - mov #FUTEX_WAKE, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAKE_OP, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAKE_OP, r0 + or r0, r5 +#endif +99: mov #1, r6 mov #0, r7 + mov r8, r0 + add #cond_lock, r0 + mov.l .Lfutexop, r1 mov #SYS_futex, r3 extu.b r3, r3 trapa #0x14 SYSCALL_INST_PAD + /* For any kind of error, we try again with WAKE. + The general test also covers running on old kernels. */ + mov r0, r1 + mov #-12, r2 + shad r2, r1 + not r1, r1 + tst r1, r1 + bt 7f + +6: + mov #0, r0 + lds.l @r15+, pr + rts + mov.l @r15+, r8 + +#ifndef __ASSUME_PRIVATE_FUTEX +.Lpfoff: + .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE +#endif + .align 2 +.Lfutexop: + .long FUTEX_OP_CLEAR_WAKE_IF_GT_ONE + +7: + /* r5 should be either FUTEX_WAKE_OP or + FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */ + mov #(FUTEX_WAKE ^ FUTEX_WAKE_OP), r0 + xor r0, r5 + trapa #0x14 + SYSCALL_INST_PAD + 4: /* Unlock. */ #if cond_lock != 0 @@ -90,12 +139,26 @@ __pthread_cond_signal: DEC (@r8, r2) #endif tst r2, r2 - bf 5f -6: - mov #0, r0 - lds.l @r15+, pr - rts - mov.l @r15+, r8 + bt 6b + +5: + /* Unlock in loop requires wakeup. */ + mov r8, r4 +#if cond_lock != 0 + add #cond_lock, r4 +#endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 + mov #LLL_SHARED, r5 +99: + mov.l .Lwake4, r1 + bsrf r1 + extu.b r5, r5 +.Lwake4b: + bra 6b + nop 1: /* Initial locking failed. */ @@ -103,7 +166,12 @@ __pthread_cond_signal: #if cond_lock != 0 add #cond_lock, r5 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 mov #LLL_SHARED, r6 +99: extu.b r6, r6 mov.l .Lwait4, r1 bsrf r1 @@ -112,20 +180,6 @@ __pthread_cond_signal: bra 2b nop -5: - /* Unlock in loop requires wakeup. */ - mov r8, r4 -#if cond_lock != 0 - add #cond_lock, r4 -#endif - mov #LLL_SHARED, r5 - mov.l .Lwake4, r1 - bsrf r1 - extu.b r5, r5 -.Lwake4b: - bra 6b - nop - .align 2 .Lwait4: .long __lll_lock_wait-.Lwait4b diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S 2007-08-14 08:00:47.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S 2007-08-14 08:05:35.000000000 +0900 @@ -21,8 +21,9 @@ #include #include #include -#include "lowlevel-atomic.h" #include +#include +#include "lowlevel-atomic.h" .text @@ -230,7 +231,22 @@ __pthread_cond_timedwait: mov r15, r7 add #16, r7 - mov #FUTEX_WAIT, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAIT, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAIT, r0 + or r0, r5 +#endif +99: mov.l @(8,r15), r6 mov r8, r4 add #cond_futex, r4 @@ -339,7 +355,22 @@ __pthread_cond_timedwait: mov r8, r4 add #cond_nwaiters, r4 - mov #FUTEX_WAKE, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAKE, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAKE, r0 + or r0, r5 +#endif +99: mov #1, r6 mov #0, r7 mov #SYS_futex, r3 @@ -379,6 +410,10 @@ __pthread_cond_timedwait: rts mov.l @r15+, r8 +#ifndef __ASSUME_PRIVATE_FUTEX +.Lpfoff: + .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE +#endif .L1k: .word 1000 .align 2 @@ -399,7 +434,12 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r5 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 mov #LLL_SHARED, r6 +99: extu.b r6, r6 mov.l .Lwait2, r1 bsrf r1 @@ -414,7 +454,12 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lmwait2, r1 bsrf r1 extu.b r5, r5 @@ -428,7 +473,12 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r5 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 mov #LLL_SHARED, r6 +99: extu.b r6, r6 mov.l .Lwait3, r1 bsrf r1 @@ -443,7 +493,12 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lmwait3, r1 bsrf r1 extu.b r5, r5 @@ -466,7 +521,12 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lmwait4, r1 bsrf r1 extu.b r5, r5 @@ -510,7 +570,12 @@ __condvar_tw_cleanup: #if cond_lock != 0 add #cond_lock, r5 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 mov #LLL_SHARED, r6 +99: extu.b r6, r6 mov.l .Lwait5, r1 bsrf r1 @@ -605,7 +670,12 @@ __condvar_tw_cleanup: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lmwait5, r1 bsrf r1 extu.b r5, r5 diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S 2007-08-04 09:57:13.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S 2007-08-14 08:04:24.000000000 +0900 @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "lowlevel-atomic.h" .text @@ -135,7 +137,22 @@ __pthread_cond_wait: mov.l r0, @r15 mov #0, r7 - mov #FUTEX_WAIT, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAIT, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff0, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAIT, r0 + or r0, r5 +#endif +99: mov.l @(8,r15), r6 mov r8, r4 add #cond_futex, r4 @@ -213,7 +230,22 @@ __pthread_cond_wait: mov r8, r4 add #cond_nwaiters, r4 - mov #FUTEX_WAKE, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAKE, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff0, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAKE, r0 + or r0, r5 +#endif +99: mov #1, r6 mov #0, r7 mov #SYS_futex, r3 @@ -247,6 +279,10 @@ __pthread_cond_wait: rts mov.l @r15+, r8 +#ifndef __ASSUME_PRIVATE_FUTEX +.Lpfoff0: + .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE +#endif .align 2 .Lmunlock0: .long __pthread_mutex_unlock_usercnt-.Lmunlock0b @@ -263,7 +299,12 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r5 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 mov #LLL_SHARED, r6 +99: extu.b r6, r6 mov.l .Lwait0, r1 bsrf r1 @@ -277,7 +318,12 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lwake0, r1 bsrf r1 extu.b r5, r5 @@ -291,7 +337,12 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r5 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 mov #LLL_SHARED, r6 +99: extu.b r6, r6 mov.l .Lwait1, r1 bsrf r1 @@ -306,7 +357,12 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lwake1, r1 bsrf r1 extu.b r5, r5 @@ -329,7 +385,12 @@ __pthread_cond_wait: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lwake2, r1 bsrf r1 extu.b r5, r5 @@ -374,7 +435,12 @@ __condvar_w_cleanup: #if cond_lock != 0 add #cond_lock, r5 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 mov #LLL_SHARED, r6 +99: extu.b r6, r6 mov.l .Lwait3, r1 bsrf r1 @@ -447,7 +513,22 @@ __condvar_w_cleanup: mov r8, r4 add #cond_nwaiters, r4 - mov #FUTEX_WAKE, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAKE, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff1, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAKE, r0 + or r0, r5 +#endif +99: mov #1, r6 mov #0, r7 mov #SYS_futex, r3 @@ -469,7 +550,12 @@ __condvar_w_cleanup: #if cond_lock != 0 add #cond_lock, r4 #endif + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 mov #LLL_SHARED, r5 +99: mov.l .Lwake3, r1 bsrf r1 extu.b r5, r5 @@ -481,7 +567,22 @@ __condvar_w_cleanup: bf/s 5f mov r8, r4 add #cond_futex, r4 - mov #FUTEX_WAKE, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAKE, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff1, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAKE, r0 + or r0, r5 +#endif +99: mov #-1, r6 shlr r6 /* r6 = 0x7fffffff */ mov #0, r7 @@ -505,6 +606,10 @@ __condvar_w_cleanup: mov r11, r4 sleep +#ifndef __ASSUME_PRIVATE_FUTEX +.Lpfoff1: + .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE +#endif .align 2 .Lwait3: .long __lll_lock_wait-.Lwait3b diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S 2007-08-04 09:57:13.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S 2007-08-14 08:04:24.000000000 +0900 @@ -94,7 +94,7 @@ __pthread_once: bf 3f /* Different for generation -> run initializer. */ /* Somebody else got here first. Wait. */ -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r5 extu.b r5, r5 #else @@ -168,7 +168,7 @@ __pthread_once: INC (@r9, r2) /* Wake up all other threads. */ mov r9, r4 -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5 extu.b r5, r5 #else @@ -213,7 +213,7 @@ __pthread_once: mov #0, r7 mov.l r7, @r9 mov r9, r4 -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5 #else stc gbr, r1 @@ -239,7 +239,7 @@ __pthread_once: sleep cfi_endproc -#if !__ASSUME_PRIVATE_FUTEX +#ifndef __ASSUME_PRIVATE_FUTEX .Lpfoff: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE #endif diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S 2007-08-04 09:57:13.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S 2007-08-14 08:04:24.000000000 +0900 @@ -74,7 +74,7 @@ __pthread_rwlock_rdlock: tst r2, r2 bf 10f 11: -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX mov #PSHARED, r0 mov.b @(r0,r8), r5 mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0 @@ -142,7 +142,7 @@ __pthread_rwlock_rdlock: rts mov r3, r0 -#if !__ASSUME_PRIVATE_FUTEX +#ifndef __ASSUME_PRIVATE_FUTEX .Lpfoff: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE #endif diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S 2007-08-04 09:57:14.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S 2007-08-14 08:04:24.000000000 +0900 @@ -115,7 +115,7 @@ pthread_rwlock_timedrdlock: /* Futex call. */ mov r15, r7 -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX mov #PSHARED, r0 mov.b @(r0,r8), r5 mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0 @@ -193,7 +193,7 @@ pthread_rwlock_timedrdlock: rts mov r3, r0 -#if !__ASSUME_PRIVATE_FUTEX +#ifndef __ASSUME_PRIVATE_FUTEX .Lpfoff: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE #endif diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S 2007-08-04 09:57:14.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S 2007-08-14 08:04:24.000000000 +0900 @@ -111,7 +111,7 @@ pthread_rwlock_timedwrlock: /* Futex call. */ mov r15, r7 -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX mov #PSHARED, r0 mov.b @(r0,r8), r5 mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0 @@ -191,7 +191,7 @@ pthread_rwlock_timedwrlock: rts mov r3, r0 -#if !__ASSUME_PRIVATE_FUTEX +#ifndef __ASSUME_PRIVATE_FUTEX .Lpfoff: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE #endif diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S 2007-08-04 09:57:14.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S 2007-08-14 08:04:24.000000000 +0900 @@ -85,7 +85,7 @@ __pthread_rwlock_unlock: bf 7f 8: -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX mov #PSHARED, r0 mov.b @(r0,r8), r5 mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r0 @@ -177,7 +177,7 @@ __pthread_rwlock_unlock: bra 8b mov.l @r15+, r4 -#if !__ASSUME_PRIVATE_FUTEX +#ifndef __ASSUME_PRIVATE_FUTEX .Lpfoff: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE #endif diff -uprN ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S --- ORIG/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S 2007-08-04 09:57:14.000000000 +0900 +++ LOCAL/libc/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S 2007-08-14 08:04:24.000000000 +0900 @@ -72,7 +72,7 @@ __pthread_rwlock_wrlock: 11: mov r8, r4 add #WRITERS_WAKEUP, r4 -#if __ASSUME_PRIVATE_FUTEX +#ifdef __ASSUME_PRIVATE_FUTEX mov #PSHARED, r0 mov.b @(r0,r8), r5 mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0 @@ -174,7 +174,7 @@ __pthread_rwlock_wrlock: bra 7b mov #0, r3 -#if !__ASSUME_PRIVATE_FUTEX +#ifndef __ASSUME_PRIVATE_FUTEX .Lpfoff: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE #endif From drepper@redhat.com Wed Aug 15 06:41:00 2007 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 15 Aug 2007 06:41:00 -0000 Subject: [PATCH] SH nptl fixes In-Reply-To: <20070815.082324.123975822.kkojima@rr.iij4u.or.jp> References: <20070815.082324.123975822.kkojima@rr.iij4u.or.jp> Message-ID: <46C2A01C.2030103@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Applied. - -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) iD8DBQFGwqAc2ijCOnn/RHQRAhfeAJ4ofTmQPwjWTPtyU6VyFe+f89SgVwCgi+9a 9xmMYG5t77+HevIVlF0RiR4= =lf9c -----END PGP SIGNATURE----- From aj@suse.de Thu Aug 16 07:18:00 2007 From: aj@suse.de (Andreas Jaeger) Date: Thu, 16 Aug 2007 07:18:00 -0000 Subject: Add missing extern Message-ID: In our bugzilla we got a report that an extern is missing (for details: https://bugzilla.novell.com/show_bug.cgi?id=233835). This results on static linking with -Wl,-warn-common in lots of these warnings: /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/libc.a(strtod_l.o): warning: common of `_nl_category_name_idxs' overridden by definition /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/libc.a(setlocale.o): warning: defined here /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/libc.a(mbrtowc.o): warning: multiple common of `_nl_category_name_idxs' Ok to commit? Andreas 2007-08-16 Andreas Jaeger * locale/localeinfo.h: Make _nl_category_name_idxs extern. Reported by Peter Festner . Index: locale/localeinfo.h =================================================================== RCS file: /cvs/glibc/libc/locale/localeinfo.h,v retrieving revision 1.59 diff -u -p -r1.59 localeinfo.h --- locale/localeinfo.h 27 Oct 2006 23:11:43 -0000 1.59 +++ locale/localeinfo.h 16 Aug 2007 06:52:15 -0000 @@ -186,7 +186,7 @@ extern const union catnamestr_t }; char str[0]; } _nl_category_names attribute_hidden; -const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden; +extern const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden; extern const uint8_t _nl_category_name_sizes[__LC_LAST] attribute_hidden; /* Name of the standard locales. */ -- Andreas Jaeger, Director Platform / openSUSE, aj@suse.de SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG N?rnberg) Maxfeldstr. 5, 90409 N?rnberg, Germany GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 188 bytes Desc: not available URL: From jakub@redhat.com Thu Aug 16 20:13:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 16 Aug 2007 20:13:00 -0000 Subject: [PATCH] Fix checking of ld.so undefined symbols on sparc64 Message-ID: <20070816201927.GC2279@sunsite.mff.cuni.cz> Hi! The nm -u ld.so | cmp -s /dev/null - test fails on sparc64, because ld.so (and other shared libs) on sparc64 have STT_REGISTER SHN_UNDEF symbols which are supposed to be undefined per psABI and are not really any kind of errors, just notes about each library's use of global registers. Using readelf -s allows us to filter symbols which can be SHN_UNDEF (symbol 0 and STT_REGISTER). Ok? 2007-08-16 Jakub Jelinek * elf/Makefile ($(objpfx)ld.so): Use readelf -s and awk instead of nm -u to check for undefined symbols. --- libc/elf/Makefile.jj 2007-08-10 15:31:49.000000000 +0200 +++ libc/elf/Makefile 2007-08-16 22:08:21.000000000 +0200 @@ -307,7 +307,9 @@ $(objpfx)ld.so: $(objpfx)librtld.os $(ld $(filter-out $(map-file),$^) $(load-map-file) \ -Wl,-soname=$(rtld-installed-name) -T $@.lds rm -f $@.lds - nm -u $@ | cmp -s /dev/null - + readelf -s $@ \ + | awk '($7 ~ /^UND(|EF)$/ && $1 != "0:" && $4 != "REGISTER") { print }' \ + | cmp -s /dev/null - # interp.c exists just to get this string into the libraries. CFLAGS-interp.c = -D'RUNTIME_LINKER="$(slibdir)/$(rtld-installed-name)"' \ Jakub From roland@redhat.com Thu Aug 16 20:23:00 2007 From: roland@redhat.com (Roland McGrath) Date: Thu, 16 Aug 2007 20:23:00 -0000 Subject: [PATCH] Fix checking of ld.so undefined symbols on sparc64 In-Reply-To: Jakub Jelinek's message of Thursday, 16 August 2007 22:19:28 +0200 <20070816201927.GC2279@sunsite.mff.cuni.cz> Message-ID: <20070816202303.9AEB04D0461@magilla.localdomain> Might as well just use { print; exit 2 } in the awk. From jakub@redhat.com Thu Aug 16 20:28:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 16 Aug 2007 20:28:00 -0000 Subject: [PATCH] Fix checking of ld.so undefined symbols on sparc64 In-Reply-To: <20070816202303.9AEB04D0461@magilla.localdomain> References: <20070816201927.GC2279@sunsite.mff.cuni.cz> <20070816202303.9AEB04D0461@magilla.localdomain> Message-ID: <20070816203351.GD2279@sunsite.mff.cuni.cz> On Thu, Aug 16, 2007 at 01:23:03PM -0700, Roland McGrath wrote: > Might as well just use { print; exit 2 } in the awk. Well, that would print just one line, we want to see all undefined symbols, don't we? But awk '($7 ~ /^UND(|EF)$/ && $1 != "0:" && $4 != "REGISTER") { print; p=1 } END { exit p != 0 }' could work... Jakub From roland@redhat.com Thu Aug 16 20:53:00 2007 From: roland@redhat.com (Roland McGrath) Date: Thu, 16 Aug 2007 20:53:00 -0000 Subject: Add missing extern In-Reply-To: Andreas Jaeger's message of Thursday, 16 August 2007 09:18:37 +0200 Message-ID: <20070816205308.55EC34D0461@magilla.localdomain> > Ok to commit? Yes. Thanks, Roland From roland@redhat.com Thu Aug 16 21:17:00 2007 From: roland@redhat.com (Roland McGrath) Date: Thu, 16 Aug 2007 21:17:00 -0000 Subject: [PATCH] Fix checking of ld.so undefined symbols on sparc64 In-Reply-To: Jakub Jelinek's message of Thursday, 16 August 2007 22:33:51 +0200 <20070816203351.GD2279@sunsite.mff.cuni.cz> Message-ID: <20070816211648.8405F4D0461@magilla.localdomain> > On Thu, Aug 16, 2007 at 01:23:03PM -0700, Roland McGrath wrote: > > Might as well just use { print; exit 2 } in the awk. > > Well, that would print just one line, we want to see all undefined > symbols, don't we? > But > awk '($7 ~ /^UND(|EF)$/ && $1 != "0:" && $4 != "REGISTER") { print; p=1 } END { exit p != 0 }' > could work... Sure. I just meant no need for the cmp when using awk. From jakub@redhat.com Sun Aug 26 11:05:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Sun, 26 Aug 2007 11:05:00 -0000 Subject: [PATCH] Fix i?86 posix_fallocate Message-ID: <20070826111152.GG2279@sunsite.mff.cuni.cz> Hi! Without EXTRA fallocate64.o* wasn't compiled nor linked in and so when __NR_fallocate was defined, i?86 glibc build failed. With EXTRA on the other side the build failed when __NR_fallocate was not defined. This patch should hopefully cure it, in a similar way how we handle pselect6 (though, pselect6 uses hand written assembly, while for fallocate we can IMHO use the PSEUDO_* macros just fine). 2007-08-26 Jakub Jelinek * sysdeps/unix/sysv/linux/i386/Makefile (sysdep_routines): Add call_fallocate in misc subdir. * sysdeps/unix/sysv/linux/i386/call_fallocate.S: New file. * sysdeps/unix/sysv/linux/i386/syscalls.list (fallocate64): Remove. * sysdeps/unix/sysv/linux/i386/posix_fallocate.c: Use __call_fallocate instead of __fallocate64. * sysdeps/unix/sysv/linux/i386/posix_fallocate64.c: Use __call_fallocate instead of __fallocate64. --- libc/sysdeps/unix/sysv/linux/i386/Makefile.jj 2006-01-21 09:14:17.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/i386/Makefile 2007-08-26 00:01:52.000000000 +0200 @@ -1,5 +1,5 @@ ifeq ($(subdir),misc) -sysdep_routines += ioperm iopl vm86 call_pselect6 +sysdep_routines += ioperm iopl vm86 call_pselect6 call_fallocate sysdep_headers += sys/elf.h sys/perm.h sys/reg.h sys/vm86.h sys/debugreg.h sys/io.h endif --- libc/sysdeps/unix/sysv/linux/i386/call_fallocate.S.jj 2007-08-25 23:59:07.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/call_fallocate.S 2007-08-26 00:00:29.000000000 +0200 @@ -0,0 +1,7 @@ +#include + +#ifdef __NR_fallocate +PSEUDO_ERRVAL (__call_fallocate, fallocate, 6) + ret_ERRVAL +PSEUDO_END_ERRVAL(__call_fallocate) +#endif --- libc/sysdeps/unix/sysv/linux/i386/syscalls.list.jj 2007-08-25 23:57:09.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/syscalls.list 2007-08-25 23:57:19.000000000 +0200 @@ -6,4 +6,3 @@ vm86 - vm86 i:ip __vm86 vm86@@GLIBC_2 oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0 waitpid - waitpid Ci:ipi __waitpid waitpid __libc_waitpid -fallocate64 - fallocate Vi:iiiiii __fallocate64 --- libc/sysdeps/unix/sysv/linux/i386/posix_fallocate64.c.jj 2007-08-01 17:50:38.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/posix_fallocate64.c 2007-08-26 00:01:12.000000000 +0200 @@ -30,7 +30,7 @@ extern int __posix_fallocate64_l64 (int extern int __have_fallocate attribute_hidden; #endif -extern int __fallocate64 (int fd, int mode, __off64_t offset, __off64_t len) +extern int __call_fallocate (int fd, int mode, __off64_t offset, __off64_t len) attribute_hidden; /* Reserve storage for the data of the file associated with FD. */ @@ -42,7 +42,7 @@ __posix_fallocate64_l64 (int fd, __off64 if (__builtin_expect (__have_fallocate >= 0, 1)) # endif { - int res = __fallocate64 (fd, 0, offset, len); + int res = __call_fallocate (fd, 0, offset, len); if (! res) return 0; --- libc/sysdeps/unix/sysv/linux/i386/posix_fallocate.c.jj 2007-08-01 17:50:52.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/posix_fallocate.c 2007-08-26 00:00:57.000000000 +0200 @@ -28,7 +28,7 @@ int __have_fallocate attribute_hidden; #endif -extern int __fallocate64 (int fd, int mode, __off64_t offset, __off64_t len) +extern int __call_fallocate (int fd, int mode, __off64_t offset, __off64_t len) attribute_hidden; /* Reserve storage for the data of the file associated with FD. */ @@ -40,7 +40,7 @@ posix_fallocate (int fd, __off_t offset, if (__builtin_expect (__have_fallocate >= 0, 1)) # endif { - int res = __fallocate64 (fd, 0, offset, len); + int res = __call_fallocate (fd, 0, offset, len); if (! res) return 0; Jakub From jakub@redhat.com Mon Aug 27 12:47:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 27 Aug 2007 12:47:00 -0000 Subject: [PATCH] Fix personality on x86_64 and ppc Message-ID: <20070827125429.GH2279@sunsite.mff.cuni.cz> Hi! With the addition of sysdeps/unix/sysv/linux/{x86_64,powerpc}/init-first.c the personality syscall is no longer exported on those architectures. Fixed thusly, not sure why init-first has been mentioned there at all, when it doesn't even call that syscall. 2007-08-27 Jakub Jelinek * sysdeps/unix/sysv/linux/syscalls.list (personality): Change caller to EXTRA. --- libc/sysdeps/unix/sysv/linux/syscalls.list.jj 2007-05-21 23:33:57.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/syscalls.list 2007-08-27 14:36:06.000000000 +0200 @@ -43,7 +43,7 @@ munlockall - munlockall i: munlockall nanosleep - nanosleep Ci:pp __libc_nanosleep __nanosleep nanosleep nfsservctl EXTRA nfsservctl i:ipp nfsservctl pause - pause Ci: __libc_pause pause -personality init-first personality i:i __personality personality +personality EXTRA personality i:i __personality personality pipe - pipe i:f __pipe pipe pivot_root EXTRA pivot_root i:ss pivot_root prctl EXTRA prctl i:iiiii __prctl prctl Jakub From roland@redhat.com Mon Aug 27 20:12:00 2007 From: roland@redhat.com (Roland McGrath) Date: Mon, 27 Aug 2007 20:12:00 -0000 Subject: [PATCH] Fix personality on x86_64 and ppc In-Reply-To: Jakub Jelinek's message of Monday, 27 August 2007 14:54:29 +0200 <20070827125429.GH2279@sunsite.mff.cuni.cz> Message-ID: <20070827201220.142804D05BE@magilla.localdomain> > Fixed thusly, not sure why init-first has been mentioned there at all, > when it doesn't even call that syscall. Applied. I suspect that at the dawn of time init-first.c called it. From jakub@redhat.com Tue Aug 28 20:00:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 28 Aug 2007 20:00:00 -0000 Subject: [PATCH] Check fread and fread_unlocked buffer overflows with -D_FORTIFY_SOURCE{,=2} Message-ID: <20070828200726.GI2279@sunsite.mff.cuni.cz> Hi! fread/fread_unlocked checking: 2007-08-28 Jakub Jelinek * libio/bits/stdio2.h (__fread_chk, __fread_unlocked_chk): New prototypes. (__fread_alias, __fread_unlocked_alias): New aliases. (fread): New extern inline. (fread_unlocked): Likewise. Undef macro before definition of the inline function. * debug/Makefile (routines): Add fread_chk and fread_u_chk. (CFLAGS-fread_chk.c, CFLAGS-fread_u_chk.c): Add. * debug/Versions (libc): Export __fread_chk@@GLIBC_2.7 and __fread_unlocked_chk@@GLIBC_2.7. * debug/fread_chk.c: New file. * debug/fread_u_chk.c: New file. * debug/tst-chk1.c (do_test): Add fread and fread_unlocked tests. --- libc/libio/bits/stdio2.h.jj 2007-07-03 12:36:59.000000000 +0200 +++ libc/libio/bits/stdio2.h 2007-08-28 21:41:06.000000000 +0200 @@ -98,6 +98,27 @@ fgets (char *__restrict __s, int __n, FI return __fgets_alias (__s, __n, __stream); } +extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, + size_t __size, size_t __n, + FILE *__restrict __stream) __wur; +extern size_t __REDIRECT (__fread_alias, + (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream), + fread) __wur; + +__extern_always_inline __wur size_t +fread (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) +{ + if (__bos0 (__ptr) != (size_t) -1 + && (!__builtin_constant_p (__size) + || !__builtin_constant_p (__n) + || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)) + || __size * __n > __bos0 (__ptr))) + return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream); + return __fread_alias (__ptr, __size, __n, __stream); +} + #ifdef __USE_GNU extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size, int __n, FILE *__restrict __stream) __wur; @@ -114,3 +135,49 @@ fgets_unlocked (char *__restrict __s, in return __fgets_unlocked_alias (__s, __n, __stream); } #endif + +#ifdef __USE_MISC +# undef fread_unlocked +extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen, + size_t __size, size_t __n, + FILE *__restrict __stream) __wur; +extern size_t __REDIRECT (__fread_unlocked_alias, + (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream), + fread_unlocked) __wur; + +__extern_always_inline __wur size_t +fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) +{ + if (__bos0 (__ptr) != (size_t) -1 + && (!__builtin_constant_p (__size) + || !__builtin_constant_p (__n) + || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)) + || __size * __n > __bos0 (__ptr))) + return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n, __stream); + +# ifdef __USE_EXTERN_INLINES + if (__builtin_constant_p (__size) + && __builtin_constant_p (__n) + && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2)) + && __size * __n <= 8) + { + size_t __cnt = __size * __n; + char *__cptr = (char *) __ptr; + if (__cnt == 0) + return 0; + + for (; __cnt > 0; --__cnt) + { + int __c = _IO_getc_unlocked (__stream); + if (__c == EOF) + break; + *__cptr++ = __c; + } + return (__cptr - (char *) __ptr) / __size; + } +# endif + return __fread_unlocked_alias (__ptr, __size, __n, __stream); +} +#endif --- libc/debug/Versions.jj 2006-04-24 18:59:05.000000000 +0200 +++ libc/debug/Versions 2007-08-28 20:53:26.000000000 +0200 @@ -39,4 +39,7 @@ libc { GLIBC_2.5 { __readlinkat_chk; } + GLIBC_2.7 { + __fread_chk; __fread_unlocked_chk; + } } --- libc/debug/Makefile.jj 2007-08-27 14:17:17.000000000 +0200 +++ libc/debug/Makefile 2007-08-28 21:27:54.000000000 +0200 @@ -32,7 +32,7 @@ routines = backtrace backtracesyms back gets_chk chk_fail readonly-area fgets_chk fgets_u_chk \ read_chk pread_chk pread64_chk recv_chk recvfrom_chk \ readlink_chk readlinkat_chk getwd_chk getcwd_chk \ - realpath_chk ptsname_r_chk \ + realpath_chk ptsname_r_chk fread_chk fread_u_chk \ wctomb_chk wcscpy_chk wmemcpy_chk wmemmove_chk wmempcpy_chk \ wcpcpy_chk wcsncpy_chk wcscat_chk wcsncat_chk wmemset_chk \ wcpncpy_chk \ @@ -58,6 +58,8 @@ CFLAGS-vfprintf_chk.c = -D_IO_MTSAFE_IO CFLAGS-gets_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-fgets_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-fgets_u_chk.c = -D_IO_MTSAFE_IO $(exceptions) +CFLAGS-fread_chk.c = -D_IO_MTSAFE_IO $(exceptions) +CFLAGS-fread_u_chk.c = -D_IO_MTSAFE_IO $(exceptions) CFLAGS-swprintf_chk.c = -D_IO_MTSAFE_IO CFLAGS-vswprintf_chk.c = -D_IO_MTSAFE_IO CFLAGS-wprintf_chk.c = -D_IO_MTSAFE_IO $(exceptions) --- libc/debug/fread_chk.c.jj 2007-08-28 20:25:09.000000000 +0200 +++ libc/debug/fread_chk.c 2007-08-28 20:38:43.000000000 +0200 @@ -0,0 +1,56 @@ +/* Copyright (C) 1993, 1995, 1997, 1998, 1999, 2002, 2003, 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + 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 Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +size_t +__fread_chk (void *__restrict ptr, size_t ptrlen, + size_t size, size_t n, FILE *__restrict stream) +{ + size_t bytes_requested = size * n; + if (__builtin_expect ((n | size) + >= (((size_t) 1) << (8 * sizeof (size_t) / 2)), 0)) + { + if (size != 0 && bytes_requested / size != n) + __chk_fail (); + } + + if (__builtin_expect (bytes_requested > ptrlen, 0)) + __chk_fail (); + + CHECK_FILE (stream, 0); + if (bytes_requested == 0) + return 0; + + size_t bytes_read; + _IO_acquire_lock (stream); + bytes_read = INTUSE(_IO_sgetn) (stream, (char *) ptr, bytes_requested); + _IO_release_lock (stream); + return bytes_requested == bytes_read ? n : bytes_read / size; +} --- libc/debug/fread_u_chk.c.jj 2007-08-28 20:25:09.000000000 +0200 +++ libc/debug/fread_u_chk.c 2007-08-28 20:52:15.000000000 +0200 @@ -0,0 +1,54 @@ +/* Copyright (C) 1993, 1995, 1997, 1998, 1999, 2002, 2003, 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + 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 Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +size_t +__fread_unlocked_chk (void *__restrict ptr, size_t ptrlen, + size_t size, size_t n, FILE *__restrict stream) +{ + size_t bytes_requested = size * n; + if (__builtin_expect ((n | size) + >= (((size_t) 1) << (8 * sizeof (size_t) / 2)), 0)) + { + if (size != 0 && bytes_requested / size != n) + __chk_fail (); + } + + if (__builtin_expect (bytes_requested > ptrlen, 0)) + __chk_fail (); + + CHECK_FILE (stream, 0); + if (bytes_requested == 0) + return 0; + + size_t bytes_read + = INTUSE(_IO_sgetn) (stream, (char *) ptr, bytes_requested); + return bytes_requested == bytes_read ? n : bytes_read / size; +} --- libc/debug/tst-chk1.c.jj 2006-04-24 19:00:18.000000000 +0200 +++ libc/debug/tst-chk1.c 2007-08-28 21:26:27.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2004. @@ -746,6 +746,75 @@ do_test (void) CHK_FAIL_END #endif + rewind (stdin); + + if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf) + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); + if (fread (buf, sizeof (buf), 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + rewind (stdin); + + if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf) + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); + if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1) + FAIL (); + CHK_FAIL_END +#endif + + rewind (stdin); + + if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf) + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); + if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + rewind (stdin); + + if (fread_unlocked (buf, 1, 4, stdin) != 4 + || memcmp (buf, "abcdFGHI\na", 10)) + FAIL (); + if (fread_unlocked (buf, 4, 1, stdin) != 1 + || memcmp (buf, "efghFGHI\na", 10)) + FAIL (); + + rewind (stdin); + + if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf) + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); + if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START + if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1) + FAIL (); + CHK_FAIL_END +#endif + lseek (fileno (stdin), 0, SEEK_SET); if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 Jakub