diff options
-rw-r--r-- | sysdeps/generic/pt-cond-timedwait.c | 23 | ||||
-rw-r--r-- | sysdeps/generic/pt-mutex-timedlock.c | 2 | ||||
-rw-r--r-- | sysdeps/generic/pt-rwlock-timedrdlock.c | 2 | ||||
-rw-r--r-- | sysdeps/generic/pt-rwlock-timedwrlock.c | 2 | ||||
-rw-r--r-- | sysdeps/l4/pt-start.c | 2 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/pt-setup.c | 8 | ||||
-rw-r--r-- | sysdeps/mach/hurd/pt-docancel.c | 9 | ||||
-rw-r--r-- | sysdeps/mach/hurd/pt-sysdep.h | 7 | ||||
-rw-r--r-- | sysdeps/mach/pt-start.c | 106 | ||||
-rw-r--r-- | sysdeps/mach/pt-thread-alloc.c | 2 | ||||
-rw-r--r-- | sysdeps/mach/pt-thread-start.c | 6 | ||||
-rw-r--r-- | sysdeps/mach/pt-wakeup.c | 4 |
12 files changed, 54 insertions, 119 deletions
diff --git a/sysdeps/generic/pt-cond-timedwait.c b/sysdeps/generic/pt-cond-timedwait.c index 99761f3a..4abeb71c 100644 --- a/sysdeps/generic/pt-cond-timedwait.c +++ b/sysdeps/generic/pt-cond-timedwait.c @@ -73,7 +73,28 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &canceltype); if (abstime) - err = __pthread_timedblock (self, abstime); + { + error_t err; + + err = __pthread_timedblock (self, abstime); + if (err) + /* We timed out. We may need to disconnect ourself from the + waiter queue. + + FIXME: What do we do if we get a wakeup message before we + disconnect ourself? It may remain until the next time we + block. */ + { + assert (err == ETIMEDOUT); + + __pthread_spin_lock (&mutex->__lock); + if (self->prevp) + __pthread_dequeue (self); + __pthread_spin_unlock (&mutex->__lock); + + return err; + } + } else { err = 0; diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c index e8c9b466..3603986c 100644 --- a/sysdeps/generic/pt-mutex-timedlock.c +++ b/sysdeps/generic/pt-mutex-timedlock.c @@ -114,7 +114,7 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, disconnect ourself? It may remain until the next time we block. */ { - assert (err = ETIMEDOUT); + assert (err == ETIMEDOUT); __pthread_spin_lock (&mutex->__lock); if (self->prevp) diff --git a/sysdeps/generic/pt-rwlock-timedrdlock.c b/sysdeps/generic/pt-rwlock-timedrdlock.c index 3660339b..85cb9468 100644 --- a/sysdeps/generic/pt-rwlock-timedrdlock.c +++ b/sysdeps/generic/pt-rwlock-timedrdlock.c @@ -86,7 +86,7 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, disconnect ourself? It may remain until the next time we block. */ { - assert (err = ETIMEDOUT); + assert (err == ETIMEDOUT); __pthread_spin_lock (&rwlock->__lock); if (self->prevp) diff --git a/sysdeps/generic/pt-rwlock-timedwrlock.c b/sysdeps/generic/pt-rwlock-timedwrlock.c index 2f732175..edf6413f 100644 --- a/sysdeps/generic/pt-rwlock-timedwrlock.c +++ b/sysdeps/generic/pt-rwlock-timedwrlock.c @@ -72,7 +72,7 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, disconnect ourself? It may remain until the next time we block. */ { - assert (err = ETIMEDOUT); + assert (err == ETIMEDOUT); __pthread_spin_lock (&rwlock->__lock); if (self->prevp) diff --git a/sysdeps/l4/pt-start.c b/sysdeps/l4/pt-start.c index 5a506998..fb4e27be 100644 --- a/sysdeps/l4/pt-start.c +++ b/sysdeps/l4/pt-start.c @@ -69,7 +69,7 @@ __pthread_start (struct __pthread *thread) /* The main thread is already running: do nothing. */ { assert (__pthread_total == 1); - thread->threadid = __mach_thread_self (); + thread->threadid = L4_Myself (); } else { diff --git a/sysdeps/mach/hurd/i386/pt-setup.c b/sysdeps/mach/hurd/i386/pt-setup.c index a2495046..369a28e1 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 Free Software Foundation, Inc. + Copyright (C) 2000, 2002 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 <stdint.h> #include <assert.h> +#include <mach.h> #include <pt-internal.h> @@ -83,17 +84,20 @@ __pthread_setup (struct __pthread *thread, void *(*start_routine)(void *), void *arg) { error_t err; + mach_port_t ktid; thread->mcontext.pc = entry_point; thread->mcontext.sp = stack_setup (thread, start_routine, arg); - if (thread->kernel_thread != __mach_thread_self ()) + ktid = __mach_port_self (); + if (thread->kernel_thread != ktid) { err = __thread_set_pcsp (thread->kernel_thread, 1, thread->mcontext.pc, 1, thread->mcontext.sp); assert_perror (err); } + __mach_port_deallocate (__mach_task_self (), ktid); return 0; } diff --git a/sysdeps/mach/hurd/pt-docancel.c b/sysdeps/mach/hurd/pt-docancel.c index 58524ff0..bac62a71 100644 --- a/sysdeps/mach/hurd/pt-docancel.c +++ b/sysdeps/mach/hurd/pt-docancel.c @@ -30,10 +30,17 @@ call_exit (void) int __pthread_do_cancel (struct __pthread *p) { + mach_port_t ktid; + int me; + assert (p->cancel_pending = 1); assert (p->cancel_state == PTHREAD_CANCEL_ENABLE); - if (__mach_thread_self () == p->kernel_thread) + ktid = __mach_thread_self (); + me = p->kernel_thread == ktid; + __mach_port_deallocate (__mach_task_self (), ktid); + + if (me) call_exit (); else { diff --git a/sysdeps/mach/hurd/pt-sysdep.h b/sysdeps/mach/hurd/pt-sysdep.h index 3addef7c..18de9c55 100644 --- a/sysdeps/mach/hurd/pt-sysdep.h +++ b/sysdeps/mach/hurd/pt-sysdep.h @@ -1,5 +1,5 @@ /* Internal defenitions for pthreads library. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2002 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 @@ -45,7 +45,10 @@ __hurd_threadvar_location (_HURD_THREADVAR_THREAD); \ \ assert (thread); \ - assert (thread->kernel_thread == __mach_thread_self ()); \ + assert (({ mach_port_t ktid = __mach_thread_self (); \ + int ok = thread->kernel_thread == ktid; \ + __mach_port_deallocate (__mach_task_self (), ktid);\ + ok; })); \ thread; \ }) diff --git a/sysdeps/mach/pt-start.c b/sysdeps/mach/pt-start.c deleted file mode 100644 index 5e8cd5aa..00000000 --- a/sysdeps/mach/pt-start.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Start thread. Mach version. - Copyright (C) 2000,02 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 <assert.h> -#include <errno.h> -#include <string.h> - -#include <mach.h> - -#include <pt-internal.h> - -/* Prepare a wakeup message. */ -static error_t -create_wakeupmsg (struct __pthread *thread) -{ - kern_return_t err; - - /* Build wakeup message. */ - thread->wakeupmsg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); - thread->wakeupmsg.msgh_size = 0; - - err = __mach_port_allocate (__mach_task_self (), MACH_PORT_RIGHT_RECEIVE, - &thread->wakeupmsg.msgh_remote_port); - if (err) - return EAGAIN; - - thread->wakeupmsg.msgh_local_port = MACH_PORT_NULL; - thread->wakeupmsg.msgh_seqno = 0; - thread->wakeupmsg.msgh_id = 0; - - err = __mach_port_insert_right (__mach_task_self (), - thread->wakeupmsg.msgh_remote_port, - thread->wakeupmsg.msgh_remote_port, - MACH_MSG_TYPE_MAKE_SEND); - if (err) - { - __mach_port_deallocate (__mach_task_self (), - thread->wakeupmsg.msgh_remote_port); - return EAGAIN; - } - - return 0; -} - -/* Start THREAD. We allocate all system-specific resources, including - a kernel thread, set it up, and get it running. */ -int -__pthread_start (struct __pthread *thread) -{ - error_t err; - - err = create_wakeupmsg (thread); - if (err) - return err; - - /* If there are no pthreads in the system then the pthread library - is bootstrapping and the main thread must create initialize - itself. The thread itself is already running, it just has no - pthread context. We want to reuse what it already has (including - the kernel thread), however, we must determine which thread is - the main thread. - - We cannot test if __pthread_total is one as we later decrement it - before creating the signal thread. Currently, we check if - __pthread_num_threads--the number of allocated thread - structures--is one. __pthread_alloc has already been called in - __pthread_create_internal for us. This predicate could be - improved, however, it is sufficient for now. */ - if (__pthread_num_threads == 1) - { - assert (__pthread_total == 1); - thread->kernel_thread = __mach_thread_self (); - } - else - { - err = __thread_create (__mach_task_self (), &thread->kernel_thread); - if (err) - return EAGAIN; - - err = __thread_set_pcsp (thread->kernel_thread, - 1, thread->mcontext.pc, - 1, thread->mcontext.sp); - assert_perror (err); - - err = __thread_resume (thread->kernel_thread); - assert_perror (err); - } - - return 0; -} diff --git a/sysdeps/mach/pt-thread-alloc.c b/sysdeps/mach/pt-thread-alloc.c index af929533..a191c712 100644 --- a/sysdeps/mach/pt-thread-alloc.c +++ b/sysdeps/mach/pt-thread-alloc.c @@ -86,6 +86,8 @@ __pthread_thread_alloc (struct __pthread *thread) { assert (__pthread_total == 0); thread->kernel_thread = __mach_thread_self (); + /* We implicitly hold a reference. */ + __mach_port_deallocate (__mach_task_self (), thread->kernel_thread); } else { diff --git a/sysdeps/mach/pt-thread-start.c b/sysdeps/mach/pt-thread-start.c index eade5098..11b017ff 100644 --- a/sysdeps/mach/pt-thread-start.c +++ b/sysdeps/mach/pt-thread-start.c @@ -33,7 +33,11 @@ __pthread_thread_start (struct __pthread *thread) { /* The main thread is already running: do nothing. */ assert (__pthread_total == 1); - assert (thread->kernel_thread == __mach_thread_self ()); + assert (({ mach_port_t ktid = __mach_thread_self (); + int ok = thread->kernel_thread == ktid; + __mach_port_deallocate (__mach_task_self (), + thread->kernel_thread); + ok; })); } else { diff --git a/sysdeps/mach/pt-wakeup.c b/sysdeps/mach/pt-wakeup.c index 8ab10fb8..4920d102 100644 --- a/sysdeps/mach/pt-wakeup.c +++ b/sysdeps/mach/pt-wakeup.c @@ -1,5 +1,5 @@ /* Wakeup a thread. Mach version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2002 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 @@ __pthread_wakeup (struct __pthread *thread) error_t err; err = __mach_msg (&thread->wakeupmsg, MACH_SEND_MSG, - sizeof (mach_msg_header_t), 0, MACH_PORT_NULL, + sizeof (thread->wakeupmsg), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); assert_perror (err); } |