summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sysdeps/generic/pt-cond-timedwait.c23
-rw-r--r--sysdeps/generic/pt-mutex-timedlock.c2
-rw-r--r--sysdeps/generic/pt-rwlock-timedrdlock.c2
-rw-r--r--sysdeps/generic/pt-rwlock-timedwrlock.c2
-rw-r--r--sysdeps/l4/pt-start.c2
-rw-r--r--sysdeps/mach/hurd/i386/pt-setup.c8
-rw-r--r--sysdeps/mach/hurd/pt-docancel.c9
-rw-r--r--sysdeps/mach/hurd/pt-sysdep.h7
-rw-r--r--sysdeps/mach/pt-start.c106
-rw-r--r--sysdeps/mach/pt-thread-alloc.c2
-rw-r--r--sysdeps/mach/pt-thread-start.c6
-rw-r--r--sysdeps/mach/pt-wakeup.c4
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);
}