From f2b09556f28624f7428cbf6184f4836dad4009bf Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Tue, 18 Jan 2005 09:57:35 +0000 Subject: libpthread/ 2005-01-12 Pietro Ferrari * include/pthread/pthread.h (pthread_spin_destroy): Replace extern inline with extern __inline. (pthread_spin_init): Likewise. (pthread_spin_lock): Likewise. (pthread_spin_trylock): Likewise. (pthread_spin_unlock): Likewise. * sysdeps/mach/bits/spin-lock.h (__pthread_spin_lock): Likewise. * sysdeps/i386/bits/spin-lock.h (__pthread_spin_lock): Likewise. * sysdeps/generic/bits/mutex.h (__pthread_mutex_trylock): Likewise. (pthread_mutex_lock): Likewise. (pthread_mutex_trylock): Likewise. * sysdeps/generic/bits/pthread.h (pthread_equal): Likewise. --- sysdeps/mach/bits/spin-lock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sysdeps/mach') diff --git a/sysdeps/mach/bits/spin-lock.h b/sysdeps/mach/bits/spin-lock.h index f295df7a..e137c244 100644 --- a/sysdeps/mach/bits/spin-lock.h +++ b/sysdeps/mach/bits/spin-lock.h @@ -70,10 +70,10 @@ __pthread_spin_trylock (__pthread_spinlock_t *__lock) return __spin_try_lock (__lock) ? 0 : __EBUSY; } -extern inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); +extern __inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); extern int _pthread_spin_lock (__pthread_spinlock_t *__lock); -extern inline int +extern __inline int __pthread_spin_lock (__pthread_spinlock_t *__lock) { if (__pthread_spin_trylock (__lock)) -- cgit v1.2.3 From d5bd96ef227dbb794326a8d707d04c9ffcdb3969 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Tue, 18 Jan 2005 10:08:52 +0000 Subject: libpthread/ 2005-01-18 Neal H. Walfield * sysdeps/mach/hurd/pt-sysdep.h (__pthread_stack_dealloc): Add __always_inline__ attribute. * sysdeps/l4/hurd/pt-sysdep.h (_pthread_self): Likewise. (__attribute__): Likewise. --- sysdeps/l4/hurd/pt-sysdep.h | 2 ++ sysdeps/mach/hurd/pt-sysdep.h | 1 + 2 files changed, 3 insertions(+) (limited to 'sysdeps/mach') diff --git a/sysdeps/l4/hurd/pt-sysdep.h b/sysdeps/l4/hurd/pt-sysdep.h index e37beefa..87175330 100644 --- a/sysdeps/l4/hurd/pt-sysdep.h +++ b/sysdeps/l4/hurd/pt-sysdep.h @@ -35,6 +35,7 @@ L4_Word_t my_errno; extern inline struct __pthread * +__attribute__((__always_inline__)) _pthread_self (void) { return (struct __pthread *) L4_MyUserDefinedHandle (); @@ -42,6 +43,7 @@ _pthread_self (void) extern inline void __pthread_stack_dealloc (void *stackaddr, size_t stacksize) +__attribute__((__always_inline__)) { /* XXX: can only implement this once we have a working memory manager. */ return; diff --git a/sysdeps/mach/hurd/pt-sysdep.h b/sysdeps/mach/hurd/pt-sysdep.h index 18de9c55..83bad963 100644 --- a/sysdeps/mach/hurd/pt-sysdep.h +++ b/sysdeps/mach/hurd/pt-sysdep.h @@ -53,6 +53,7 @@ }) extern inline void +__attribute__((__always_inline__)) __pthread_stack_dealloc (void *stackaddr, size_t stacksize) { __vm_deallocate (__mach_task_self (), (vm_offset_t) stackaddr, stacksize); -- cgit v1.2.3 From 925d7efa3ce2bae7a2e889a57e7337de4877ff75 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Tue, 8 Feb 2005 14:42:03 +0000 Subject: libpthread/ 2005-02-08 Neal H. Walfield * sysdeps/mach/pt-spin.c (__pthread_spin_lock): Make a weak alias to _pthread_spin_lock. * sysdeps/posix/pt-spin.c (__pthread_spin_lock): Likewise. --- sysdeps/mach/pt-spin.c | 3 ++- sysdeps/posix/pt-spin.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'sysdeps/mach') diff --git a/sysdeps/mach/pt-spin.c b/sysdeps/mach/pt-spin.c index 010faca8..d9a2a32a 100644 --- a/sysdeps/mach/pt-spin.c +++ b/sysdeps/mach/pt-spin.c @@ -1,5 +1,5 @@ /* Spin locks. Mach version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2004 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 @@ -33,3 +33,4 @@ _pthread_spin_lock (__pthread_spinlock_t *lock) } weak_alias (_pthread_spin_lock, pthread_spin_lock); +weak_alias (_pthread_spin_lock, __pthread_spin_lock); diff --git a/sysdeps/posix/pt-spin.c b/sysdeps/posix/pt-spin.c index cdc482c1..486030de 100644 --- a/sysdeps/posix/pt-spin.c +++ b/sysdeps/posix/pt-spin.c @@ -1,5 +1,5 @@ /* Spin locks. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2004 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 @@ -51,3 +51,4 @@ _pthread_spin_lock (__pthread_spinlock_t *lock) } weak_alias (_pthread_spin_lock, pthread_spin_lock); +weak_alias (_pthread_spin_lock, __pthread_spin_lock); -- cgit v1.2.3 From 317c73af1d3142947ba5f5d2f5251c4a34abda52 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Wed, 4 May 2005 16:04:06 +0000 Subject: libpthread/ 2005-05-04 Neal H. Walfield * Makefile (SRCS): Add pt-thread_dealloc.c. * sysdeps/mach/pt-thread-dealloc.c: New file. * pthread/pt-internal.h (__pthread_thread_dealloc): New declaration. (__pthread_thread_halt): Add parameter NEED_DEALLOC. Update callers. * sysdeps/mach/pt-thread-halt.c (__pthread_thread_halt): Respect new NEED_DEALLOC parameter. Move code which deallocates kernel resources from here ... * sysdeps/mach/pt-thread-dealloc.c (__pthread_thread_dealloc): ...to here. * pthread/pt-create.c (__pthread_create_internal): Call __pthread_thread_dealloc on failure. * pthread/pt-exit.c (pthread_exit): Call __pthread_thread_dealloc. * sysdeps/mach/pt-thread-alloc.c (create_wakeupmsg): Call __mach_port_destroy to deallocate the receive right. __mach_port_deallocate won't do it. * pthread/pt-detach.c (pthread_detach): Don't call __pthread_thread_halt a second time. * sysdeps/mach/hurd/pt-sysdep.c (_cthread_init_routine): Fix declaration. (init_routine): Update declaration and remove gratuitous cast. --- pthread/pt-create.c | 3 ++- pthread/pt-detach.c | 4 +--- pthread/pt-exit.c | 13 +++++++++---- pthread/pt-internal.h | 20 +++++++++++++++----- sysdeps/mach/hurd/pt-sysdep.c | 10 +++++----- sysdeps/mach/pt-thread-alloc.c | 9 +++++---- sysdeps/mach/pt-thread-dealloc.c | 41 ++++++++++++++++++++++++++++++++++++++++ sysdeps/mach/pt-thread-halt.c | 18 +++++++++++------- 8 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 sysdeps/mach/pt-thread-dealloc.c (limited to 'sysdeps/mach') diff --git a/pthread/pt-create.c b/pthread/pt-create.c index cf5b32d8..bad5d83f 100644 --- a/pthread/pt-create.c +++ b/pthread/pt-create.c @@ -192,7 +192,8 @@ __pthread_create_internal (struct __pthread **thread, failed_sigstate: __pthread_sigstate_destroy (pthread); failed_setup: - __pthread_thread_halt (pthread); + __pthread_thread_dealloc (pthread); + __pthread_thread_halt (pthread, 0); failed_thread_alloc: __pthread_stack_dealloc (pthread->stackaddr, pthread->stacksize); pthread->stack = 0; diff --git a/pthread/pt-detach.c b/pthread/pt-detach.c index c22f6a03..42a84080 100644 --- a/pthread/pt-detach.c +++ b/pthread/pt-detach.c @@ -1,5 +1,5 @@ /* Detach a thread. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2005 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 @@ -58,8 +58,6 @@ pthread_detach (pthread_t thread) __pthread_mutex_unlock (&pthread->state_lock); - __pthread_thread_halt (pthread); - assert (pthread->stack); __pthread_stack_dealloc (pthread->stackaddr, pthread->stacksize); pthread->stack = 0; diff --git a/pthread/pt-exit.c b/pthread/pt-exit.c index fb9e97c0..7484ffd1 100644 --- a/pthread/pt-exit.c +++ b/pthread/pt-exit.c @@ -1,5 +1,5 @@ /* Thread termination. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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 @@ -35,6 +35,7 @@ pthread_exit (void *status) struct __pthread *self = _pthread_self (); struct __pthread_cancelation_handler **handlers; int oldstate; + int need_dealloc; /* Run any cancelation handlers. According to POSIX, the cancellation cleanup handlers should be called with cancellation @@ -69,10 +70,13 @@ pthread_exit (void *status) if (self->cancel_state == PTHREAD_CANCEL_ENABLE && self->cancel_pending) status = PTHREAD_CANCELED; + __pthread_thread_dealloc (self); + switch (self->state) { default: - assert (! "This cannot happen!"); + assert (! "Consistency error: unexpected self->state"); + abort (); break; case PTHREAD_DETACHED: @@ -82,7 +86,7 @@ pthread_exit (void *status) deallocate our own stack. However, it will eventually be reused when this thread structure is recycled. */ __pthread_mutex_unlock (&self->state_lock); - __pthread_dealloc (self); + need_dealloc = 1; break; @@ -99,6 +103,7 @@ pthread_exit (void *status) waiting to join us. */ pthread_cond_broadcast (&self->state_cond); __pthread_mutex_unlock (&self->state_lock); + need_dealloc = 0; break; } @@ -108,7 +113,7 @@ pthread_exit (void *status) This means that before freeing any resources, such a thread should make sure that this thread is really halted. */ - __pthread_thread_halt (self); + __pthread_thread_halt (self, need_dealloc); /* NOTREACHED */ abort (); diff --git a/pthread/pt-internal.h b/pthread/pt-internal.h index 75631db0..e9086956 100644 --- a/pthread/pt-internal.h +++ b/pthread/pt-internal.h @@ -195,16 +195,26 @@ extern int __pthread_setup (struct __pthread *thread, void *(*start_routine)(void *), void *arg); -/* Allocate a kernel thread for THREAD; it must not be placed on the - run queue. */ +/* Allocate a kernel thread (and any miscellaneous system dependent + resources) for THREAD; it must not be placed on the run queue. */ extern int __pthread_thread_alloc (struct __pthread *thread); +/* Deallocate any kernel resources associated with THREAD except don't + halt the thread itself. On return, the thread will be marked as + dead and __pthread_halt will be called. */ +extern void __pthread_thread_dealloc (struct __pthread *thread); + /* Start THREAD making it eligible to run. */ extern int __pthread_thread_start (struct __pthread *thread); -/* Stop thread thread and deallocate any kernel resources associated - with THREAD. */ -extern void __pthread_thread_halt (struct __pthread *thread); +/* Stop the kernel thread associated with THREAD. If NEED_DEALLOC is + true, the function must call __pthread_dealloc on THREAD. + + NB: The thread executing this function may be the thread which is + being halted, thus the last action should be halting the thread + itself. */ +extern void __pthread_thread_halt (struct __pthread *thread, + int need_dealloc); /* Block THREAD. */ diff --git a/sysdeps/mach/hurd/pt-sysdep.c b/sysdeps/mach/hurd/pt-sysdep.c index b42fe255..5e070067 100644 --- a/sysdeps/mach/hurd/pt-sysdep.c +++ b/sysdeps/mach/hurd/pt-sysdep.c @@ -1,5 +1,5 @@ /* System dependent pthreads code. Hurd version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,16 +29,16 @@ #include /* Forward. */ -static int init_routine (void); +static void *init_routine (void); /* OK, the name of this variable isn't really appropriate, but I don't want to change it yet. */ -int (*_cthread_init_routine)(void) = &init_routine; +void *(*_cthread_init_routine)(void) = &init_routine; /* This function is called from the Hurd-specific startup code. It should return a new stack pointer for the main thread. The caller will switch to this new stack before doing anything serious. */ -static int +static void * init_routine (void) { struct __pthread *thread; @@ -68,5 +68,5 @@ init_routine (void) = (__pthread_default_attr.stacksize - __hurd_threadvar_max * sizeof (uintptr_t)); - return (int) thread->mcontext.sp; + return thread->mcontext.sp; } diff --git a/sysdeps/mach/pt-thread-alloc.c b/sysdeps/mach/pt-thread-alloc.c index a191c712..1acba98a 100644 --- a/sysdeps/mach/pt-thread-alloc.c +++ b/sysdeps/mach/pt-thread-alloc.c @@ -1,5 +1,5 @@ /* Start thread. Mach version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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 @@ -50,8 +50,8 @@ create_wakeupmsg (struct __pthread *thread) MACH_MSG_TYPE_MAKE_SEND); if (err) { - __mach_port_deallocate (__mach_task_self (), - thread->wakeupmsg.msgh_remote_port); + __mach_port_destroy (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port); return EAGAIN; } @@ -86,7 +86,8 @@ __pthread_thread_alloc (struct __pthread *thread) { assert (__pthread_total == 0); thread->kernel_thread = __mach_thread_self (); - /* We implicitly hold a reference. */ + /* We implicitly hold a reference drop the one that we just + acquired. */ __mach_port_deallocate (__mach_task_self (), thread->kernel_thread); } else diff --git a/sysdeps/mach/pt-thread-dealloc.c b/sysdeps/mach/pt-thread-dealloc.c new file mode 100644 index 00000000..55d8c4d5 --- /dev/null +++ b/sysdeps/mach/pt-thread-dealloc.c @@ -0,0 +1,41 @@ +/* Deallocate the kernel thread resources. Mach version. + Copyright (C) 2005 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 +#include + +#include + +/* Deallocate any kernel resources associated with THREAD except don't + halt the thread itself. On return, the thread will be marked as + dead and __pthread_halt will be called. */ +void +__pthread_thread_dealloc (struct __pthread *thread) +{ + /* Why no assert? Easy. When Mach kills a task, it starts by + invalidating the task port and then terminating the threads one + by one. But while it is terminating them, they are still + eligible to be scheduled. Imagine we have two threads, one calls + exit, one calls pthread_exit. The second one may run this after + the mask port can been destroyed thus gratuitously triggering the + assert. */ + __mach_port_destroy (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port); +} diff --git a/sysdeps/mach/pt-thread-halt.c b/sysdeps/mach/pt-thread-halt.c index 84e6ac8e..9f860247 100644 --- a/sysdeps/mach/pt-thread-halt.c +++ b/sysdeps/mach/pt-thread-halt.c @@ -1,5 +1,5 @@ /* Deallocate the kernel thread resources. Mach version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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,17 +23,21 @@ #include +/* Stop the kernel thread associated with THREAD. If NEED_DEALLOC is + true, the function must call __pthread_dealloc on THREAD. -/* Deallocate the kernel thread resources associated with THREAD. */ + NB: The thread executing this function may be the thread which is + being halted, thus the last action should be halting the thread + itself. */ void -__pthread_thread_halt (struct __pthread *thread) +__pthread_thread_halt (struct __pthread *thread, int need_dealloc) { error_t err; + thread_t tid = thread->kernel_thread; - err = __mach_port_deallocate (__mach_task_self (), - thread->wakeupmsg.msgh_remote_port); - assert_perror (err); + if (need_dealloc) + __pthread_dealloc (thread); - err = __thread_terminate (thread->kernel_thread); + err = __thread_terminate (tid); assert_perror (err); } -- cgit v1.2.3 From 1c31ded80a4e76294ba08b2da2117b0af8c5cdaa Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Thu, 12 May 2005 20:55:38 +0000 Subject: libpthread/ 2005-05-12 Neal H. Walfield * include/pthread/pthread.h (pthread_exit): Add noreturn attribute. * sysdeps/generic/bits/condition.h (__PTHREAD_COND_INITIALIZER): Don't create a compound literal. * sysdeps/generic/bits/mutex.h (__PTHREAD_MUTEX_INITIALIZER): Don't create a compound literal. (pthread_mutex_init): Don't assign to *__MUTEX directly. Initialize an intermediate local variable and then copy the result. * sysdeps/generic/bits/rwlock.h (__PTHREAD_RWLOCK_INITIALIZER): Don't create a compound literal. (pthread_rwlock_init): Don't assign to *__RWLOCK directly. Initialize an intermediate local variable and then copy the result. * sysdeps/i386/bits/spin-lock.h (__SPIN_LOCK_INITIALIZER): Don't create a compound literal. * pthread/pt-alloc.c (initialize_pthread): Cast PTHREAD_MUTEX_INITIALIZER and PTHREAD_COND_INITIALIZER to create a compound literal. * tests/test-1.c (main): Use pthread_mutex_init, not PTHREAD_MUTEX_INIT for mutex initialization * sysdeps/generic/pt-barrier-init.c (pthread_barrier_init): Remove assert. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-cond-init.c (pthread_cond_init): Include . Remove assert. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-mutex-init.c (_pthread_mutex_init): Cast PTHREAD_MUTEX_INITIALIZER to create a compound literal. * sysdeps/generic/pt-rwlock-init.c: Include . (_pthread_rwlock_init): Cast __PTHREAD_RWLOCK_INITIALIZER to create a compound literal. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-cond-timedwait.c (__pthread_cond_timedwait_internal): Check that ABSTIME->TV_NSEC is valid. Don't shadow ERR. Don't return before cleaning up. * sysdeps/generic/pt-mutex-timedlock.c (pthread_mutex_timedlock): Move after __pthread_mutex_timedlock_internal. Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/pt-rwlock-timedrdlock.c (pthread_rwlock_timedrdlock): Move after. __pthread_rwlock_timedrdlock_internal. (__pthread_rwlock_timedrdlock_internal): Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/pt-rwlock-timedwrlock.c (pthread_rwlock_timedwrlock): Move after __pthread_rwlock_timedwrlock_internal. (__pthread_rwlock_timedwrlock_internal): Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/sem-timedwait.c (__sem_timedwait_internal): Check that TIMEOUT->TV_NSEC is valid before enqueuing the thread. * sysdeps/generic/pt-rwlock-rdlock.c (__pthread_rwlock_timedrdlock_internal): Fix declaration. * sysdeps/generic/pt-mutex-trylock.c (__pthread_mutex_trylock): Don't return EDEADLK. POSIX does not allow it. * sysdeps/mach/pt-timedblock.c (__pthread_timedblock): Calculate the relative timeout without overflowing. * sysdeps/mach/hurd/i386/pt-setup.c (stack_setup): Cast THREAD. --- pthread/pt-alloc.c | 4 ++-- sysdeps/generic/bits/condition.h | 5 ++--- sysdeps/generic/bits/mutex.h | 10 +++++----- sysdeps/generic/bits/rwlock.h | 8 ++++---- sysdeps/generic/pt-barrier-init.c | 16 +++++++++++++--- sysdeps/generic/pt-cond-init.c | 17 ++++++++++++++--- sysdeps/generic/pt-cond-timedwait.c | 9 ++++----- sysdeps/generic/pt-mutex-init.c | 4 ++-- sysdeps/generic/pt-mutex-timedlock.c | 19 +++++++++++-------- sysdeps/generic/pt-mutex-trylock.c | 5 +++-- sysdeps/generic/pt-rwlock-init.c | 18 ++++++++++++++++-- sysdeps/generic/pt-rwlock-rdlock.c | 4 ++-- sysdeps/generic/pt-rwlock-timedrdlock.c | 19 +++++++++++-------- sysdeps/generic/pt-rwlock-timedwrlock.c | 19 +++++++++++-------- sysdeps/generic/sem-timedwait.c | 12 ++++++------ sysdeps/i386/bits/spin-lock.h | 4 ++-- sysdeps/mach/hurd/i386/pt-setup.c | 4 ++-- sysdeps/mach/pt-timedblock.c | 22 +++++++++++++++------- tests/test-1.c | 2 +- 19 files changed, 126 insertions(+), 75 deletions(-) (limited to 'sysdeps/mach') diff --git a/pthread/pt-alloc.c b/pthread/pt-alloc.c index e8d3c033..30dcede0 100644 --- a/pthread/pt-alloc.c +++ b/pthread/pt-alloc.c @@ -69,8 +69,8 @@ initialize_pthread (struct __pthread *new, int recycling) new->stack = 0; - new->state_lock = PTHREAD_MUTEX_INITIALIZER; - new->state_cond = PTHREAD_COND_INITIALIZER; + new->state_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; + new->state_cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER; new->cancelation_handlers = 0; diff --git a/sysdeps/generic/bits/condition.h b/sysdeps/generic/bits/condition.h index cb7e935c..f3b09be4 100644 --- a/sysdeps/generic/bits/condition.h +++ b/sysdeps/generic/bits/condition.h @@ -1,5 +1,5 @@ /* Condition type. Generic version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2005 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 @@ -34,7 +34,6 @@ struct __pthread_cond /* Initializer for a condition variable. */ #define __PTHREAD_COND_INITIALIZER \ - ((struct __pthread_cond) \ - { __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL }) + { __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL } #endif /* bits/condition.h */ diff --git a/sysdeps/generic/bits/mutex.h b/sysdeps/generic/bits/mutex.h index 9958b8d1..2e32d783 100644 --- a/sysdeps/generic/bits/mutex.h +++ b/sysdeps/generic/bits/mutex.h @@ -1,5 +1,5 @@ /* Mutex type. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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 @@ -52,9 +52,7 @@ struct __pthread_mutex /* Initializer for a mutex. N.B. this also happens to be compatible with the cthread mutex initializer. */ # define __PTHREAD_MUTEX_INITIALIZER \ - ((struct __pthread_mutex) \ - { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, \ - NULL, 0, 0 }) + { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 } # endif #endif /* Not __pthread_mutex_defined. */ @@ -74,13 +72,15 @@ _EXTERN_INLINE int pthread_mutex_init (struct __pthread_mutex *__mutex, const pthread_mutexattr_t *attr) { + struct __pthread_mutex initialized_mutex = __PTHREAD_MUTEX_INITIALIZER; + extern int _pthread_mutex_init (struct __pthread_mutex *, const pthread_mutexattr_t *); if (attr) return _pthread_mutex_init (__mutex, attr); - *__mutex = __PTHREAD_MUTEX_INITIALIZER; + *__mutex = initialized_mutex; return 0; } diff --git a/sysdeps/generic/bits/rwlock.h b/sysdeps/generic/bits/rwlock.h index d089b0c6..5793f65d 100644 --- a/sysdeps/generic/bits/rwlock.h +++ b/sysdeps/generic/bits/rwlock.h @@ -1,5 +1,5 @@ /* rwlock type. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 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 @@ -40,21 +40,21 @@ struct __pthread_rwlock /* Initializer for a rwlock. */ #define __PTHREAD_RWLOCK_INITIALIZER \ - ((struct __pthread_rwlock) \ - { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 }) + { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 } _EXTERN_INLINE int pthread_rwlock_init (struct __pthread_rwlock *__rwlock, const struct __pthread_rwlockattr *__attr) { + struct __pthread_rwlock initialized_rwlock = __PTHREAD_RWLOCK_INITIALIZER; extern int _pthread_rwlock_init (struct __pthread_rwlock *, const struct __pthread_rwlockattr *); if (__attr) return _pthread_rwlock_init (__rwlock, __attr); - *__rwlock = __PTHREAD_RWLOCK_INITIALIZER; + *__rwlock = initialized_rwlock; return 0; } diff --git a/sysdeps/generic/pt-barrier-init.c b/sysdeps/generic/pt-barrier-init.c index 57911d51..c42b3bb6 100644 --- a/sysdeps/generic/pt-barrier-init.c +++ b/sysdeps/generic/pt-barrier-init.c @@ -1,5 +1,5 @@ /* pthread_barrier_init. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 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 @@ -28,8 +28,6 @@ pthread_barrier_init (pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count) { - assert (attr->pshared == PTHREAD_PROCESS_PRIVATE); - if (count == 0) return EINVAL; @@ -39,5 +37,17 @@ pthread_barrier_init (pthread_barrier_t *barrier, barrier->pending = count; barrier->count = count; + if (! attr + || memcmp (attr, &__pthread_default_barrierattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + barrier->attr = malloc (sizeof *attr); + if (! barrier->attr) + return ENOMEM; + + *barrier->attr = *attr; return 0; } diff --git a/sysdeps/generic/pt-cond-init.c b/sysdeps/generic/pt-cond-init.c index 4afcc94e..b9e9fb7a 100644 --- a/sysdeps/generic/pt-cond-init.c +++ b/sysdeps/generic/pt-cond-init.c @@ -19,6 +19,7 @@ #include #include +#include #include @@ -26,9 +27,19 @@ int pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr) { - if (attr) - assert (attr->pshared == PTHREAD_PROCESS_PRIVATE); + *cond = (pthread_cond_t) __PTHREAD_COND_INITIALIZER; - *cond = __PTHREAD_COND_INITIALIZER; + if (! attr + || memcmp (attr, &__pthread_default_condattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + cond->__attr = malloc (sizeof *attr); + if (! cond->__attr) + return ENOMEM; + + *cond->__attr = *attr; return 0; } diff --git a/sysdeps/generic/pt-cond-timedwait.c b/sysdeps/generic/pt-cond-timedwait.c index 4abeb71c..c10bdb30 100644 --- a/sysdeps/generic/pt-cond-timedwait.c +++ b/sysdeps/generic/pt-cond-timedwait.c @@ -1,5 +1,5 @@ /* Wait on a condition. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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 @@ -58,6 +58,9 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, __pthread_mutex_lock (mutex); } + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + struct __pthread *self = _pthread_self (); /* Add ourselves to the list of waiters. */ @@ -74,8 +77,6 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, if (abstime) { - error_t err; - err = __pthread_timedblock (self, abstime); if (err) /* We timed out. We may need to disconnect ourself from the @@ -91,8 +92,6 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, if (self->prevp) __pthread_dequeue (self); __pthread_spin_unlock (&mutex->__lock); - - return err; } } else diff --git a/sysdeps/generic/pt-mutex-init.c b/sysdeps/generic/pt-mutex-init.c index 2902f6e4..23c9f0d9 100644 --- a/sysdeps/generic/pt-mutex-init.c +++ b/sysdeps/generic/pt-mutex-init.c @@ -1,5 +1,5 @@ /* Initialize a mutex. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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 @@ -28,7 +28,7 @@ int _pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - *mutex = __PTHREAD_MUTEX_INITIALIZER; + *mutex = (pthread_mutex_t) __PTHREAD_MUTEX_INITIALIZER; if (! attr || memcmp (attr, &__pthread_default_mutexattr, sizeof (*attr) == 0)) diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c index 3603986c..5e222bd3 100644 --- a/sysdeps/generic/pt-mutex-timedlock.c +++ b/sysdeps/generic/pt-mutex-timedlock.c @@ -1,5 +1,5 @@ /* Lock a mutex with a timeout. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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 @@ -24,13 +24,6 @@ #define LOSE do { * (int *) 0 = 0; } while (1) -int -pthread_mutex_timedlock (struct __pthread_mutex *mutex, - const struct timespec *abstime) -{ - return __pthread_mutex_timedlock_internal (mutex, abstime); -} - /* Try to lock MUTEX, block until *ABSTIME if it is already held. As a GNU extension, if TIMESPEC is NULL then wait forever. */ int @@ -96,6 +89,9 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, } } + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + /* Add ourselves to the queue. */ __pthread_enqueue (&mutex->__queue, self); __pthread_spin_unlock (&mutex->__lock); @@ -146,3 +142,10 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, return 0; } + +int +pthread_mutex_timedlock (struct __pthread_mutex *mutex, + const struct timespec *abstime) +{ + return __pthread_mutex_timedlock_internal (mutex, abstime); +} diff --git a/sysdeps/generic/pt-mutex-trylock.c b/sysdeps/generic/pt-mutex-trylock.c index 9457ddac..6fdea1ae 100644 --- a/sysdeps/generic/pt-mutex-trylock.c +++ b/sysdeps/generic/pt-mutex-trylock.c @@ -65,8 +65,9 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) break; case PTHREAD_MUTEX_ERRORCHECK: - if (mutex->owner == self) - err = EDEADLK; + /* We could check if MUTEX->OWNER is SELF, however, POSIX + does not permit pthread_mutex_trylock to return EDEADLK + instead of EBUSY, only pthread_mutex_lock. */ break; case PTHREAD_MUTEX_RECURSIVE: diff --git a/sysdeps/generic/pt-rwlock-init.c b/sysdeps/generic/pt-rwlock-init.c index 8fe87644..d6c8c1ae 100644 --- a/sysdeps/generic/pt-rwlock-init.c +++ b/sysdeps/generic/pt-rwlock-init.c @@ -1,5 +1,5 @@ /* Initialize a rwlock. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 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,13 +18,27 @@ Boston, MA 02111-1307, USA. */ #include +#include #include int _pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) { - *rwlock = __PTHREAD_RWLOCK_INITIALIZER; + *rwlock = (pthread_rwlock_t) __PTHREAD_RWLOCK_INITIALIZER; + + if (! attr + || memcmp (attr, &__pthread_default_rwlockattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + rwlock->__attr = malloc (sizeof *attr); + if (! rwlock->__attr) + return ENOMEM; + + *rwlock->__attr = *attr; return 0; } diff --git a/sysdeps/generic/pt-rwlock-rdlock.c b/sysdeps/generic/pt-rwlock-rdlock.c index 22c11204..480cf489 100644 --- a/sysdeps/generic/pt-rwlock-rdlock.c +++ b/sysdeps/generic/pt-rwlock-rdlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for reading. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 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,7 +21,7 @@ #include /* Implemented in pt-rwlock-timedrdlock.c. */ -extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_mutex *mutex, +extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, const struct timespec *abstime); /* Acquire RWLOCK for reading, block if we can't get it. */ diff --git a/sysdeps/generic/pt-rwlock-timedrdlock.c b/sysdeps/generic/pt-rwlock-timedrdlock.c index 85cb9468..ba610fa5 100644 --- a/sysdeps/generic/pt-rwlock-timedrdlock.c +++ b/sysdeps/generic/pt-rwlock-timedrdlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for reading. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 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,13 +22,6 @@ #include -int -pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock, - const struct timespec *abstime) -{ - return __pthread_rwlock_timedrdlock_internal (rwlock, abstime); -} - /* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if it is already held. As a GNU extension, if TIMESPEC is NULL then wait forever. */ @@ -66,6 +59,9 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, /* Better be blocked by a writer. */ assert (rwlock->readers == 0); + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + self = _pthread_self (); /* Add ourself to the queue. */ @@ -108,3 +104,10 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, return 0; } + +int +pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + return __pthread_rwlock_timedrdlock_internal (rwlock, abstime); +} diff --git a/sysdeps/generic/pt-rwlock-timedwrlock.c b/sysdeps/generic/pt-rwlock-timedwrlock.c index edf6413f..04eab51f 100644 --- a/sysdeps/generic/pt-rwlock-timedwrlock.c +++ b/sysdeps/generic/pt-rwlock-timedwrlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for writing. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 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,13 +22,6 @@ #include -int -pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock, - const struct timespec *abstime) -{ - return __pthread_rwlock_timedwrlock_internal (rwlock, abstime); -} - /* Acquire RWLOCK for writing blocking until *ABSTIME if we cannot get it. As a special GNU extension, if ABSTIME is NULL then the wait shall not time out. */ @@ -52,6 +45,9 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, /* The lock is busy. */ + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + self = _pthread_self (); /* Add ourselves to the queue. */ @@ -90,3 +86,10 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, return 0; } + +int +pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + return __pthread_rwlock_timedwrlock_internal (rwlock, abstime); +} diff --git a/sysdeps/generic/sem-timedwait.c b/sysdeps/generic/sem-timedwait.c index f3d280b7..0c521117 100644 --- a/sysdeps/generic/sem-timedwait.c +++ b/sysdeps/generic/sem-timedwait.c @@ -39,6 +39,12 @@ __sem_timedwait_internal (sem_t *restrict sem, return 0; } + if (timeout && (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)) + { + errno = EINVAL; + return -1; + } + /* Add ourselves to the queue. */ self = _pthread_self (); @@ -50,12 +56,6 @@ __sem_timedwait_internal (sem_t *restrict sem, { error_t err; - if (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000) - { - errno = EINVAL; - return -1; - } - err = __pthread_timedblock (self, timeout); if (err) /* We timed out. We may need to disconnect ourself from the diff --git a/sysdeps/i386/bits/spin-lock.h b/sysdeps/i386/bits/spin-lock.h index 3176a15f..e86bc13e 100644 --- a/sysdeps/i386/bits/spin-lock.h +++ b/sysdeps/i386/bits/spin-lock.h @@ -1,5 +1,5 @@ /* Machine-specific definitions for spin locks. i386 version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2005 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 @@ -32,7 +32,7 @@ __BEGIN_DECLS typedef __volatile int __pthread_spinlock_t; /* Initializer for a spin lock object. */ -# define __SPIN_LOCK_INITIALIZER ((__pthread_spinlock_t) 0) +# define __SPIN_LOCK_INITIALIZER (0) #if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES diff --git a/sysdeps/mach/hurd/i386/pt-setup.c b/sysdeps/mach/hurd/i386/pt-setup.c index 9a855847..32ace6ad 100644 --- a/sysdeps/mach/hurd/i386/pt-setup.c +++ b/sysdeps/mach/hurd/i386/pt-setup.c @@ -1,5 +1,5 @@ /* Setup thread stack. Hurd/i386 version. - Copyright (C) 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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 @@ -58,7 +58,7 @@ stack_setup (struct __pthread *thread, top -= __hurd_threadvar_max; /* Save the self pointer. */ - top[_HURD_THREADVAR_THREAD] = thread; + top[_HURD_THREADVAR_THREAD] = (void *) thread; if (start_routine) { diff --git a/sysdeps/mach/pt-timedblock.c b/sysdeps/mach/pt-timedblock.c index 6324ae76..ddb8baec 100644 --- a/sysdeps/mach/pt-timedblock.c +++ b/sysdeps/mach/pt-timedblock.c @@ -1,5 +1,5 @@ /* Block a thread with a timeout. Mach version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 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 @@ -34,7 +34,7 @@ __pthread_timedblock (struct __pthread *thread, { error_t err; mach_msg_header_t msg; - mach_msg_timeout_t ms; + mach_msg_timeout_t timeout; struct timeval now; /* We have an absolute time and now we have to convert it to a @@ -43,15 +43,23 @@ __pthread_timedblock (struct __pthread *thread, err = gettimeofday(&now, NULL); assert (! err); - ms = abstime->tv_sec * 1000 + (abstime->tv_nsec + 999999) / 1000000 - - now.tv_sec * 1000 - (now.tv_usec + 999) / 1000; - - if (ms <= 0) + if (now.tv_sec > abstime->tv_sec + || (now.tv_sec == abstime->tv_sec + && now.tv_usec > ((abstime->tv_nsec + 999) / 1000))) return ETIMEDOUT; + timeout = (abstime->tv_sec - now.tv_sec) * 1000; + + if (((abstime->tv_nsec + 999) / 1000) >= now.tv_usec) + timeout -= (((abstime->tv_nsec + 999) / 1000) - now.tv_usec + 999) / 1000; + else + /* Need to do a carry. */ + timeout -= 1000 + ((abstime->tv_nsec + 999999) / 1000000) + - (now.tv_usec + 999) / 1000; + err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof msg, thread->wakeupmsg.msgh_remote_port, - ms, MACH_PORT_NULL); + timeout, MACH_PORT_NULL); if (err == EMACH_RCV_TIMED_OUT) return ETIMEDOUT; diff --git a/tests/test-1.c b/tests/test-1.c index 86c7c97e..318fd6e9 100644 --- a/tests/test-1.c +++ b/tests/test-1.c @@ -27,7 +27,7 @@ main (int argc, char **argv) for (i = 0; i < THREADS; i ++) { - mutex[i] = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init (&mutex[i], 0); pthread_mutex_lock (&mutex[i]); err = pthread_create (&tid[i], 0, foo, &mutex[i]); if (err) -- cgit v1.2.3