summaryrefslogtreecommitdiff
path: root/sysdeps/mach
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach')
-rw-r--r--sysdeps/mach/bits/spin-lock.h4
-rw-r--r--sysdeps/mach/hurd/ia32/pt-setup.c4
-rw-r--r--sysdeps/mach/hurd/pt-sysdep.c10
-rw-r--r--sysdeps/mach/hurd/pt-sysdep.h1
-rw-r--r--sysdeps/mach/pt-spin.c3
-rw-r--r--sysdeps/mach/pt-thread-alloc.c9
-rw-r--r--sysdeps/mach/pt-thread-dealloc.c41
-rw-r--r--sysdeps/mach/pt-thread-halt.c18
-rw-r--r--sysdeps/mach/pt-timedblock.c22
9 files changed, 84 insertions, 28 deletions
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))
diff --git a/sysdeps/mach/hurd/ia32/pt-setup.c b/sysdeps/mach/hurd/ia32/pt-setup.c
index 9a855847..32ace6ad 100644
--- a/sysdeps/mach/hurd/ia32/pt-setup.c
+++ b/sysdeps/mach/hurd/ia32/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/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 <pt-internal.h>
/* 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/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);
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/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 <assert.h>
+#include <errno.h>
+#include <mach.h>
+
+#include <pt-internal.h>
+
+/* 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 <pt-internal.h>
+/* 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);
}
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;