From 2cddc873d21695166265d4c87c1939e5269a5108 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 23 Aug 2009 19:28:22 +0200 Subject: Fix assertion failure in pthread_mutex_trylock * sysdeps/generic/pt-mutex-trylock.c [!ALWAYS_TRACK_MUTEX_OWNER] (__pthread_mutex_trylock): Disable owner tracking. --- sysdeps/generic/pt-mutex-trylock.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sysdeps/generic/pt-mutex-trylock.c b/sysdeps/generic/pt-mutex-trylock.c index 5264dc7b..3c8cd03c 100644 --- a/sysdeps/generic/pt-mutex-trylock.c +++ b/sysdeps/generic/pt-mutex-trylock.c @@ -34,6 +34,7 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) if (__pthread_spin_trylock (&mutex->__held) == 0) /* Acquired the lock. */ { +#if defined(ALWAYS_TRACK_MUTEX_OWNER) #ifndef NDEBUG self = _pthread_self (); if (self) @@ -44,6 +45,7 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) assert (! mutex->owner); mutex->owner = _pthread_self (); } +#endif #endif if (mutex->attr) -- cgit v1.2.3 From 9c989b58f694567e214deed700708f3ba9901270 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 23 Aug 2009 19:38:06 +0200 Subject: Fix pthread_mutex_t static initializers Fix pthread_mutex_t static initializers by not leaving references to __pthread_recursive_mutexattr. * include/pthread/pthread.h.orig (PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP): New macro. * sysdeps/generic/pt-mutex-destroy.c (_pthread_mutex_destroy): Compare mutex->attr with __PTHREAD_ERRORCHECK_MUTEXATTR and __PTHREAD_RECURSIVE_MUTEXATTR instead of __pthread_recursive_mutexattr. * sysdeps/generic/pt-mutex-init.c (_pthread_mutex_init): Likewise. * sysdeps/generic/pt-mutex-timedlock.c (__pthread_mutex_timedlock_internal): Likewise. * sysdeps/generic/pt-mutex-transfer-np.c (__pthread_mutex_transfer_np): Likewise. * sysdeps/generic/pt-mutex-trylock.c (__pthread_mutex_trylock): Likewise. * sysdeps/generic/pt-mutex-unlock.c (__pthread_mutex_unlock): Likewise. * sysdeps/generic/pt-mutexattr.c (__pthread_errorcheck_mutexattr): New const. * sysdeps/generic/bits/mutex-attr.h (__pthread_errorcheck_mutexattr): Declare const. * sysdeps/generic/bits/mutex.h (__PTHREAD_ERRORCHECK_MUTEXATTR, __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER, __PTHREAD_RECURSIVE_MUTEXATTR): New macros. (__PTHREAD_RECURSIVE_MUTEX_INITIALIZER): Use __PTHREAD_RECURSIVE_MUTEXATTR macro instead of &__pthread_recursive_mutexattr. --- sysdeps/generic/bits/mutex-attr.h | 1 + sysdeps/generic/bits/mutex.h | 10 +++++++++- sysdeps/generic/pt-mutex-destroy.c | 3 ++- sysdeps/generic/pt-mutex-init.c | 13 +++++-------- sysdeps/generic/pt-mutex-timedlock.c | 22 ++++++++++++++-------- sysdeps/generic/pt-mutex-transfer-np.c | 11 +++++++++-- sysdeps/generic/pt-mutex-trylock.c | 14 ++++++++++---- sysdeps/generic/pt-mutex-unlock.c | 16 +++++++++++----- sysdeps/generic/pt-mutexattr.c | 8 ++++++++ 9 files changed, 69 insertions(+), 29 deletions(-) diff --git a/sysdeps/generic/bits/mutex-attr.h b/sysdeps/generic/bits/mutex-attr.h index 9161cdab..8514ebe8 100644 --- a/sysdeps/generic/bits/mutex-attr.h +++ b/sysdeps/generic/bits/mutex-attr.h @@ -35,6 +35,7 @@ struct __pthread_mutexattr }; /* Attributes for a recursive mutex. */ +extern const struct __pthread_mutexattr __pthread_errorcheck_mutexattr; extern const struct __pthread_mutexattr __pthread_recursive_mutexattr; #endif /* bits/mutex-attr.h */ diff --git a/sysdeps/generic/bits/mutex.h b/sysdeps/generic/bits/mutex.h index 86068cf5..c734c393 100644 --- a/sysdeps/generic/bits/mutex.h +++ b/sysdeps/generic/bits/mutex.h @@ -57,9 +57,17 @@ struct __pthread_mutex # define __PTHREAD_MUTEX_INITIALIZER \ { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 } +# define __PTHREAD_ERRORCHECK_MUTEXATTR ((struct __pthread_mutexattr *) ((unsigned long) __PTHREAD_MUTEX_ERRORCHECK + 1)) + +# define __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, \ + __PTHREAD_ERRORCHECK_MUTEXATTR, 0, 0, 0 } + +# define __PTHREAD_RECURSIVE_MUTEXATTR ((struct __pthread_mutexattr *) ((unsigned long) __PTHREAD_MUTEX_RECURSIVE + 1)) + # define __PTHREAD_RECURSIVE_MUTEX_INITIALIZER \ { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, \ - (struct __pthread_mutexattr *) &__pthread_recursive_mutexattr, 0, 0, 0 } + __PTHREAD_RECURSIVE_MUTEXATTR, 0, 0, 0 } # endif #endif /* Not __pthread_mutex_defined. */ diff --git a/sysdeps/generic/pt-mutex-destroy.c b/sysdeps/generic/pt-mutex-destroy.c index b0ca00f7..3bbc73fe 100644 --- a/sysdeps/generic/pt-mutex-destroy.c +++ b/sysdeps/generic/pt-mutex-destroy.c @@ -26,7 +26,8 @@ int _pthread_mutex_destroy (pthread_mutex_t *mutex) { - if (mutex->attr == &__pthread_recursive_mutexattr) + if (mutex->attr == __PTHREAD_ERRORCHECK_MUTEXATTR + || mutex->attr == __PTHREAD_RECURSIVE_MUTEXATTR) /* Static attributes. */ ; else diff --git a/sysdeps/generic/pt-mutex-init.c b/sysdeps/generic/pt-mutex-init.c index a818fe3a..2f960286 100644 --- a/sysdeps/generic/pt-mutex-init.c +++ b/sysdeps/generic/pt-mutex-init.c @@ -35,14 +35,11 @@ _pthread_mutex_init (pthread_mutex_t *mutex, /* The default attributes. */ return 0; - if (attr == &__pthread_recursive_mutexattr) - /* Non-default but known attributes. */ - { - mutex->attr = attr; - return 0; - } - - mutex->attr = malloc (sizeof *attr); + if (! mutex->attr + || mutex->attr == __PTHREAD_ERRORCHECK_MUTEXATTR + || mutex->attr == __PTHREAD_RECURSIVE_MUTEXATTR) + mutex->attr = malloc (sizeof *attr); + if (! mutex->attr) return ENOMEM; diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c index ee432192..883e50af 100644 --- a/sysdeps/generic/pt-mutex-timedlock.c +++ b/sysdeps/generic/pt-mutex-timedlock.c @@ -31,6 +31,12 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, const struct timespec *abstime) { struct __pthread *self; + const struct __pthread_mutexattr *attr = mutex->attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; __pthread_spin_lock (&mutex->__lock); if (__pthread_spin_trylock (&mutex->__held) == 0) @@ -50,8 +56,8 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, #endif #endif - if (mutex->attr) - switch (mutex->attr->mutex_type) + if (attr) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; @@ -75,7 +81,7 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, self = _pthread_self (); assert (self); - if (! mutex->attr || mutex->attr->mutex_type == PTHREAD_MUTEX_NORMAL) + if (! attr || attr->mutex_type == PTHREAD_MUTEX_NORMAL) { #if defined(ALWAYS_TRACK_MUTEX_OWNER) assert (mutex->owner != self); @@ -83,7 +89,7 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, } else { - switch (mutex->attr->mutex_type) + switch (attr->mutex_type) { case PTHREAD_MUTEX_ERRORCHECK: if (mutex->owner == self) @@ -108,7 +114,7 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, } #if !defined(ALWAYS_TRACK_MUTEX_OWNER) - if (mutex->attr && mutex->attr->mutex_type != PTHREAD_MUTEX_NORMAL) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) #endif assert (mutex->owner); @@ -147,14 +153,14 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, __pthread_block (self); #if !defined(ALWAYS_TRACK_MUTEX_OWNER) - if (mutex->attr && mutex->attr->mutex_type != PTHREAD_MUTEX_NORMAL) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) #endif { assert (mutex->owner == self); } - if (mutex->attr) - switch (mutex->attr->mutex_type) + if (attr) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; diff --git a/sysdeps/generic/pt-mutex-transfer-np.c b/sysdeps/generic/pt-mutex-transfer-np.c index 7796ac4f..967f1c7c 100644 --- a/sysdeps/generic/pt-mutex-transfer-np.c +++ b/sysdeps/generic/pt-mutex-transfer-np.c @@ -29,13 +29,20 @@ __pthread_mutex_transfer_np (struct __pthread_mutex *mutex, pthread_t tid) assert (mutex->owner == _pthread_self ()); struct __pthread *thread = __pthread_getid (tid); + const struct __pthread_mutexattr *attr = mutex->attr; + if (! thread) return ESRCH; if (thread == _pthread_self ()) return 0; - if (mutex->attr && mutex->attr->mutex_type == PTHREAD_MUTEX_ERRORCHECK) + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; + + if (attr && attr->mutex_type == PTHREAD_MUTEX_ERRORCHECK) { if (mutex->owner != _pthread_self ()) @@ -46,7 +53,7 @@ __pthread_mutex_transfer_np (struct __pthread_mutex *mutex, pthread_t tid) #ifndef NDEBUG # if !defined(ALWAYS_TRACK_MUTEX_OWNER) - if (mutex->attr && mutex->attr->mutex_type != PTHREAD_MUTEX_NORMAL) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) # endif { mutex->owner = thread; diff --git a/sysdeps/generic/pt-mutex-trylock.c b/sysdeps/generic/pt-mutex-trylock.c index 3c8cd03c..7a54cc9a 100644 --- a/sysdeps/generic/pt-mutex-trylock.c +++ b/sysdeps/generic/pt-mutex-trylock.c @@ -29,6 +29,12 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) { int err; struct __pthread *self; + const struct __pthread_mutexattr *attr = mutex->attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; __pthread_spin_lock (&mutex->__lock); if (__pthread_spin_trylock (&mutex->__held) == 0) @@ -48,8 +54,8 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) #endif #endif - if (mutex->attr) - switch (mutex->attr->mutex_type) + if (attr) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; @@ -70,10 +76,10 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) err = EBUSY; - if (mutex->attr) + if (attr) { self = _pthread_self (); - switch (mutex->attr->mutex_type) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; diff --git a/sysdeps/generic/pt-mutex-unlock.c b/sysdeps/generic/pt-mutex-unlock.c index 7645fd4c..09d70f8f 100644 --- a/sysdeps/generic/pt-mutex-unlock.c +++ b/sysdeps/generic/pt-mutex-unlock.c @@ -28,10 +28,16 @@ int __pthread_mutex_unlock (pthread_mutex_t *mutex) { struct __pthread *wakeup; - + const struct __pthread_mutexattr *attr = mutex->attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; + __pthread_spin_lock (&mutex->__lock); - if (! mutex->attr || mutex->attr->mutex_type == PTHREAD_MUTEX_NORMAL) + if (! attr || attr->mutex_type == PTHREAD_MUTEX_NORMAL) { #if defined(ALWAYS_TRACK_MUTEX_OWNER) # ifndef NDEBUG @@ -45,7 +51,7 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) #endif } else - switch (mutex->attr->mutex_type) + switch (attr->mutex_type) { case PTHREAD_MUTEX_ERRORCHECK: case PTHREAD_MUTEX_RECURSIVE: @@ -55,7 +61,7 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) return EPERM; } - if (mutex->attr->mutex_type == PTHREAD_MUTEX_RECURSIVE) + if (attr->mutex_type == PTHREAD_MUTEX_RECURSIVE) if (--mutex->locks > 0) { __pthread_spin_unlock (&mutex->__lock); @@ -82,7 +88,7 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) #ifndef NDEBUG # if !defined (ALWAYS_TRACK_MUTEX_OWNER) - if (mutex->attr && mutex->attr->mutex_type != PTHREAD_MUTEX_NORMAL) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) # endif { mutex->owner = wakeup; diff --git a/sysdeps/generic/pt-mutexattr.c b/sysdeps/generic/pt-mutexattr.c index d80a7d74..5ebde6ea 100644 --- a/sysdeps/generic/pt-mutexattr.c +++ b/sysdeps/generic/pt-mutexattr.c @@ -28,6 +28,14 @@ const struct __pthread_mutexattr __pthread_default_mutexattr = mutex_type: PTHREAD_MUTEX_DEFAULT }; +const struct __pthread_mutexattr __pthread_errorcheck_mutexattr = +{ + prioceiling: 0, + protocol: PTHREAD_PRIO_NONE, + pshared: PTHREAD_PROCESS_PRIVATE, + mutex_type: PTHREAD_MUTEX_ERRORCHECK +}; + const struct __pthread_mutexattr __pthread_recursive_mutexattr = { prioceiling: 0, -- cgit v1.2.3 From 25cbe85eafc3d4155a59f4690a3b581ead14d938 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 23 Aug 2009 19:47:05 +0200 Subject: Fix pthread_setcancelstate/type crash * pthread/pt-setcancelstate.c (pthread_setcancelstate): Check whether OLDSTATE is NULL before filling it. * pthread/pt-setcanceltype.c (pthread_setcanceltype): Likewise. --- pthread/pt-setcancelstate.c | 3 ++- pthread/pt-setcanceltype.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pthread/pt-setcancelstate.c b/pthread/pt-setcancelstate.c index ded58922..e2d81833 100644 --- a/pthread/pt-setcancelstate.c +++ b/pthread/pt-setcancelstate.c @@ -35,7 +35,8 @@ pthread_setcancelstate (int state, int *oldstate) break; } - *oldstate = p->cancel_state; + if (oldstate) + *oldstate = p->cancel_state; p->cancel_state = state; return 0; diff --git a/pthread/pt-setcanceltype.c b/pthread/pt-setcanceltype.c index 9511c991..3ce4259c 100644 --- a/pthread/pt-setcanceltype.c +++ b/pthread/pt-setcanceltype.c @@ -35,7 +35,8 @@ pthread_setcanceltype (int type, int *oldtype) break; } - *oldtype = p->cancel_type; + if (oldtype) + *oldtype = p->cancel_type; p->cancel_type = type; return 0; -- cgit v1.2.3 From 97998cd4d4a3be935bfa373c50c2624bbabd7d02 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 13 Oct 2009 20:15:08 +0200 Subject: Fix pthread_cleanup_push old-gcc-style initializer sysdeps/generic/bits/cancelation.h (__pthread_cleanup_push): For better portability to various compilation flags, use standard initializer for struct __pthread_cancelation_handler __handler instead of old-gcc-style. --- sysdeps/generic/bits/cancelation.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sysdeps/generic/bits/cancelation.h b/sysdeps/generic/bits/cancelation.h index f446d595..db9169a9 100644 --- a/sysdeps/generic/bits/cancelation.h +++ b/sysdeps/generic/bits/cancelation.h @@ -38,9 +38,9 @@ struct __pthread_cancelation_handler **__pthread_get_cleanup_stack (void); = __pthread_get_cleanup_stack (); \ struct __pthread_cancelation_handler __handler = \ { \ - handler: (rt), \ - arg: (rtarg), \ - next: *__handlers \ + (rt), \ + (rtarg), \ + *__handlers \ }; \ *__handlers = &__handler; -- cgit v1.2.3 From 75380300dc22bf3a8fbd89cf5a2358a9c29deaeb Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 18 Oct 2009 00:24:19 +0200 Subject: Fix pthread_kill(thread, 0) * sysdeps/hurd/pt-kill.c (pthread_kill): Return immediately after checks without calling _hurd_raise_signal if sig is 0. --- sysdeps/hurd/pt-kill.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sysdeps/hurd/pt-kill.c b/sysdeps/hurd/pt-kill.c index f970e065..d204e3f6 100644 --- a/sysdeps/hurd/pt-kill.c +++ b/sysdeps/hurd/pt-kill.c @@ -39,6 +39,9 @@ pthread_kill (pthread_t thread, int sig) ss = _hurd_thread_sigstate (pthread->kernel_thread); assert (ss); + if (!sig) + return 0; + detail.exc = 0; detail.code = sig; detail.error = 0; -- cgit v1.2.3 From 90dd2d73435a8e1bbcccf5ed99a91b2c438557f4 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Wed, 19 May 2010 08:32:16 +0200 Subject: Add pthread_yield function * pthread/pt-yield.c: New file. * Makefile (SRCS): Add pt-yield.c * Makefile.am (libpthread_a_SOURCES): Add pt-yield.c --- Makefile.am | 1 + pthread/pt-yield.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 pthread/pt-yield.c diff --git a/Makefile.am b/Makefile.am index e59c9460..e1c062c1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -133,6 +133,7 @@ libpthread_a_SOURCES = pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \ pt-kill.c \ pt-getcpuclockid.c \ pt-getschedparam.c pt-setschedparam.c pt-setschedprio.c \ + pt-yield.c \ sem-close.c sem-init.c sem-timedwait.c sem-wait.c \ sem-destroy.c sem-open.c sem-trywait.c sem-getvalue.c \ sem-post.c sem-unlink.c \ diff --git a/pthread/pt-yield.c b/pthread/pt-yield.c new file mode 100644 index 00000000..27848bb7 --- /dev/null +++ b/pthread/pt-yield.c @@ -0,0 +1,26 @@ +/* Yield the processor to another thread or process. + Copyright (C) 2010 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include + +int pthread_yield(void) +{ + return sched_yield (); +} -- cgit v1.2.3