summaryrefslogtreecommitdiff
path: root/libpthread/sysdeps/l4
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2010-08-01 01:05:53 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2010-08-01 01:05:53 +0200
commit68567b88ee8f9e395e0c1f0a565affe8a1d4d68b (patch)
tree07d3b7b96832493cb3cc57a26e88157e354cf899 /libpthread/sysdeps/l4
parentfa0f7d1afb65bf077edfcc0f8977f95fca5656b9 (diff)
Move files to libpthread/ for inclusion along hurd
Diffstat (limited to 'libpthread/sysdeps/l4')
-rw-r--r--libpthread/sysdeps/l4/bits/pthread-np.h35
-rw-r--r--libpthread/sysdeps/l4/hurd/bits/pthread-np.h31
-rw-r--r--libpthread/sysdeps/l4/hurd/ia32/pt-machdep.c20
-rw-r--r--libpthread/sysdeps/l4/hurd/ia32/pt-setup.c117
-rw-r--r--libpthread/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c213
-rw-r--r--libpthread/sysdeps/l4/hurd/powerpc/pt-machdep.c20
-rw-r--r--libpthread/sysdeps/l4/hurd/powerpc/pt-setup.c93
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-block.c30
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-kill.c3
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-setactivity-np.c39
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-sigstate-destroy.c28
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-sigstate-init.c44
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-sigstate.c81
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-startup.c30
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-sysdep.c61
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-sysdep.h61
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-thread-alloc.c95
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-thread-halt.c104
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-thread-start.c70
-rw-r--r--libpthread/sysdeps/l4/hurd/pt-wakeup.c46
-rw-r--r--libpthread/sysdeps/l4/hurd/sig-sysdep.h69
-rw-r--r--libpthread/sysdeps/l4/hurd/sigprocmask.c41
-rw-r--r--libpthread/sysdeps/l4/pt-block.c47
-rw-r--r--libpthread/sysdeps/l4/pt-docancel.c42
-rw-r--r--libpthread/sysdeps/l4/pt-pool-np.c54
-rw-r--r--libpthread/sysdeps/l4/pt-spin.c63
-rw-r--r--libpthread/sysdeps/l4/pt-stack-alloc.c43
-rw-r--r--libpthread/sysdeps/l4/pt-thread-alloc.c43
-rw-r--r--libpthread/sysdeps/l4/pt-thread-dealloc.c32
-rw-r--r--libpthread/sysdeps/l4/pt-thread-halt.c45
-rw-r--r--libpthread/sysdeps/l4/pt-thread-start.c40
-rw-r--r--libpthread/sysdeps/l4/pt-timedblock.c35
-rw-r--r--libpthread/sysdeps/l4/pt-wakeup.c54
33 files changed, 1829 insertions, 0 deletions
diff --git a/libpthread/sysdeps/l4/bits/pthread-np.h b/libpthread/sysdeps/l4/bits/pthread-np.h
new file mode 100644
index 00000000..6a02bdc0
--- /dev/null
+++ b/libpthread/sysdeps/l4/bits/pthread-np.h
@@ -0,0 +1,35 @@
+/* Non-portable functions. L4 version.
+ Copyright (C) 2003, 2007 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. */
+
+/*
+ * Never include this file directly; use <pthread.h> or <cthreads.h> instead.
+ */
+
+#ifndef _BITS_PTHREAD_NP_H
+#define _BITS_PTHREAD_NP_H 1
+
+#include <l4.h>
+
+/* Add the thread TID to the internal kernel thread pool. */
+extern int pthread_pool_add_np (l4_thread_id_t tid);
+
+/* Get the first thread from the pool. */
+extern l4_thread_id_t pthread_pool_get_np (void);
+
+#endif /* bits/pthread-np.h */
diff --git a/libpthread/sysdeps/l4/hurd/bits/pthread-np.h b/libpthread/sysdeps/l4/hurd/bits/pthread-np.h
new file mode 100644
index 00000000..a90793df
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/bits/pthread-np.h
@@ -0,0 +1,31 @@
+/* Non-portable functions. Viengoos version.
+ Copyright (C) 2008 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. */
+
+/*
+ * Never include this file directly; use <pthread.h> or <cthreads.h> instead.
+ */
+
+#ifndef _BITS_PTHREAD_NP_H
+#define _BITS_PTHREAD_NP_H 1
+
+#include <hurd/addr.h>
+
+int pthread_setactivity_np (addr_t activity);
+
+#endif /* bits/pthread-np.h */
diff --git a/libpthread/sysdeps/l4/hurd/ia32/pt-machdep.c b/libpthread/sysdeps/l4/hurd/ia32/pt-machdep.c
new file mode 100644
index 00000000..dbf5cd7e
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/ia32/pt-machdep.c
@@ -0,0 +1,20 @@
+/* Machine dependent pthreads code. Hurd/i386 version.
+ Copyright (C) 2000 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. */
+
+/* Nothing to do. */
diff --git a/libpthread/sysdeps/l4/hurd/ia32/pt-setup.c b/libpthread/sysdeps/l4/hurd/ia32/pt-setup.c
new file mode 100644
index 00000000..579905c9
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/ia32/pt-setup.c
@@ -0,0 +1,117 @@
+/* Setup thread stack. Viengoos/i386 version.
+ Copyright (C) 2000, 2002, 2008 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 <l4.h>
+
+#include <pt-internal.h>
+#include <hurd/thread.h>
+#include <hurd/exceptions.h>
+
+/* The stack layout used on the i386 is:
+
+ -----------------
+ | ARG |
+ -----------------
+ | START_ROUTINE |
+ -----------------
+ | Return address |
+ ----------------- <- %ebp
+ | Frame pointer |
+ -----------------
+
+ We do the following: setup the stack to return to the entry routine.
+
+
+*/
+
+/* The stack contains:
+
+ arg
+ start_routine
+ 0 <- fake return address
+ C entry_point
+*/
+extern uintptr_t _pthread_entry_point;
+__asm__ ("\n\
+ .globl _pthread_entry_point, __pthread_entry_point\n\
+_pthread_entry_point:\n\
+__pthread_entry_point:\n\
+ pushl $0\n\
+ popf\n\
+\n\
+ xor %ebp, %ebp\n\
+ ret\n");
+
+/* Set up the stack for THREAD, such that it appears as if
+ START_ROUTINE and ARG were passed to the new thread's entry-point.
+ Return the stack pointer for the new thread. We also take the
+ opportunity to install THREAD in our utcb. */
+static void *
+stack_setup (struct __pthread *thread,
+ void *(*start_routine)(void *), void *arg,
+ void (*entry_point)(void *(*)(void *), void *))
+{
+ uintptr_t *top;
+
+ /* Calculate top of the new stack. */
+ top = (uintptr_t *) ((uintptr_t) thread->stackaddr + thread->stacksize);
+
+ /* Align on 0x10 for MMX operations. */
+ top = (uintptr_t) top & ~0xf;
+
+ if (start_routine)
+ {
+ /* Set up call frame. */
+ *--top = (uintptr_t) arg; /* Argument to START_ROUTINE. */
+ *--top = (uintptr_t) start_routine;
+ *--top = 0; /* Fake return address. */
+ *--top = (uintptr_t) entry_point;
+ }
+
+ return top;
+}
+
+int
+__pthread_setup (struct __pthread *thread,
+ void (*entry_point)(void *(*)(void *), void *),
+ void *(*start_routine)(void *), void *arg)
+{
+ thread->mcontext.pc = (void *) &_pthread_entry_point;
+ thread->mcontext.sp = (void *) stack_setup (thread, start_routine, arg,
+ entry_point);
+
+ if (__pthread_num_threads == 1)
+ return 0;
+
+ assert (! ADDR_IS_VOID (thread->exception_area[0]));
+
+ struct exception_page *exception_page = thread->exception_area_va;
+
+ /* SP is set to the end of the exception area minus one word, which
+ is the location of the exception page. */
+ exception_page->exception_handler_sp
+ = (uintptr_t) thread->exception_area_va + EXCEPTION_AREA_SIZE;
+ exception_page->exception_handler_sp -= sizeof (void *);
+ * (void **) exception_page->exception_handler_sp = thread->exception_area_va;
+
+ exception_page->exception_handler_ip = (uintptr_t) &exception_handler_entry;
+ exception_page->exception_handler_end = (uintptr_t) &exception_handler_end;
+
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c b/libpthread/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c
new file mode 100644
index 00000000..37ef8215
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c
@@ -0,0 +1,213 @@
+/* signal-dispatch-lowlevel.c - ia32 specific signal handling functions.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Neal H. Walfield <neal@gnu.org>.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 3 of
+ the License, or (at your option) any later version.
+
+ The GNU Hurd 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pt-internal.h>
+#include <sig-internal.h>
+
+#include <hurd/thread.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <atomic.h>
+
+extern char _signal_dispatch_entry;
+/* - 0(%esp) a pointer to the thread's struct signal_state.
+ - 4(%esp) a pointer to a siginfo_t.
+ - 8(%esp) is a pointer to the ss_flags field (or NULL).
+ - 12(%esp)+4 is the value of the sp when the thread was interrupted (intr_sp)
+ - 0(intr_sp) is the value of the ip when the thread was interrupted.
+ - 16(%esp) - 16 byte register save area
+*/
+__asm__ ("\n\
+ .globl _signal_dispatch_entry\n\
+_signal_dispatch_entry:\n\
+ /* Save caller saved registers (16 bytes). */\n\
+ mov %eax, 16(%esp)\n\
+ mov %ecx, 16+4(%esp)\n\
+ mov %edx, 16+8(%esp)\n\
+ pushf\n\
+ popl %eax\n\
+ mov %eax, 16+12(%esp)\n\
+\n\
+ /* Reset EFLAGS. */\n\
+ cld\n\
+ call signal_dispatch\n\
+\n\
+ /* Get the original stack and begin restoration. */\n\
+ mov 12(%esp), %edx\n\
+\n\
+ /* Move the saved registers to the user stack. */\n\
+ sub $16, %edx\n\
+ /* eax. */\n\
+ mov 16+0(%esp), %ecx\n\
+ mov %ecx, 0(%edx)\n\
+ /* ecx. */\n\
+ mov 16+4(%esp), %ecx\n\
+ mov %ecx, 4(%edx)\n\
+ /* edx. */\n\
+ mov 16+8(%esp), %ecx\n\
+ mov %ecx, 8(%edx)\n\
+ /* eflags. */\n\
+ mov 16+12(%esp), %ecx\n\
+ mov %ecx, 12(%edx)\n\
+\n\
+ /* Get the pointer to the sigaltstack flags. */\n\
+ mov 8(%esp), %ecx\n\
+\n\
+ /* Restore the user stack. */\n\
+ mov %edx, %esp\n\
+\n\
+ /* Clear the SA_ONSTACK flag. */\n\
+ and %ecx, %ecx\n\
+ jz after_clear\n\
+ lock; and $~1, 0(%ecx)\n\
+after_clear:\n\
+\n\
+ /* Restore eflags, the scratch regs and the original sp and ip. */\n\
+ popl %eax\n\
+ popl %ecx\n\
+ popl %edx\n\
+ popf\n\
+ ret\n");
+
+extern char _signal_dispatch_entry_self;
+/* - 0(%esp) is the return address (we ignore it)
+ - 4(%esp) is the sp to load
+
+ Since we are returning to signal_dispatch_lowlevel's caller, we
+ also need to restore its frame pointer. */
+__asm__ ("\n\
+ .globl _signal_dispatch_entry_self\n\
+_signal_dispatch_entry_self:\n\
+ mov 0(%ebp), %ebp\n\
+ mov 4(%esp), %esp\n\
+ jmp _signal_dispatch_entry\n");
+
+void
+signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid,
+ siginfo_t si)
+{
+ assert (pthread_mutex_trylock (&ss->lock) == EBUSY);
+
+ struct __pthread *thread = __pthread_getid (tid);
+
+ bool self = tid == pthread_self ();
+
+ uintptr_t intr_sp;
+
+ if (self)
+ {
+ /* The return address is just before the first argument. */
+ intr_sp = (uintptr_t) &ss - 4;
+ assert (* (void **) intr_sp == __builtin_return_address (0));
+ }
+ else
+ {
+ struct hurd_thread_exregs_in in;
+ memset (&in, 0, sizeof (in));
+ struct hurd_thread_exregs_out out;
+
+ error_t err;
+ err = rm_thread_exregs (ADDR_VOID, thread->object,
+ HURD_EXREGS_STOP | HURD_EXREGS_ABORT_IPC
+ | HURD_EXREGS_GET_REGS,
+ in, &out);
+ if (err)
+ panic ("Failed to modify thread " ADDR_FMT,
+ ADDR_PRINTF (thread->object));
+
+ intr_sp = out.sp;
+
+ /* Push the ip on the user stack. */
+ intr_sp -= 4;
+ * (uintptr_t *) intr_sp = out.ip;
+ }
+
+ bool altstack = false;
+ uintptr_t sp;
+ if (! (ss->actions[si.si_signo - 1].sa_flags & SA_ONSTACK)
+ || (ss->stack.ss_flags & SS_DISABLE)
+ || (ss->stack.ss_flags & SS_ONSTACK))
+ {
+ assert (! self);
+ sp = intr_sp;
+ }
+ else
+ {
+ /* The stack grows down. */
+ sp = (uintptr_t) ss->stack.ss_sp + ss->stack.ss_size;
+
+ /* We know intimately that SS_ONSTACK is the least significant
+ bit. */
+ assert (SS_ONSTACK == 1);
+ atomic_bit_set (&ss->stack.ss_flags, 0);
+
+ altstack = true;
+ }
+
+ /* Set up the call frame for a call to signal_dispatch_entry. */
+
+ /* Allocate a siginfo structure on the stack. */
+ sp = sp - sizeof (siginfo_t);
+ siginfo_t *sip = (void *) sp;
+ /* Copy the user supplied values. */
+ *sip = si;
+
+ /* Add space for the 4 caller saved registers. */
+ sp -= 4 * sizeof (uintptr_t);
+
+ /* Save the interrupted sp. */
+ sp -= 4;
+ * (uintptr_t *) sp = intr_sp;
+
+ /* Address of the ss_flags. */
+ sp -= 4;
+ if (altstack)
+ * (uintptr_t *) sp = (uintptr_t) &ss->stack.ss_flags;
+ else
+ * (uintptr_t *) sp = 0;
+
+ /* Push the parameters to signal_dispatch. */
+
+ /* signal info structure. */
+ sp -= 4;
+ * (uintptr_t *) sp = (uintptr_t) sip;
+
+ /* The ss. */
+ sp -= 4;
+ * (uintptr_t *) sp = (uintptr_t) ss;
+
+ pthread_mutex_transfer_np (&ss->lock, tid);
+
+ if (self)
+ ((void (*) (uintptr_t)) &_signal_dispatch_entry_self) ((uintptr_t) sp);
+ else
+ {
+ struct hurd_thread_exregs_in in;
+ struct hurd_thread_exregs_out out;
+
+ in.sp = sp;
+ in.ip = (uintptr_t) &_signal_dispatch_entry;
+
+ rm_thread_exregs (ADDR_VOID, thread->object,
+ HURD_EXREGS_SET_SP_IP
+ | HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC,
+ in, &out);
+ }
+}
diff --git a/libpthread/sysdeps/l4/hurd/powerpc/pt-machdep.c b/libpthread/sysdeps/l4/hurd/powerpc/pt-machdep.c
new file mode 100644
index 00000000..754d203e
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/powerpc/pt-machdep.c
@@ -0,0 +1,20 @@
+/* Machine dependent pthreads code. Hurd/PowerPC version.
+ Copyright (C) 2003 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. */
+
+/* Nothing to do. */
diff --git a/libpthread/sysdeps/l4/hurd/powerpc/pt-setup.c b/libpthread/sysdeps/l4/hurd/powerpc/pt-setup.c
new file mode 100644
index 00000000..d3cf4ec3
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/powerpc/pt-setup.c
@@ -0,0 +1,93 @@
+/* Setup thread stack. Hurd/PowerPC version.
+ Copyright (C) 2003 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 <l4.h>
+
+#include <pt-internal.h>
+
+/* Arguments is passed in registers on the PowerPC. But the
+ exchange registers syscall only allows us to set the PC and the
+ stack pointer so we put the entry point and start function on
+ the stack. */
+struct start_info
+{
+ void (*entry_point) (void *(*)(void *), void *);
+ void *(*start_routine) (void *);
+ void *arg;
+};
+
+void first_entry_1 (void);
+
+/* Stage 1 entry function. The start_info structure is inlined on the
+ stack. Put values into registers and call entry function. */
+asm (" ;\
+first_entry_1: ;\
+ lwz 0, 0(1) ;\
+ lwz 3, 4(1) ;\
+ lwz 4, 8(1) ;\
+ mtctr 0 ;\
+ bctrl ;\
+");
+
+/* Set up the stack for THREAD, such that it appears as if
+ START_ROUTINE and ARG were passed to the new thread's entry-point.
+ Return the stack pointer for the new thread. We also take the
+ opportunity to install THREAD in our utcb. */
+static void *
+stack_setup (struct __pthread *thread,
+ void (*entry_point)(void *(*)(void *), void *),
+ void *(*start_routine)(void *), void *arg)
+{
+ l4_word_t *top;
+
+ /* Calculate top of the new stack. */
+ top = (l4_word_t *) ((l4_word_t) thread->stackaddr + thread->stacksize);
+
+ /* Initial stack frame. */
+ top[-4] = 0;
+ top = top - 4;
+
+ if (start_routine)
+ {
+ struct start_info *info = ((struct start_info *) top) - 1;
+
+ info->entry_point = entry_point;
+ info->start_routine = start_routine;
+ info->arg = arg;
+ return (void *) info;
+ }
+ return top;
+}
+
+int
+__pthread_setup (struct __pthread *thread,
+ void (*entry_point)(void *(*)(void *), void *),
+ void *(*start_routine)(void *), void *arg)
+{
+ thread->mcontext.pc = first_entry_1;
+ thread->mcontext.sp = stack_setup (thread, entry_point,
+ start_routine, arg);
+
+ if (l4_same_threads (thread->threadid, l4_myself ()))
+ l4_set_user_defined_handle ((l4_word_t) thread);
+ else
+ l4_set_user_defined_handle_of (thread->threadid,
+ (l4_word_t) thread);
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-block.c b/libpthread/sysdeps/l4/hurd/pt-block.c
new file mode 100644
index 00000000..2315b1c4
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-block.c
@@ -0,0 +1,30 @@
+/* Block a thread. Viengoos version.
+ Copyright (C) 2008 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 <pt-internal.h>
+
+#include <hurd/stddef.h>
+#include <hurd/futex.h>
+
+/* Block THREAD. */
+void
+__pthread_block (struct __pthread *thread)
+{
+ futex_wait (&thread->threadid, thread->threadid);
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-kill.c b/libpthread/sysdeps/l4/hurd/pt-kill.c
new file mode 100644
index 00000000..c72e82f4
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-kill.c
@@ -0,0 +1,3 @@
+/* The generic version is good enough for us, however, the generic
+ Hurd on Mach version supplies a specialized version */
+#include "../generic/pt-kill.c"
diff --git a/libpthread/sysdeps/l4/hurd/pt-setactivity-np.c b/libpthread/sysdeps/l4/hurd/pt-setactivity-np.c
new file mode 100644
index 00000000..f2f07233
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-setactivity-np.c
@@ -0,0 +1,39 @@
+/* Set a thread's activity activity. Viengoos version.
+ Copyright (C) 2008 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 <pt-internal.h>
+
+#include <hurd/addr.h>
+#include <hurd/thread.h>
+
+int
+pthread_setactivity_np (addr_t activity)
+{
+ struct __pthread *self = _pthread_self ();
+
+ struct hurd_thread_exregs_in in;
+ in.activity = activity;
+
+ struct hurd_thread_exregs_out out;
+ int err = rm_thread_exregs (ADDR_VOID, self->object,
+ HURD_EXREGS_SET_ACTIVITY,
+ in, &out);
+
+ return err;
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-sigstate-destroy.c b/libpthread/sysdeps/l4/hurd/pt-sigstate-destroy.c
new file mode 100644
index 00000000..997a0369
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-sigstate-destroy.c
@@ -0,0 +1,28 @@
+/* Destroy the signal state. Hurd on L4 version.
+ Copyright (C) 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
+ 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 <pthread.h>
+
+#include <pt-internal.h>
+
+void
+__pthread_sigstate_destroy (struct __pthread *thread)
+{
+ /* Nothing to do. */
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-sigstate-init.c b/libpthread/sysdeps/l4/hurd/pt-sigstate-init.c
new file mode 100644
index 00000000..4c40fdb3
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-sigstate-init.c
@@ -0,0 +1,44 @@
+/* Initialize the signal state. Hurd on L4 version.
+ Copyright (C) 2003, 2008 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 <pthread.h>
+
+#include <pt-internal.h>
+#include <sig-internal.h>
+
+error_t
+__pthread_sigstate_init (struct __pthread *thread)
+{
+ struct signal_state *ss = &thread->ss;
+
+ memset (ss, 0, sizeof (*ss));
+
+ ss->stack.ss_flags = SS_DISABLE;
+
+ int signo;
+ for (signo = 1; signo < NSIG; ++signo)
+ {
+ sigemptyset (&ss->actions[signo - 1].sa_mask);
+ ss->actions[signo - 1].sa_flags = SA_RESTART;
+ ss->actions[signo - 1].sa_handler = SIG_DFL;
+ ss->lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
+ }
+
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-sigstate.c b/libpthread/sysdeps/l4/hurd/pt-sigstate.c
new file mode 100644
index 00000000..66dd08cf
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-sigstate.c
@@ -0,0 +1,81 @@
+/* Set a thread's signal state. Hurd on L4 version.
+ Copyright (C) 2002, 2005, 2008 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 <pthread.h>
+#include <assert.h>
+#include <signal.h>
+
+#include <pt-internal.h>
+
+error_t
+__pthread_sigstate (struct __pthread *thread, int how,
+ const sigset_t *set, sigset_t *oset,
+ int clear_pending)
+{
+ struct signal_state *ss = &thread->ss;
+ pthread_mutex_lock (&ss->lock);
+
+ if (oset)
+ *oset = ss->blocked;
+
+ if (set)
+ {
+ /* Mask out SIGKILL and SIGSTOP. */
+ sigset_t s = *set;
+ sigdelset (&s, SIGKILL);
+ sigdelset (&s, SIGSTOP);
+
+ switch (how)
+ {
+ case SIG_BLOCK:
+ ss->blocked |= s;
+ break;
+ case SIG_UNBLOCK:
+ ss->blocked &= ~s;
+ break;
+ case SIG_SETMASK:
+ ss->blocked = s;
+ break;
+ default:
+ errno = EINVAL;
+ pthread_mutex_unlock (&ss->lock);
+ return -1;
+ }
+ }
+
+ if (clear_pending)
+ sigemptyset (&ss->pending);
+
+ /* A "signal shall remain pending until it is unblocked" (2.4.1).
+
+ "If there are any pending unblocked signals after the call to
+ sigprocmask(), at least one of those signals shall be delivered
+ before the call to sigprocmask() returns."
+ (pthread_sigmask). */
+ sigset_t extant = ~ss->blocked & ss->pending;
+ if (! extant)
+ extant = ~ss->blocked & process_pending;
+
+ pthread_mutex_unlock (&ss->lock);
+
+ if (extant)
+ raise (l4_lsb64 (extant));
+
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-startup.c b/libpthread/sysdeps/l4/hurd/pt-startup.c
new file mode 100644
index 00000000..b6461de7
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-startup.c
@@ -0,0 +1,30 @@
+/* Thread initialization. Hurd/L4 version.
+ Copyright (C) 2007 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 <l4.h>
+#include <pt-internal.h>
+
+#include <hurd/exceptions.h>
+
+void
+__pthread_startup (void)
+{
+ struct __pthread *pthread = _pthread_self ();
+ pthread->threadid = l4_myself ();
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-sysdep.c b/libpthread/sysdeps/l4/hurd/pt-sysdep.c
new file mode 100644
index 00000000..c23364c7
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-sysdep.c
@@ -0,0 +1,61 @@
+/* System dependent pthreads code. Hurd version.
+ Copyright (C) 2000, 2008 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 <stddef.h>
+#include <stdint.h>
+
+#include <pt-internal.h>
+
+int
+sched_yield (void)
+{
+ l4_yield ();
+ return 0;
+}
+
+/* Forward. */
+static void init_routine (void (*) (void *), void *)
+ __attribute__ ((noreturn));
+
+/* OK, the name of this variable isn't really appropriate, but I don't
+ want to change it yet. */
+void (*_pthread_init_routine)(void (*) (void *), 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 void
+init_routine (void (*entry) (void *), void *arg)
+{
+ /* Initialize the library. */
+ __pthread_initialize ();
+
+ struct __pthread *thread;
+ int err;
+
+ /* Create the pthread structure for the main thread (i.e. us). */
+ err = __pthread_create_internal (&thread, 0,
+ (void *(*)(void *)) entry, arg);
+ assert_perror (err);
+
+ /* Switch stacks. */
+ l4_start_sp_ip (l4_myself (), thread->mcontext.sp,
+ thread->mcontext.pc);
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-sysdep.h b/libpthread/sysdeps/l4/hurd/pt-sysdep.h
new file mode 100644
index 00000000..08bcd143
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-sysdep.h
@@ -0,0 +1,61 @@
+/* Internal definitions for pthreads library.
+ Copyright (C) 2000, 2002, 2005, 2007, 2008 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. */
+
+#ifndef _PT_SYSDEP_H
+#define _PT_SYSDEP_H 1
+
+#include <l4.h>
+#include <hurd/storage.h>
+#include <sys/mman.h>
+
+/* XXX */
+#define _POSIX_THREAD_THREADS_MAX 64
+
+/* The default stack size: 2MB. */
+#define PTHREAD_STACK_DEFAULT (2 * 1024 * 1024)
+
+#include <hurd/exceptions.h>
+
+#define EXCEPTION_AREA_SIZE EXCEPTION_STACK_SIZE
+#define EXCEPTION_AREA_SIZE_LOG2 EXCEPTION_STACK_SIZE_LOG2
+/* The exception page is the first object. */
+#define EXCEPTION_PAGE 0
+
+#define PTHREAD_SYSDEP_MEMBERS \
+ addr_t object; \
+ l4_thread_id_t threadid; \
+ addr_t exception_area[EXCEPTION_AREA_SIZE / PAGESIZE]; \
+ void *exception_area_va; \
+ l4_word_t my_errno;
+
+extern inline struct __pthread *
+__attribute__((__always_inline__))
+_pthread_self (void)
+{
+ return (struct __pthread *) l4_user_defined_handle ();
+}
+
+extern inline void
+__attribute__((__always_inline__))
+__pthread_stack_dealloc (void *stackaddr, size_t stacksize)
+{
+ munmap (stackaddr, stacksize);
+}
+
+#endif /* pt-sysdep.h */
diff --git a/libpthread/sysdeps/l4/hurd/pt-thread-alloc.c b/libpthread/sysdeps/l4/hurd/pt-thread-alloc.c
new file mode 100644
index 00000000..ada7b3b8
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-thread-alloc.c
@@ -0,0 +1,95 @@
+/* Allocate kernel thread. Viengoos version.
+ Copyright (C) 2007, 2008 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 <hurd/startup.h>
+#include <hurd/storage.h>
+#include <hurd/as.h>
+#include <hurd/addr.h>
+
+#include <pt-internal.h>
+
+extern struct hurd_startup_data *__hurd_startup_data;
+
+extern addr_t meta_data_activity;
+
+int
+__pthread_thread_alloc (struct __pthread *thread)
+{
+ /* The main thread is already running of course. */
+ if (__pthread_num_threads == 1)
+ {
+ thread->object = __hurd_startup_data->thread;
+ thread->threadid = l4_myself ();
+ return 0;
+ }
+ else
+ {
+ addr_t exception_area = as_alloc (EXCEPTION_AREA_SIZE_LOG2, 1, true);
+
+ thread->exception_area_va
+ = ADDR_TO_PTR (addr_extend (exception_area,
+ 0, EXCEPTION_AREA_SIZE_LOG2));
+
+ int i;
+ for (i = 0; i < EXCEPTION_AREA_SIZE / PAGESIZE; i ++)
+ {
+ addr_t slot = addr_chop (PTR_TO_ADDR (thread->exception_area_va
+ + i * PAGESIZE),
+ PAGESIZE_LOG2);
+ as_ensure (slot);
+
+ struct storage storage = storage_alloc (ADDR_VOID, cap_page,
+ STORAGE_LONG_LIVED,
+ OBJECT_POLICY_DEFAULT,
+ slot);
+ if (ADDR_IS_VOID (storage.addr))
+ {
+ int j;
+ for (j = 0; j < i; j ++)
+ storage_free (thread->exception_area[j], false);
+ as_free (exception_area, false);
+ return EAGAIN;
+ }
+
+ thread->exception_area[i] = storage.addr;
+ }
+
+ struct storage storage;
+ storage = storage_alloc (meta_data_activity, cap_thread,
+ /* Threads are rarely shortly lived. */
+ STORAGE_MEDIUM_LIVED, OBJECT_POLICY_DEFAULT,
+ ADDR_VOID);
+ if (ADDR_IS_VOID (storage.addr))
+ {
+ int j;
+ for (j = 0; j < EXCEPTION_AREA_SIZE / PAGESIZE; j ++)
+ storage_free (thread->exception_area[j], false);
+ as_free (exception_area, false);
+ return EAGAIN;
+ }
+
+ thread->object = storage.addr;
+ }
+
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-thread-halt.c b/libpthread/sysdeps/l4/hurd/pt-thread-halt.c
new file mode 100644
index 00000000..98fefaab
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-thread-halt.c
@@ -0,0 +1,104 @@
+/* Deallocate the kernel thread resources. Viengoos version.
+ Copyright (C) 2007, 2008 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 <pt-internal.h>
+
+#include <hurd/exceptions.h>
+#include <hurd/mutex.h>
+#include <hurd/as.h>
+#include <hurd/addr.h>
+
+/* If we try to deallocate our self, we will end up causing a
+ deadlock. Thus, when a thread tries to free itself, we add it
+ here. The next thread to free a thread will free it. */
+ss_mutex_t saved_object_lock;
+static addr_t saved_object;
+
+void
+__pthread_thread_halt (struct __pthread *thread, int need_dealloc)
+{
+ /* We may deallocate THREAD. First save any data we need. */
+
+ addr_t exception_area[EXCEPTION_AREA_SIZE / PAGESIZE];
+ memcpy (exception_area, thread->exception_area,
+ sizeof (thread->exception_area));
+ memset (thread->exception_area, 0, sizeof (thread->exception_area));
+
+ void *va = thread->exception_area_va;
+
+ addr_t object = thread->object;
+ l4_thread_id_t tid = thread->threadid;
+
+ if (need_dealloc)
+ __pthread_dealloc (thread);
+
+ /* The THREAD data structure is no longer valid. */
+ thread = NULL;
+
+ /* Deallocate any saved object. */
+ ss_mutex_lock (&saved_object_lock);
+ if (! ADDR_IS_VOID (saved_object))
+ {
+ storage_free (saved_object, false);
+ saved_object = ADDR_VOID;
+ }
+ ss_mutex_unlock (&saved_object_lock);
+
+ /* Free the exception area. */
+
+ /* Clean up the exception page. */
+ exception_page_cleanup
+ (ADDR_TO_PTR (addr_extend (exception_area[EXCEPTION_PAGE],
+ 0, PAGESIZE_LOG2)));
+
+ /* Free the storage. */
+ int i;
+ for (i = 0; i < EXCEPTION_AREA_SIZE / PAGESIZE; i ++)
+ {
+ assert (! ADDR_IS_VOID (exception_area[i]));
+ storage_free (exception_area[i], false);
+ }
+
+ /* And the address space. */
+ as_free (addr_chop (PTR_TO_ADDR (va), EXCEPTION_AREA_SIZE_LOG2), false);
+
+ if (tid == l4_myself ())
+ /* If we try to storage_free (storage.addr), we will freeze in the
+ middle. That's no good. We set SAVED_OBJECT to our thread
+ object and the next thread in will free us. */
+ {
+ ss_mutex_lock (&saved_object_lock);
+ saved_object = object;
+ ss_mutex_unlock (&saved_object_lock);
+ }
+ else
+ storage_free (object, false);
+
+ if (tid == l4_myself ())
+ {
+ l4_send_timeout (l4_myself (), L4_NEVER);
+ panic ("Failed to stop thread %x.%x!",
+ l4_thread_no (l4_myself ()), l4_version (l4_myself ()));
+ }
+ else
+ thread_stop (object);
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-thread-start.c b/libpthread/sysdeps/l4/hurd/pt-thread-start.c
new file mode 100644
index 00000000..9db399ce
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-thread-start.c
@@ -0,0 +1,70 @@
+/* Start thread. L4 version.
+ Copyright (C) 2007 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 <hurd/thread.h>
+#include <hurd/exceptions.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_thread_start (struct __pthread *thread)
+{
+ error_t err;
+
+ if (__pthread_num_threads == 1)
+ /* The main thread is already running of course. */
+ {
+ assert (__pthread_total == 1);
+ assert (l4_is_thread_equal (l4_myself (), thread->threadid));
+ l4_set_user_defined_handle ((l4_word_t) thread);
+ }
+ else
+ {
+ struct hurd_thread_exregs_in in;
+ struct hurd_thread_exregs_out out;
+
+ in.aspace = ADDR (0, 0);
+ in.aspace_cap_properties = CAP_PROPERTIES_VOID;
+ in.aspace_cap_properties_flags = CAP_COPY_COPY_SOURCE_GUARD;
+
+ in.activity = ADDR_VOID;
+
+ in.exception_page = addr_chop (PTR_TO_ADDR (thread->exception_area_va),
+ PAGESIZE_LOG2);
+
+ in.sp = (l4_word_t) thread->mcontext.sp;
+ in.ip = (l4_word_t) thread->mcontext.pc;
+
+ in.user_handle = (l4_word_t) thread;
+ err = rm_thread_exregs (ADDR_VOID, thread->object,
+ HURD_EXREGS_SET_ASPACE
+ | HURD_EXREGS_SET_ACTIVITY
+ | HURD_EXREGS_SET_EXCEPTION_PAGE
+ | HURD_EXREGS_SET_SP_IP
+ | HURD_EXREGS_SET_USER_HANDLE
+ | HURD_EXREGS_START
+ | HURD_EXREGS_ABORT_IPC,
+ in, &out);
+ assert (err == 0);
+ }
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/hurd/pt-wakeup.c b/libpthread/sysdeps/l4/hurd/pt-wakeup.c
new file mode 100644
index 00000000..e568a6f9
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/pt-wakeup.c
@@ -0,0 +1,46 @@
+/* Wakeup a thread. Viengoos version.
+ Copyright (C) 2008 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 <pt-internal.h>
+
+#include <hurd/stddef.h>
+#include <hurd/futex.h>
+#include <stdint.h>
+
+/* Wakeup THREAD. */
+void
+__pthread_wakeup (struct __pthread *thread)
+{
+ /* We need to loop here as the blocked thread may not yet be
+ blocked! Here's what happens when a thread blocks: it registers
+ itself as blocked, drops the relevant lock and then actually
+ blocks (via __pthread_block). This means that after dropping the
+ lock and before blocking, it may be interrupted and another
+ thread may try to wake it. */
+ long ret;
+ do
+ {
+ ret = futex_wake (&thread->threadid, INT_MAX);
+ assertx (ret <= 1, "tid: %x, ret: %d", thread->threadid, ret);
+
+ if (ret == 0)
+ l4_thread_switch (thread->threadid);
+ }
+ while (ret == 0);
+}
diff --git a/libpthread/sysdeps/l4/hurd/sig-sysdep.h b/libpthread/sysdeps/l4/hurd/sig-sysdep.h
new file mode 100644
index 00000000..33e13857
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/sig-sysdep.h
@@ -0,0 +1,69 @@
+/* sig-sysdep.h - Hurd system specific header file.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Neal H. Walfield <neal@gnu.org>.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 3 of
+ the License, or (at your option) any later version.
+
+ The GNU Hurd 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <l4.h>
+#include <string.h>
+
+struct utcb
+{
+ l4_word_t saved_sender;
+ l4_word_t saved_receiver;
+ l4_word_t saved_timeout;
+ l4_word_t saved_error_code;
+ l4_word_t saved_flags;
+ l4_word_t saved_br0;
+ l4_msg_t saved_message;
+};
+
+static inline void
+utcb_state_save (struct utcb *buffer)
+{
+ l4_word_t *utcb = _L4_utcb ();
+
+ buffer->saved_sender = utcb[_L4_UTCB_SENDER];
+ buffer->saved_receiver = utcb[_L4_UTCB_RECEIVER];
+ buffer->saved_timeout = utcb[_L4_UTCB_TIMEOUT];
+ buffer->saved_error_code = utcb[_L4_UTCB_ERROR_CODE];
+ buffer->saved_flags = utcb[_L4_UTCB_FLAGS];
+ buffer->saved_br0 = utcb[_L4_UTCB_BR0];
+ memcpy (&buffer->saved_message,
+ utcb, L4_NUM_MRS * sizeof (l4_word_t));
+}
+
+static inline void
+utcb_state_restore (struct utcb *buffer)
+{
+ l4_word_t *utcb = _L4_utcb ();
+
+ utcb[_L4_UTCB_SENDER] = buffer->saved_sender;
+ utcb[_L4_UTCB_RECEIVER] = buffer->saved_receiver;
+ utcb[_L4_UTCB_TIMEOUT] = buffer->saved_timeout;
+ utcb[_L4_UTCB_ERROR_CODE] = buffer->saved_error_code;
+ utcb[_L4_UTCB_FLAGS] = buffer->saved_flags;
+ utcb[_L4_UTCB_BR0] = buffer->saved_br0;
+ memcpy (utcb, &buffer->saved_message,
+ L4_NUM_MRS * sizeof (l4_word_t));
+}
+
+#define SIGNAL_DISPATCH_ENTRY \
+ struct utcb buffer; utcb_state_save (&buffer);
+
+#define SIGNAL_DISPATCH_EXIT \
+ utcb_state_restore (&buffer);
diff --git a/libpthread/sysdeps/l4/hurd/sigprocmask.c b/libpthread/sysdeps/l4/hurd/sigprocmask.c
new file mode 100644
index 00000000..a38b3795
--- /dev/null
+++ b/libpthread/sysdeps/l4/hurd/sigprocmask.c
@@ -0,0 +1,41 @@
+/* sigprocmask.c - Generic sigprocmask implementation.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Written by Neal H. Walfield <neal@gnu.org>.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 3 of
+ the License, or (at your option) any later version.
+
+ The GNU Hurd 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pt-internal.h>
+#include <sig-internal.h>
+
+int
+sigprocmask (int how, const sigset_t *restrict set, sigset_t *restrict old)
+{
+ struct __pthread *thread = _pthread_self ();
+ if (! thread)
+ /* Library is initializing. */
+ {
+ assert (__pthread_num_threads == 1);
+
+ /* We should get the default mask from the startup data structure. */
+ if (old)
+ *old = 0;
+
+ return 0;
+ }
+
+ return pthread_sigmask (how, set, old);
+}
diff --git a/libpthread/sysdeps/l4/pt-block.c b/libpthread/sysdeps/l4/pt-block.c
new file mode 100644
index 00000000..69e1d358
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-block.c
@@ -0,0 +1,47 @@
+/* Block a thread. L4 version.
+ Copyright (C) 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
+ 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 <l4.h>
+
+#include <pt-internal.h>
+
+#include <hurd/stddef.h>
+
+/* Block THREAD. */
+void
+__pthread_block (struct __pthread *thread)
+{
+ debug (5, "%x.%x/%x blocking",
+ l4_thread_no (thread->threadid), l4_version (thread->threadid),
+ thread->threadid);
+
+ l4_accept (L4_UNTYPED_WORDS_ACCEPTOR);
+ l4_msg_tag_t tag = l4_receive (l4_anythread);
+ if (l4_ipc_failed (tag))
+ {
+ debug (1, "%x.%x failed to block: %d, offset: %x",
+ l4_thread_no (l4_myself ()), l4_version (l4_myself ()),
+ (l4_error_code () >> 1) & 0x7,
+ l4_error_code () >> 4);
+ assert (! l4_ipc_failed (tag));
+ }
+ else
+ debug (5, "%x.%x unblocked",
+ l4_thread_no (thread->threadid), l4_version (thread->threadid));
+}
diff --git a/libpthread/sysdeps/l4/pt-docancel.c b/libpthread/sysdeps/l4/pt-docancel.c
new file mode 100644
index 00000000..a3965d0d
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-docancel.c
@@ -0,0 +1,42 @@
+/* Cancel a thread.
+ Copyright (C) 2002, 2007 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 <pthread.h>
+
+#include <pt-internal.h>
+
+static void
+call_exit (void)
+{
+ pthread_exit (0);
+}
+
+int
+__pthread_do_cancel (struct __pthread *p)
+{
+ assert (p->cancel_pending == 1);
+ assert (p->cancel_state == PTHREAD_CANCEL_ENABLE);
+
+ if (l4_is_thread_equal (l4_myself (), p->threadid))
+ call_exit ();
+ else
+ l4_start_sp_ip (p->threadid, (l4_word_t) p->mcontext.sp,
+ (l4_word_t) call_exit);
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/pt-pool-np.c b/libpthread/sysdeps/l4/pt-pool-np.c
new file mode 100644
index 00000000..e83022ba
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-pool-np.c
@@ -0,0 +1,54 @@
+/* Thread pool for L4 threads.
+ Copyright (C) 2004, 2007 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 <pt-internal.h>
+#include <l4/thread.h>
+
+static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER;
+
+_L4_thread_id_t pool_list = l4_nilthread;
+
+/* Add the thread TID to the pthread kernel thread pool. */
+int
+pthread_pool_add_np (l4_thread_id_t tid)
+{
+ __pthread_mutex_lock (&pool_lock);
+ /* FIXME: Do error checking. */
+ l4_set_user_defined_handle_of (tid, pool_list);
+ pool_list = tid;
+ __pthread_mutex_unlock (&pool_lock);
+
+ return 0;
+}
+
+
+/* Get the first thread from the pool. */
+l4_thread_id_t
+pthread_pool_get_np (void)
+{
+ _L4_thread_id_t tid;
+
+ __pthread_mutex_lock (&pool_lock);
+ /* FIXME: Do error checking. */
+ tid = pool_list;
+ if (tid != l4_nilthread)
+ pool_list = l4_user_defined_handle_of (tid);
+ __pthread_mutex_unlock (&pool_lock);
+ return tid;
+}
diff --git a/libpthread/sysdeps/l4/pt-spin.c b/libpthread/sysdeps/l4/pt-spin.c
new file mode 100644
index 00000000..b6978b0c
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-spin.c
@@ -0,0 +1,63 @@
+/* Spin locks. L4 version.
+ 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
+ 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 <l4.h>
+
+#include <pthread.h>
+#include <sched.h>
+
+/* The default for single processor machines; don't spin, it's
+ pointless. */
+#ifndef __PTHREAD_SPIN_COUNT
+# define __PTHREAD_SPIN_COUNT 1
+#endif
+
+/* The number of times to spin while trying to lock a spin lock object
+ before yielding the processor. */
+int __pthread_spin_count = __PTHREAD_SPIN_COUNT;
+
+
+/* Lock the spin lock object LOCK. If the lock is held by another
+ thread spin until it becomes available. */
+int
+_pthread_spin_lock (__pthread_spinlock_t *lock)
+{
+ l4_time_t timeout;
+ int i;
+
+ /* Start with a small timeout of 2 microseconds, then back off
+ exponentially. */
+ timeout = l4_time_period (2);
+
+ while (1)
+ {
+ for (i = 0; i < __pthread_spin_count; i++)
+ {
+ if (__pthread_spin_trylock (lock) == 0)
+ return 0;
+ }
+ l4_sleep (timeout);
+
+ timeout = l4_time_mul2 (timeout);
+ if (timeout == L4_NEVER)
+ timeout = L4_TIME_PERIOD_MAX;
+ }
+}
+
+weak_alias (_pthread_spin_lock, pthread_spin_lock);
diff --git a/libpthread/sysdeps/l4/pt-stack-alloc.c b/libpthread/sysdeps/l4/pt-stack-alloc.c
new file mode 100644
index 00000000..b7ec12b4
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-stack-alloc.c
@@ -0,0 +1,43 @@
+/* Allocate a new stack. L4 Hurd version.
+ Copyright (C) 2000, 2007 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 <l4.h>
+#include <errno.h>
+
+#include <pt-internal.h>
+
+#include <sys/mman.h>
+
+/* Allocate a new stack of size STACKSIZE. If successful, store the
+ address of the newly allocated stack in *STACKADDR and return 0.
+ Otherwise return an error code (EINVAL for an invalid stack size,
+ EAGAIN if the system lacked the necessary resources to allocate a
+ new stack). */
+int
+__pthread_stack_alloc (void **stackaddr, size_t stacksize)
+{
+ void *buffer = mmap (0, stacksize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (buffer == MAP_FAILED)
+ return EAGAIN;
+
+ *stackaddr = buffer;
+
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/pt-thread-alloc.c b/libpthread/sysdeps/l4/pt-thread-alloc.c
new file mode 100644
index 00000000..ec69afb5
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-thread-alloc.c
@@ -0,0 +1,43 @@
+/* Allocate kernel thread. L4 version.
+ Copyright (C) 2003, 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 <string.h>
+
+#include <pt-internal.h>
+
+int
+__pthread_thread_alloc (struct __pthread *thread)
+{
+ error_t err;
+
+ /* The main thread is already running of course. */
+ if (__pthread_num_threads == 1)
+ thread->threadid = l4_myself ();
+ else
+ {
+ thread->threadid = pthread_pool_get_np ();
+ if (thread->threadid != l4_nilthread)
+ return 0;
+
+ return EAGAIN;
+ }
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/pt-thread-dealloc.c b/libpthread/sysdeps/l4/pt-thread-dealloc.c
new file mode 100644
index 00000000..c09e4860
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-thread-dealloc.c
@@ -0,0 +1,32 @@
+/* Deallocate the kernel thread resources. L4 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 <l4.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)
+{
+}
diff --git a/libpthread/sysdeps/l4/pt-thread-halt.c b/libpthread/sysdeps/l4/pt-thread-halt.c
new file mode 100644
index 00000000..aa2bf43d
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-thread-halt.c
@@ -0,0 +1,45 @@
+/* Deallocate the kernel thread resources. L4version.
+ Copyright (C) 2000, 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
+ 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 <pt-internal.h>
+
+/* Deallocate the kernel thread resources associated with THREAD. */
+void
+__pthread_thread_halt (struct __pthread *thread, int need_dealloc)
+{
+ l4_thread_id_t tid = thread->threadid;
+
+ if (need_dealloc)
+ __pthread_dealloc (thread);
+
+ /* There is potential race here: once if TID is the current thread,
+ then once we add TID to the pool, someone can reallocate it
+ before we call stop. However, to start the thread, the caller
+ atomically starts and sets the sp and ip, thus, if the stop has
+ not yet executed at that point, it won't. */
+
+ if (tid != l4_myself ())
+ l4_stop (tid);
+ pthread_pool_add_np (tid);
+ if (tid == l4_myself ())
+ l4_stop (tid);
+}
diff --git a/libpthread/sysdeps/l4/pt-thread-start.c b/libpthread/sysdeps/l4/pt-thread-start.c
new file mode 100644
index 00000000..144c58bb
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-thread-start.c
@@ -0,0 +1,40 @@
+/* Start thread. L4 version.
+ Copyright (C) 2003, 2004, 2007 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 <pt-internal.h>
+
+/* Start THREAD. Get the kernel thread scheduled and running. */
+int
+__pthread_thread_start (struct __pthread *thread)
+{
+ if (__pthread_num_threads == 1)
+ /* The main thread is already running of course. */
+ {
+ assert (__pthread_total == 1);
+ assert (l4_is_thread_equal (l4_myself (), thread->threadid));
+ }
+ else
+ l4_start_sp_ip (thread->threadid, (l4_word_t) thread->mcontext.sp,
+ (l4_word_t) thread->mcontext.pc);
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/pt-timedblock.c b/libpthread/sysdeps/l4/pt-timedblock.c
new file mode 100644
index 00000000..ce7972bd
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-timedblock.c
@@ -0,0 +1,35 @@
+/* Block a thread with a timeout. L4 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 <time.h>
+#include <sys/time.h>
+
+#include <pt-internal.h>
+
+/* Block THREAD. */
+error_t
+__pthread_timedblock (struct __pthread *thread,
+ const struct timespec *abstime)
+{
+#warning Need gettimeofday to implement properly.
+ __pthread_block (thread);
+ return 0;
+}
diff --git a/libpthread/sysdeps/l4/pt-wakeup.c b/libpthread/sysdeps/l4/pt-wakeup.c
new file mode 100644
index 00000000..de378465
--- /dev/null
+++ b/libpthread/sysdeps/l4/pt-wakeup.c
@@ -0,0 +1,54 @@
+/* Wakeup a thread. L4 version.
+ Copyright (C) 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
+ 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 <l4.h>
+
+#include <pt-internal.h>
+
+#include <hurd/stddef.h>
+
+/* Wakeup THREAD. */
+void
+__pthread_wakeup (struct __pthread *thread)
+{
+ debug (5, "%x.%x/%x waking %x.%x/%x",
+ l4_thread_no (l4_myself ()), l4_version (l4_myself ()), l4_myself (),
+ l4_thread_no (thread->threadid), l4_version (thread->threadid),
+ thread->threadid);
+
+ /* Signal the waiter. */
+ l4_msg_t msg;
+ l4_msg_clear (msg);
+ l4_msg_set_untyped_words (msg, 0);
+ l4_msg_load (msg);
+
+ l4_msg_tag_t tag = l4_send (thread->threadid);
+ if (l4_ipc_failed (tag))
+ {
+ int err = l4_error_code ();
+ debug (1, "%x.%x failed to wake %x.%x: %s (%d)",
+ l4_thread_no (l4_myself ()), l4_version (l4_myself ()),
+ l4_thread_no (thread->threadid), l4_version (thread->threadid),
+ l4_strerror (err), err);
+ }
+ else
+ debug (5, "%x.%x woke %x.%x",
+ l4_thread_no (l4_myself ()), l4_version (l4_myself ()),
+ l4_thread_no (thread->threadid), l4_version (thread->threadid));
+}