From 0a37669aa5d98875e783df75681f035a905b7f31 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 16 Feb 2003 10:57:38 +0000 Subject: [PATCH] Update. * tst-rwlock6.c: More pthread_rwlock_timedwrlock and pthread_rwlock_timedrdlock tests. * tst-rwlock7.c: More pthread_rwlock_timedwrlock tests. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S: Check for invalid tv_nsec field. * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S: Likewise. * pthread_mutex_trylock.c (__pthread_mutex_trylock): Protect recursive mutex of overflow. * tst-attr1.c (do_test): Add test for pthread_mutexattr_setpshared. --- nptl/ChangeLog | 13 +++++ nptl/pthread_mutex_trylock.c | 6 ++- .../unix/sysv/linux/i386/bits/pthreadtypes.h | 3 +- .../i386/i486/pthread_rwlock_timedrdlock.S | 10 +++- .../i386/i486/pthread_rwlock_timedwrlock.S | 12 ++++- nptl/tst-attr1.c | 33 ++++++++++++ nptl/tst-clock1.c | 1 + nptl/tst-rwlock6.c | 50 ++++++++++++++++++- nptl/tst-rwlock7.c | 22 +++++++- nptl/tst-umask1.c | 2 +- 10 files changed, 142 insertions(+), 10 deletions(-) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 7e611221a4..72414b17ab 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,18 @@ 2003-02-16 Ulrich Drepper + * tst-rwlock6.c: More pthread_rwlock_timedwrlock and + pthread_rwlock_timedrdlock tests. + * tst-rwlock7.c: More pthread_rwlock_timedwrlock tests. + * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S: + Check for invalid tv_nsec field. + * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S: + Likewise. + + * pthread_mutex_trylock.c (__pthread_mutex_trylock): Protect + recursive mutex of overflow. + + * tst-attr1.c (do_test): Add test for pthread_mutexattr_setpshared. + * libc-cancellation.c (__libc_enable_asynccancel): Rwrite to avoid going into an endless loop. * Makefile (tests): Add tst-cancel9. diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c index aae506739f..394a9cba9b 100644 --- a/nptl/pthread_mutex_trylock.c +++ b/nptl/pthread_mutex_trylock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -36,6 +36,10 @@ __pthread_mutex_trylock (mutex) if (mutex->__data.__owner == pd) { /* Just bump the counter. */ + if (__builtin_expect (mutex->__data.__count + 1 == 0, 0)) + /* Overflow of the counter. */ + return EAGAIN; + ++mutex->__data.__count; return 0; } diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h index 97b94a3074..756ece29e0 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h @@ -1,6 +1,5 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2002. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S index 2e99ac669a..b275b8b922 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S @@ -27,6 +27,7 @@ #define FUTEX_WAKE 1 #define EAGAIN 11 +#define EINVAL 22 #define EDEADLK 35 #define ETIMEDOUT 110 @@ -71,7 +72,11 @@ pthread_rwlock_timedrdlock: cmpl $0, FLAGS(%ebp) je 5f -3: incl READERS_QUEUED(%ebp) + /* Check the value of the timeout parameter. */ +3: cmpl $1000000000, 4(%edi) + jae 19f + + incl READERS_QUEUED(%ebp) je 4f LOCK @@ -189,4 +194,7 @@ pthread_rwlock_timedrdlock: 18: movl $ETIMEDOUT, %ecx jmp 9b + +19: movl $EINVAL, %ecx + jmp 9b .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S index bf8f1d48db..ec8f4b9f6d 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S @@ -27,6 +27,7 @@ #define FUTEX_WAKE 1 #define EAGAIN 11 +#define EINVAL 22 #define EDEADLK 35 #define ETIMEDOUT 110 @@ -69,7 +70,11 @@ pthread_rwlock_timedwrlock: cmp $0, NR_READERS(%ebp) je 5f -3: incl WRITERS_QUEUED(%ebp) + /* Check the value of the timeout parameter. */ +3: cmpl $1000000000, 4(%edi) + jae 19f + + incl WRITERS_QUEUED(%ebp) je 4f LOCK @@ -156,7 +161,7 @@ pthread_rwlock_timedwrlock: 14: cmpl %gs:8, %eax jne 3b - movl $EDEADLK, %ecx +20: movl $EDEADLK, %ecx jmp 9b 6: movl %ebp, %eax @@ -181,4 +186,7 @@ pthread_rwlock_timedwrlock: 18: movl $ETIMEDOUT, %ecx jmp 9b + +19: movl $EINVAL, %ecx + jmp 9b .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock diff --git a/nptl/tst-attr1.c b/nptl/tst-attr1.c index bfa7075018..c5870beb5b 100644 --- a/nptl/tst-attr1.c +++ b/nptl/tst-attr1.c @@ -35,6 +35,14 @@ do_test (void) exit (1); } + pthread_mutexattr_t ma; + + if (pthread_mutexattr_init (&ma) != 0) + { + puts ("mutexattr_init failed"); + exit (1); + } + /* XXX Remove if default value is clear. */ pthread_attr_setinheritsched (&a, PTHREAD_INHERIT_SCHED); pthread_attr_setschedpolicy (&a, SCHED_OTHER); @@ -143,6 +151,31 @@ contentionscope changed to %d by invalid setscope call\n", s); exit (1); } } + + if (r != PTHREAD_PROCESS_PRIVATE && r != PTHREAD_PROCESS_SHARED) + { + int e = pthread_mutexattr_setpshared (&ma, r); + + if (e == 0) + { + printf ("mutexattr_setpshared with value %ld succeeded\n", r); + exit (1); + } + + int s; + if (pthread_mutexattr_getpshared (&ma, &s) != 0) + { + puts ("mutexattr_getpshared failed"); + exit (1); + } + + if (s != PTHREAD_PROCESS_PRIVATE) + { + printf ("\ +pshared changed to %d by invalid mutexattr_setpshared call\n", s); + exit (1); + } + } } return 0; diff --git a/nptl/tst-clock1.c b/nptl/tst-clock1.c index e0ab3024d3..fbb5fa907e 100644 --- a/nptl/tst-clock1.c +++ b/nptl/tst-clock1.c @@ -19,6 +19,7 @@ #include #include +#include #include #include diff --git a/nptl/tst-rwlock6.c b/nptl/tst-rwlock6.c index f0a96e8965..ea7f4ba634 100644 --- a/nptl/tst-rwlock6.c +++ b/nptl/tst-rwlock6.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -76,6 +76,24 @@ tf (void *arg) pthread_exit ((void *) 1l); } + (void) gettimeofday (&tv, NULL); + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ts.tv_sec += 10; + /* Note that the following operation makes ts invalid. */ + ts.tv_nsec += 1000000000; + + err = pthread_rwlock_timedrdlock (r, &ts); + if (err == 0) + { + puts ("2nd timedrdlock succeeded"); + pthread_exit ((void *) 1l); + } + if (err != EINVAL) + { + puts ("2nd timedrdlock did not return EINVAL"); + pthread_exit ((void *) 1l); + } + return NULL; } @@ -128,6 +146,36 @@ do_test (void) exit (1); } + (void) gettimeofday (&tv, NULL); + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ++ts.tv_sec; + int e = pthread_rwlock_timedrdlock (&r, &ts); + if (e == 0) + { + puts ("timedrdlock succeeded"); + exit (1); + } + if (e != EDEADLK) + { + puts ("timedrdlock did not return EDEADLK"); + exit (1); + } + + (void) gettimeofday (&tv, NULL); + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ++ts.tv_sec; + e = pthread_rwlock_timedwrlock (&r, &ts); + if (e == 0) + { + puts ("2nd timedwrlock succeeded"); + exit (1); + } + if (e != EDEADLK) + { + puts ("2nd timedwrlock did not return EDEADLK"); + exit (1); + } + pthread_t th; if (pthread_create (&th, NULL, tf, &r) != 0) { diff --git a/nptl/tst-rwlock7.c b/nptl/tst-rwlock7.c index 41e5af3ba8..4d7af6ca77 100644 --- a/nptl/tst-rwlock7.c +++ b/nptl/tst-rwlock7.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -76,6 +76,24 @@ tf (void *arg) pthread_exit ((void *) 1l); } + (void) gettimeofday (&tv, NULL); + TIMEVAL_TO_TIMESPEC (&tv, &ts); + ts.tv_sec += 10; + /* Note that the following operation makes ts invalid. */ + ts.tv_nsec += 1000000000; + + err = pthread_rwlock_timedwrlock (r, &ts); + if (err == 0) + { + puts ("2nd timedwrlock succeeded"); + pthread_exit ((void *) 1l); + } + if (err != EINVAL) + { + puts ("2nd timedwrlock did not return EINVAL"); + pthread_exit ((void *) 1l); + } + return NULL; } @@ -124,7 +142,7 @@ do_test (void) /* Get a read lock. */ if (pthread_rwlock_timedrdlock (&r, &ts) != 0) { - printf ("round %d: rwlock_wrlock failed\n", cnt); + printf ("round %d: rwlock_timedrdlock failed\n", cnt); exit (1); } diff --git a/nptl/tst-umask1.c b/nptl/tst-umask1.c index 22e3831b11..42d2e6810c 100644 --- a/nptl/tst-umask1.c +++ b/nptl/tst-umask1.c @@ -104,7 +104,7 @@ do_test (const char *fname) pthread_barrier_init (&bar, NULL, 2); pthread_t th; - if (pthread_create (&th, NULL, tf, fname) != 0) + if (pthread_create (&th, NULL, tf, (void *) fname) != 0) { puts ("cannot create thread"); exit (1);