diff options
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/ChangeLog | 23 | ||||
-rw-r--r-- | nptl/allocatestack.c | 24 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c | 22 | ||||
-rw-r--r-- | nptl/tst-align2.c | 10 | ||||
-rw-r--r-- | nptl/tst-cancel-wrappers.sh | 3 | ||||
-rw-r--r-- | nptl/tst-cancel4.c | 44 | ||||
-rw-r--r-- | nptl/tst-getpid1.c | 6 |
7 files changed, 120 insertions, 12 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 4976ba8741..6cbb87adeb 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,26 @@ +2007-05-02 Carlos O'Donell <carlos@systemhalted.org> + + [BZ #4455] + * tst-align2.c (do_test): Add _STACK_GROWS_UP case. + * tst-getpid1.c (do_test): Likewise. + + [BZ #4456] + * allocatestack.c (change_stack_perm): Add _STACK_GROWS_UP case. + (allocate_stack): Likewise. + +2007-05-07 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/unix/sysv/linux/lowlevelrobustlock.c + (__lll_robust_lock_wait): Fix race caused by reloading of futex value. + (__lll_robust_timedlock_wait): Likewise. + Reported by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>. + +2007-05-06 Mike Frysinger <vapier@gentoo.org> + + [BZ #4465] + * tst-cancel-wrappers.sh: Set C["fdatasync"] to 1. + * tst-cancel4.c (tf_fdatasync): New test. + 2007-04-27 Ulrich Drepper <drepper@redhat.com> [BZ #4392] diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index c05cd47dff..6b60642042 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -1,4 +1,4 @@ -/* 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 <drepper@redhat.com>, 2002. @@ -288,9 +288,14 @@ change_stack_perm (struct pthread *pd + (((((pd->stackblock_size - pd->guardsize) / 2) & pagemask) + pd->guardsize) & pagemask)); size_t len = pd->stackblock + pd->stackblock_size - stack; -#else +#elif _STACK_GROWS_DOWN void *stack = pd->stackblock + pd->guardsize; size_t len = pd->stackblock_size - pd->guardsize; +#elif _STACK_GROWS_UP + void *stack = pd->stackblock; + size_t len = (uintptr_t) pd - pd->guardsize - (uintptr_t) pd->stackblock; +#else +# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" #endif if (mprotect (stack, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) return errno; @@ -570,8 +575,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, { #ifdef NEED_SEPARATE_REGISTER_STACK char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1); -#else +#elif _STACK_GROWS_DOWN char *guard = mem; +# elif _STACK_GROWS_UP + char *guard = (char *) (((uintptr_t) pd - guardsize) & ~pagesize_m1); #endif if (mprotect (guard, guardsize, PROT_NONE) != 0) { @@ -618,10 +625,14 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, oldguard + pd->guardsize - guard - guardsize, prot) != 0) goto mprot_error; -#else +#elif _STACK_GROWS_DOWN if (mprotect ((char *) mem + guardsize, pd->guardsize - guardsize, prot) != 0) goto mprot_error; +#elif _STACK_GROWS_UP + if (mprotect ((char *) pd - pd->guardsize, + pd->guardsize - guardsize, prot) != 0) + goto mprot_error; #endif pd->guardsize = guardsize; @@ -661,8 +672,11 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, #ifdef NEED_SEPARATE_REGISTER_STACK *stack = pd->stackblock; *stacksize = stacktop - *stack; -#else +#elif _STACK_GROWS_DOWN *stack = stacktop; +#elif _STACK_GROWS_UP + *stack = pd->stackblock; + assert (*stack > 0); #endif return 0; diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c index 3e88ee1866..30ef991bd0 100644 --- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -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 Jakub Jelinek <jakub@redhat.com>, 2006. @@ -30,6 +30,10 @@ __lll_robust_lock_wait (int *futex) int oldval = *futex; int tid = THREAD_GETMEM (THREAD_SELF, tid); + /* If the futex changed meanwhile try locking again. */ + if (oldval == 0) + goto try; + do { if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0)) @@ -41,6 +45,9 @@ __lll_robust_lock_wait (int *futex) continue; lll_futex_wait (futex, newval); + + try: + ; } while ((oldval = atomic_compare_and_exchange_val_acq (futex, tid | FUTEX_WAITERS, @@ -57,6 +64,11 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime) return EINVAL; int tid = THREAD_GETMEM (THREAD_SELF, tid); + int oldval = *futex; + + /* If the futex changed meanwhile try locking again. */ + if (oldval == 0) + goto try; do { @@ -80,7 +92,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime) return ETIMEDOUT; /* Wait. */ - int oldval = *futex; if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0)) return oldval; @@ -90,8 +101,13 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime) continue; lll_futex_timed_wait (futex, newval, &rt); + + try: + ; } - while (atomic_compare_and_exchange_bool_acq (futex, tid | FUTEX_WAITERS, 0)); + while ((oldval = atomic_compare_and_exchange_val_acq (futex, + tid | FUTEX_WAITERS, + 0)) != 0); return 0; } diff --git a/nptl/tst-align2.c b/nptl/tst-align2.c index ec85f435b6..4685c201e4 100644 --- a/nptl/tst-align2.c +++ b/nptl/tst-align2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 Free Software Foundation, Inc. +/* Copyright (C) 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 @@ -53,8 +53,14 @@ do_test (void) char st[256 * 1024]; pid_t p = __clone2 (f, st, sizeof (st), 0, 0); #else - char st[128 * 1024]; + char st[128 * 1024] __attribute__ ((aligned)); +# if _STACK_GROWS_DOWN pid_t p = clone (f, st + sizeof (st), 0, 0); +# elif _STACK_GROWS_UP + pid_t p = clone (f, st, 0, 0); +# else +# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" +# endif #endif if (p == -1) { diff --git a/nptl/tst-cancel-wrappers.sh b/nptl/tst-cancel-wrappers.sh index d6f16d1ed2..61b9fb52de 100644 --- a/nptl/tst-cancel-wrappers.sh +++ b/nptl/tst-cancel-wrappers.sh @@ -1,6 +1,6 @@ #! /bin/sh # Test whether all cancelable functions are cancelable. -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. # This file is part of the GNU C Library. # Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. @@ -26,6 +26,7 @@ C["close"]=1 C["connect"]=1 C["creat"]=1 C["fcntl"]=1 +C["fdatasync"]=1 C["fsync"]=1 C["msgrcv"]=1 C["msgsnd"]=1 diff --git a/nptl/tst-cancel4.c b/nptl/tst-cancel4.c index 73cfa44614..45df6ce076 100644 --- a/nptl/tst-cancel4.c +++ b/nptl/tst-cancel4.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -1571,6 +1571,47 @@ tf_fsync (void *arg) static void * +tf_fdatasync (void *arg) +{ + if (arg == NULL) + // XXX If somebody can provide a portable test case in which fdatasync() + // blocks we can enable this test to run in both rounds. + abort (); + + tempfd = open ("Makefile", O_RDONLY); + if (tempfd == -1) + { + printf ("%s: cannot open Makefile\n", __FUNCTION__); + exit (1); + } + + int r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + r = pthread_barrier_wait (&b2); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__); + exit (1); + } + + pthread_cleanup_push (cl, NULL); + + fdatasync (tempfd); + + pthread_cleanup_pop (0); + + printf ("%s: fdatasync returned\n", __FUNCTION__); + + exit (1); +} + + +static void * tf_msync (void *arg) { if (arg == NULL) @@ -2078,6 +2119,7 @@ static struct ADD_TEST (pread, 2, 1), ADD_TEST (pwrite, 2, 1), ADD_TEST (fsync, 2, 1), + ADD_TEST (fdatasync, 2, 1), ADD_TEST (msync, 2, 1), ADD_TEST (sendto, 2, 1), ADD_TEST (sendmsg, 2, 1), diff --git a/nptl/tst-getpid1.c b/nptl/tst-getpid1.c index f9fd4fc0ca..e15cb61151 100644 --- a/nptl/tst-getpid1.c +++ b/nptl/tst-getpid1.c @@ -48,7 +48,13 @@ do_test (void) pid_t p = __clone2 (f, st, sizeof (st), TEST_CLONE_FLAGS, 0); #else char st[128 * 1024] __attribute__ ((aligned)); +# if _STACK_GROWS_DOWN pid_t p = clone (f, st + sizeof (st), TEST_CLONE_FLAGS, 0); +# elif _STACK_GROWS_UP + pid_t p = clone (f, st, TEST_CLONE_FLAGS, 0); +# else +# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" +# endif #endif if (p == -1) { |