summaryrefslogtreecommitdiff
path: root/libpthread
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2009-02-13 04:24:42 +0100
committerNeal H. Walfield <neal@gnu.org>2009-02-13 04:24:57 +0100
commit39e1f97996d9f5d7a1f11d0bcc53f98b37e7ffa7 (patch)
treee116cc46e03fb30debe18ea5d2d8c2257ccaa584 /libpthread
parentba024094f5fc4cd55c922990a9b2eb96af52afb1 (diff)
Almost the status quo.
Diffstat (limited to 'libpthread')
-rw-r--r--libpthread/Makefile.am1
-rw-r--r--libpthread/signal/kill.c6
-rw-r--r--libpthread/signal/pt-kill-siginfo-np.c3
-rw-r--r--libpthread/sysdeps/viengoos/ia32/pt-setup.c36
-rw-r--r--libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c333
-rw-r--r--libpthread/sysdeps/viengoos/pt-docancel.c20
-rw-r--r--libpthread/sysdeps/viengoos/pt-sysdep.c18
-rw-r--r--libpthread/sysdeps/viengoos/pt-sysdep.h8
-rw-r--r--libpthread/sysdeps/viengoos/pt-thread-alloc.c13
-rw-r--r--libpthread/sysdeps/viengoos/pt-thread-halt.c5
-rw-r--r--libpthread/sysdeps/viengoos/pt-thread-start.c5
-rw-r--r--libpthread/sysdeps/viengoos/sig-sysdep.h4
-rw-r--r--libpthread/sysdeps/viengoos/x86_64/pt-setup.c46
-rw-r--r--libpthread/sysdeps/viengoos/x86_64/signal-dispatch-lowlevel.c33
14 files changed, 284 insertions, 247 deletions
diff --git a/libpthread/Makefile.am b/libpthread/Makefile.am
index e84d725..e73d8d6 100644
--- a/libpthread/Makefile.am
+++ b/libpthread/Makefile.am
@@ -138,7 +138,6 @@ libpthread_a_SOURCES = pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \
sem-post.c sem-unlink.c \
\
pt-setactivity-np.c \
- pt-hurd-utcb-np.c \
\
kill.c \
killpg.c \
diff --git a/libpthread/signal/kill.c b/libpthread/signal/kill.c
index c7780af..c281640 100644
--- a/libpthread/signal/kill.c
+++ b/libpthread/signal/kill.c
@@ -67,6 +67,12 @@ kill (pid_t pid, int signo)
current thread has blocked the signal, the correct thing to do is
to iterate over all the other threads and find on that hasn't
blocked it. */
+
+ extern int __pthread_num_threads;
+ if (__pthread_num_threads == 0)
+ panic ("signal %d received before pthread library is able to handle it",
+ signo);
+
return pthread_kill (pthread_self (), signo);
}
diff --git a/libpthread/signal/pt-kill-siginfo-np.c b/libpthread/signal/pt-kill-siginfo-np.c
index 9bdf6cc..35642c3 100644
--- a/libpthread/signal/pt-kill-siginfo-np.c
+++ b/libpthread/signal/pt-kill-siginfo-np.c
@@ -75,7 +75,8 @@ pthread_kill_siginfo_np (pthread_t tid, siginfo_t si)
|| (ss->stack.ss_flags & SS_DISABLE)
|| (ss->stack.ss_flags & SS_ONSTACK)))
/* We are sending a signal to ourself and we don't use an
- alternate stack. */
+ alternate stack. (Recall: SA_ONSTACK means use the alt
+ stack.) */
signal_dispatch (ss, &si);
else
signal_dispatch_lowlevel (ss, tid, si);
diff --git a/libpthread/sysdeps/viengoos/ia32/pt-setup.c b/libpthread/sysdeps/viengoos/ia32/pt-setup.c
index 5604d11..46e031a 100644
--- a/libpthread/sysdeps/viengoos/ia32/pt-setup.c
+++ b/libpthread/sysdeps/viengoos/ia32/pt-setup.c
@@ -17,8 +17,6 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <l4.h>
-
#include <pt-internal.h>
/* The stack layout used on the i386 is:
@@ -35,7 +33,7 @@
We do the following: setup the stack to return to the entry routine.
-
+ On x86-64, it's similar expect the first argument is stored in RDI.
*/
/* The stack contains:
@@ -46,15 +44,22 @@
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");
+__asm__ (".globl _pthread_entry_point, __pthread_entry_point\n\t"
+ "_pthread_entry_point:\n\t"
+ "__pthread_entry_point:\n\t"
+ /* Clear the flags. */
+ "push $0\n\t"
+ "popf\n\t"
+#ifdef __x86_64
+ /* The arguments belong in RDI and RSI, not on the stack. */
+ "popq %rdi\n\t"
+ "popq %rsi\n\t"
+ /* Clear the frame pointer. */
+ "xor %rbp, %rbp\n\t"
+#else
+ "xor %ebp, %ebp\n\t"
+#endif
+ "ret\n\t");
/* 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.
@@ -76,10 +81,17 @@ stack_setup (struct __pthread *thread,
if (start_routine)
{
/* Set up call frame. */
+#ifdef __x86_64
+ *--top = 0; /* Fake return address. */
+ *--top = (uintptr_t) entry_point;
+ *--top = (uintptr_t) arg; /* Argument to START_ROUTINE. */
+ *--top = (uintptr_t) start_routine;
+#else
*--top = (uintptr_t) arg; /* Argument to START_ROUTINE. */
*--top = (uintptr_t) start_routine;
*--top = 0; /* Fake return address. */
*--top = (uintptr_t) entry_point;
+#endif
}
/* We need 4 pages of stack to avoid faulting before we have set up
diff --git a/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c b/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c
index 791b654..5f235de 100644
--- a/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c
+++ b/libpthread/sysdeps/viengoos/ia32/signal-dispatch-lowlevel.c
@@ -25,79 +25,172 @@
#include <pthread.h>
#include <stdint.h>
#include <atomic.h>
+#include <string.h>
+
+#ifdef __x86_64
+# define WS "8"
+#else
+# define WS "4"
+#endif
+
+#ifdef __x86_64
+# define R(reg) "%r" #reg
+#else
+# define R(reg) "%e" #reg
+#endif
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");
+/* Stack layout:
+
+ x86 x86-64
+ 7 13 rflags
+ 6 12 dx
+ 5 11 cx
+ 4 10 ax
+ 3 9 interrupted context's sp - WS (Note: *(intr_sp - WS) = intr_ip)
+ 2 8 &ss->stack.ss_flags (or NULL, if not on an alternative stack)
+ 7 r11 -.
+ 6 r10 \
+ 5 r9 x86-64
+ 4 r8 only
+ 3 rdi /
+ 2 rsi -'
+ 1 1 &si
+ 0 0 ss ._
+ |\
+ entry sp
+
+ */
+__asm__ (".globl _signal_dispatch_entry\n\t"
+ "_signal_dispatch_entry:\n\t"
+
+ /* Save the callee saved registers that we use (when we
+ return, we need to fully restore the register state to its
+ interrupted context--we may have forced a remote thread
+ into this function). */
+#ifdef __x86_64
+ "mov %rsi, 2*"WS"(%rsp)\n\t"
+ "mov %rdi, 3*"WS"(%rsp)\n\t"
+ "mov %r8, 4*"WS"(%rsp)\n\t"
+ "mov %r9, 5*"WS"(%rsp)\n\t"
+ "mov %r10, 6*"WS"(%rsp)\n\t"
+ "mov %r11, 7*"WS"(%rsp)\n\t"
+ /* Skip 8 and 9. */
+ "mov "R(ax)", 10*"WS"("R(sp)")\n\t"
+ "mov "R(cx)", 11*"WS"("R(sp)")\n\t"
+ "mov "R(dx)", 12*"WS"("R(sp)")\n\t"
+ "pushf\n\t"
+ "pop %rcx\n\t"
+ "mov %rcx, 13*"WS"("R(sp)")\n\t"
+#else
+ "mov "R(ax)", 4*"WS"("R(sp)")\n\t"
+ "mov "R(cx)", 5*"WS"("R(sp)")\n\t"
+ "mov "R(dx)", 6*"WS"("R(sp)")\n\t"
+ "pushf\n\t"
+ "pop %ecx\n\t"
+ "mov %ecx, 7*"WS"("R(sp)")\n\t"
+#endif
+
+ /* On x86-64, the first two arguments are passed in
+ registers. On x86, on the stack. */
+#ifdef __x86_64
+ "pop %rdi\n\t"
+ "pop %rsi\n\t"
+#endif
+
+ "cld\n\t"
+ "call signal_dispatch\n\t"
+
+#ifndef __x86_64
+ /* Fix up the stack. */
+ "add $(2*"WS"), %esp"
+#endif
+
+ /* Restore the registers in the first save area. */
+#ifdef __x86_64
+ "pop %rsi\n\t"
+ "pop %rdi\n\t"
+ "pop %r8\n\t"
+ "pop %r9\n\t"
+ "pop %r10\n\t"
+ "pop %r11\n\t"
+#endif
+
+ /* Set cx to the pointer to the sigaltstack flags. */
+ "pop "R(cx)"\n\t"
+ /* Set dx to the interrupted context's sp. */
+ "pop "R(dx)"\n\t"
+
+ "and "R(cx)", "R(cx)"\n\t"
+ "jz after_move\n\t"
+
+ /* We need to move the remaining state to the interrupted
+ stack. */
+
+ /* Make some space on that stack (which may be this stack!). */
+ "sub $(4*"WS"), "R(dx)"\n\t"
+
+ /* Move the saved registers to the user stack. */
+ /* ax. */
+ "pop 0*"WS"("R(dx)")\n\t"
+ /* cx. */
+ "pop 1*"WS"("R(dx)")\n\t"
+ /* dx. */
+ "pop 2*"WS"("R(dx)")\n\t"
+ /* Flags. */
+ "pop 3*"WS"("R(dx)")\n\t"
+
+
+ /* Restore the interrupted context's sp - 5 * WS (the four
+ saved registers above and the interrupted context's
+ IP). */
+ "mov "R(dx)", "R(sp)"\n\t"
+
+ /* Clear the SA_ONSTACK flag. */
+ "lock; and $~1, 0("R(cx)")\n\t"
+
+ "after_move:\n\t"
+ /* Restore the flag register, the scratch regs and the
+ original sp and ip. */
+ "pop "R(ax)"\n\t"
+ "pop "R(cx)"\n\t"
+ "pop "R(dx)"\n\t"
+ "popf\n\t"
+ "ret\n\t");
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");
+/* x86-64:
+
+ - 0(%rsp) is the return address
+ - %rdi is the sp to load
+
+ ia32:
+
+ - 0(%esp) is the return address
+ - 4(%esp) is the sp to load
+
+ We need to move the return IP to *(original sp). */
+__asm__ (".globl _signal_dispatch_entry_self\n\t"
+ "_signal_dispatch_entry_self:\n\t"
+
+#ifdef __x86_64
+ /* Save the current SP. */
+ "mov %rsp, 9*"WS"(%rdi)\n\t"
+ /* sp = new sp. */
+ "mov %rdi, %rsp\n\t"
+#else
+ /* eax, ecx and edx are caller saved. */
+
+ /* Save the current SP. */
+ "mov 4(%esp), %eax\n\t"
+ "mov %esp, 3*"WS"(%eax)\n\t"
+
+ /* sp = new sp. */
+ "mov %eax, %esp\n\t"
+#endif
+
+ "jmp _signal_dispatch_entry\n\t");
+
void
signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid,
@@ -109,16 +202,17 @@ signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid,
bool self = tid == pthread_self ();
- uintptr_t intr_sp;
+ bool altstack = (ss->actions[si.si_signo - 1].sa_flags & SA_ONSTACK)
+ && !(ss->stack.ss_flags & SS_DISABLE)
+ && !(ss->stack.ss_flags & SS_ONSTACK);
- if (self)
- {
- /* The return address is 4 bytes offset from the start of the
- stack frame. */
- intr_sp = (uintptr_t) __builtin_frame_address (0) + 4;
- assert (* (void **) intr_sp == __builtin_return_address (0));
- }
- else
+ if (self && ! altstack)
+ return signal_dispatch (ss, &si);
+
+ uintptr_t intr_sp = 0;
+ uintptr_t intr_ip = 0;
+ if (! self)
+ /* Suspend the thread and get its current stack. */
{
struct vg_thread_exregs_in in;
memset (&in, 0, sizeof (in));
@@ -126,91 +220,86 @@ signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid,
error_t err;
err = vg_thread_exregs (VG_ADDR_VOID, thread->object,
- VG_EXREGS_STOP | VG_EXREGS_ABORT_IPC
+ VG_EXREGS_STOP
| VG_EXREGS_GET_REGS,
- in, VG_ADDR_VOID, VG_ADDR_VOID, VG_ADDR_VOID, VG_ADDR_VOID,
+ in, VG_ADDR_VOID, VG_ADDR_VOID,
+ VG_ADDR_VOID, VG_ADDR_VOID,
&out, NULL, NULL, NULL, NULL);
if (err)
panic ("Failed to modify thread " VG_ADDR_FMT,
VG_ADDR_PRINTF (thread->object));
intr_sp = out.sp;
-
- /* Push the ip on the user stack. */
- intr_sp -= 4;
- * (uintptr_t *) intr_sp = out.ip;
+ intr_ip = 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
+ uintptr_t *sp;
+ if (altstack)
{
/* The stack grows down. */
- sp = (uintptr_t) ss->stack.ss_sp + ss->stack.ss_size;
+ sp = (uintptr_t *) ((void *) ss->stack.ss_sp + ss->stack.ss_size);
/* We know intimately that SS_ONSTACK is the least significant
bit. */
- assert (SS_ONSTACK == 1);
+ build_assert (SS_ONSTACK == 1);
atomic_bit_set (&ss->stack.ss_flags, 0);
+ }
+ else
+ {
+ assert (! self);
- altstack = true;
+ sp = (uintptr_t *) intr_sp;
+ /* Allocate space for the interrupted context's IP. */
+ sp --;
}
/* 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. */
+ /* Allocate save area 1. */
sp -= 4;
- * (uintptr_t *) sp = intr_sp;
- /* Address of the ss_flags. */
- sp -= 4;
+ /* The interrupted context's sp - WS. (In the case where INTR_SP is
+ NULL, i.e., when we are dealing with a self signal on an
+ alternate stack, we will fix it signal_dispatch_entry_self.) */
+ * -- sp = intr_sp - sizeof (uintptr_t);
+
+ /* The address of the ss_flags. */
if (altstack)
- * (uintptr_t *) sp = (uintptr_t) &ss->stack.ss_flags;
+ * -- sp = (uintptr_t) &ss->stack.ss_flags;
else
- * (uintptr_t *) sp = 0;
+ * -- sp = 0;
- /* Push the parameters to signal_dispatch. */
+ /* Allocate save area 2. */
+#ifdef __x86_64
+ sp -= 6;
+#endif
- /* signal info structure. */
- sp -= 4;
- * (uintptr_t *) sp = (uintptr_t) sip;
+ /* A pointer to the siginfo structure. */
+ * -- sp = (uintptr_t) &si;
/* The ss. */
- sp -= 4;
- * (uintptr_t *) sp = (uintptr_t) ss;
+ * -- sp = (uintptr_t) ss;
pthread_mutex_transfer_np (&ss->lock, tid);
if (self)
- ((void (*) (uintptr_t)) &_signal_dispatch_entry_self) ((uintptr_t) sp);
+ ((void (*) (uintptr_t *)) &_signal_dispatch_entry_self) (sp);
else
{
+ /* Set INTR_SP[-1] to the interrupted context's ip. */
+ ((uintptr_t *) intr_sp)[-1] = intr_ip;
+
struct vg_thread_exregs_in in;
struct vg_thread_exregs_out out;
- in.sp = sp;
+ in.sp = (uintptr_t) sp;
in.ip = (uintptr_t) &_signal_dispatch_entry;
vg_thread_exregs (VG_ADDR_VOID, thread->object,
VG_EXREGS_SET_SP_IP
- | VG_EXREGS_START | VG_EXREGS_ABORT_IPC,
- in, VG_ADDR_VOID, VG_ADDR_VOID, VG_ADDR_VOID, VG_ADDR_VOID,
+ | VG_EXREGS_START,
+ in, VG_ADDR_VOID, VG_ADDR_VOID,
+ VG_ADDR_VOID, VG_ADDR_VOID,
&out, NULL, NULL, NULL, NULL);
}
}
diff --git a/libpthread/sysdeps/viengoos/pt-docancel.c b/libpthread/sysdeps/viengoos/pt-docancel.c
index e2693af..7548dca 100644
--- a/libpthread/sysdeps/viengoos/pt-docancel.c
+++ b/libpthread/sysdeps/viengoos/pt-docancel.c
@@ -36,13 +36,19 @@ __pthread_do_cancel (struct __pthread *p)
call_exit ();
else
{
-#ifdef USE_L4
- thread_start_sp_ip (p->object,
- p->mcontext.sp, (uintptr_t) call_exit);
-#else
-# warning Unimplemented on this platform.
- assert (0);
-#endif
+ struct vg_thread_exregs_in in;
+ struct vg_thread_exregs_out out;
+
+ in.sp = (uintptr_t) p->mcontext.sp;
+ in.ip = (uintptr_t) call_exit;
+
+ error_t err;
+ err = vg_thread_exregs (VG_ADDR_VOID, p->object,
+ VG_EXREGS_SET_SP_IP,
+ in, VG_ADDR_VOID, VG_ADDR_VOID,
+ VG_ADDR_VOID, VG_ADDR_VOID,
+ &out, NULL, NULL, NULL, NULL);
+ assert (err == 0);
}
return 0;
diff --git a/libpthread/sysdeps/viengoos/pt-sysdep.c b/libpthread/sysdeps/viengoos/pt-sysdep.c
index d4d6fed..782f034 100644
--- a/libpthread/sysdeps/viengoos/pt-sysdep.c
+++ b/libpthread/sysdeps/viengoos/pt-sysdep.c
@@ -59,12 +59,18 @@ init_routine (void (*entry) (void *), void *arg)
(void *(*)(void *)) entry, arg);
assert_perror (err);
- /* Switch stacks. */
-#ifdef USE_L4
- l4_start_sp_ip (l4_myself (), thread->mcontext.sp,
- thread->mcontext.pc);
+ /* Switch stacks and jump to THREAD->MCONTEXT.PC. */
+#ifdef __x86_64
+ uintptr_t sp = (uintptr_t) thread->mcontext.sp - sizeof (uintptr_t);
+ *(uintptr_t *) sp = thread->mcontext.pc;
+
+ asm ("mov %0, %%rsp\n\t"
+ "ret\n\t" :: "r" (sp));
#else
-# warning Not ported to this platform.
- assert (0);
+ /* There is nothing wrong with using vg_thread_start_sp_ip to
+ implement the above: it just means an extra kernel entry. */
+ err = vg_thread_start_sp_ip (thread->object, thread->mcontext.sp,
+ thread->mcontext.pc);
#endif
+ panic ("Failed to set new IP: %d.", err);
}
diff --git a/libpthread/sysdeps/viengoos/pt-sysdep.h b/libpthread/sysdeps/viengoos/pt-sysdep.h
index db89112..fad3407 100644
--- a/libpthread/sysdeps/viengoos/pt-sysdep.h
+++ b/libpthread/sysdeps/viengoos/pt-sysdep.h
@@ -49,11 +49,9 @@ extern inline struct __pthread *
__attribute__((__always_inline__))
_pthread_self (void)
{
-#if USE_L4
- return (struct __pthread *) l4_user_defined_handle ();
-#else
- assert (0);
-#endif
+ struct hurd_utcb *utcb = hurd_utcb ();
+ assert (utcb);
+ return utcb->pthread;
}
extern inline void
diff --git a/libpthread/sysdeps/viengoos/pt-thread-alloc.c b/libpthread/sysdeps/viengoos/pt-thread-alloc.c
index 266444f..6b432f7 100644
--- a/libpthread/sysdeps/viengoos/pt-thread-alloc.c
+++ b/libpthread/sysdeps/viengoos/pt-thread-alloc.c
@@ -47,17 +47,10 @@ __pthread_thread_alloc (struct __pthread *thread)
thread->object = __hurd_startup_data->thread;
thread->threadid = hurd_myself ();
-#ifdef USE_L4
- l4_set_user_defined_handle ((l4_word_t) thread);
-#else
- assert (0);
-#endif
-
/* Get the thread's UTCB and stash it. */
thread->utcb = hurd_utcb ();
- /* Override the utcb fetch function. */
- hurd_utcb = pthread_hurd_utcb_np;
- assert (thread->utcb == hurd_utcb ());
+
+ thread->utcb->pthread = thread;
}
else
{
@@ -79,6 +72,8 @@ __pthread_thread_alloc (struct __pthread *thread)
if (unlikely (err))
panic ("Failed to initialize thread's activation state: %d", err);
+ thread->utcb->pthread = thread;
+
err = vg_cap_copy (VG_ADDR_VOID,
thread->lock_message_buffer->receiver,
VG_ADDR (VG_MESSENGER_THREAD_SLOT,
diff --git a/libpthread/sysdeps/viengoos/pt-thread-halt.c b/libpthread/sysdeps/viengoos/pt-thread-halt.c
index ba9f2b0..1c1522a 100644
--- a/libpthread/sysdeps/viengoos/pt-thread-halt.c
+++ b/libpthread/sysdeps/viengoos/pt-thread-halt.c
@@ -38,7 +38,10 @@ __pthread_thread_halt (struct __pthread *thread)
if (thread == _pthread_self ())
{
while (1)
- vg_suspend ();
+ {
+ vg_suspend ();
+ assert (! "Failed to suspend self.");
+ }
}
else
{
diff --git a/libpthread/sysdeps/viengoos/pt-thread-start.c b/libpthread/sysdeps/viengoos/pt-thread-start.c
index 5a3867d..347d56c 100644
--- a/libpthread/sysdeps/viengoos/pt-thread-start.c
+++ b/libpthread/sysdeps/viengoos/pt-thread-start.c
@@ -49,14 +49,11 @@ __pthread_thread_start (struct __pthread *thread)
in.sp = (uintptr_t) thread->mcontext.sp;
in.ip = (uintptr_t) thread->mcontext.pc;
- in.user_handle = (uintptr_t) thread;
err = vg_thread_exregs (VG_ADDR_VOID, thread->object,
VG_EXREGS_SET_ASPACE
| VG_EXREGS_SET_ACTIVITY
| VG_EXREGS_SET_SP_IP
- | VG_EXREGS_SET_USER_HANDLE
- | VG_EXREGS_START
- | VG_EXREGS_ABORT_IPC,
+ | VG_EXREGS_START,
in, aspace, activity, VG_ADDR_VOID, VG_ADDR_VOID,
&out, NULL, NULL, NULL, NULL);
assert (err == 0);
diff --git a/libpthread/sysdeps/viengoos/sig-sysdep.h b/libpthread/sysdeps/viengoos/sig-sysdep.h
index c1cbe92..4f40463 100644
--- a/libpthread/sysdeps/viengoos/sig-sysdep.h
+++ b/libpthread/sysdeps/viengoos/sig-sysdep.h
@@ -73,7 +73,7 @@ utcb_state_restore (struct utcb *buffer)
#else
#warning Signal dispatch entry and exit unimplemented for this platform.
-#define SIGNAL_DISPATCH_ENTRY assert (0)
-#define SIGNAL_DISPATCH_EXIT assert (0)
+#define SIGNAL_DISPATCH_ENTRY do {} while (0)
+#define SIGNAL_DISPATCH_EXIT do {} while (0)
#endif
diff --git a/libpthread/sysdeps/viengoos/x86_64/pt-setup.c b/libpthread/sysdeps/viengoos/x86_64/pt-setup.c
index e6a2977..195650f 100644
--- a/libpthread/sysdeps/viengoos/x86_64/pt-setup.c
+++ b/libpthread/sysdeps/viengoos/x86_64/pt-setup.c
@@ -1,45 +1 @@
-/* Setup thread stack. Viengoos/x86_64 version.
- Copyright (C) 2000, 2002, 2008, 2009 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>
-
-/* 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 *))
-{
-# warning Not ported to this architecture.
- assert (0);
- return 0;
-}
-
-int
-__pthread_setup (struct __pthread *thread,
- void (*entry_point)(void *(*)(void *), void *),
- void *(*start_routine)(void *), void *arg)
-{
- thread->mcontext.pc = (void *) 0;
- thread->mcontext.sp = (void *) stack_setup (thread, start_routine, arg,
- entry_point);
- return 0;
-}
+#include "../ia32/pt-setup.c"
diff --git a/libpthread/sysdeps/viengoos/x86_64/signal-dispatch-lowlevel.c b/libpthread/sysdeps/viengoos/x86_64/signal-dispatch-lowlevel.c
index a196faf..f098599 100644
--- a/libpthread/sysdeps/viengoos/x86_64/signal-dispatch-lowlevel.c
+++ b/libpthread/sysdeps/viengoos/x86_64/signal-dispatch-lowlevel.c
@@ -1,32 +1 @@
-/* signal-dispatch-lowlevel.c - x86_64 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>
-
-void
-signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid,
- siginfo_t si)
-{
- assert (pthread_mutex_trylock (&ss->lock) == EBUSY);
-
-#warning Not ported to this architecture.
- assert (0);
-}
+#include "../ia32/signal-dispatch-lowlevel.c"