summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sysdeps/l4/hurd/ia32/pt-setup.c16
-rw-r--r--sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c6
-rw-r--r--sysdeps/l4/hurd/pt-setactivity-np.c2
-rw-r--r--sysdeps/l4/hurd/pt-sysdep.h16
-rw-r--r--sysdeps/l4/hurd/pt-thread-alloc.c53
-rw-r--r--sysdeps/l4/hurd/pt-thread-halt.c72
-rw-r--r--sysdeps/l4/hurd/pt-thread-start.c5
7 files changed, 114 insertions, 56 deletions
diff --git a/sysdeps/l4/hurd/ia32/pt-setup.c b/sysdeps/l4/hurd/ia32/pt-setup.c
index f5987797..cc2f0757 100644
--- a/sysdeps/l4/hurd/ia32/pt-setup.c
+++ b/sysdeps/l4/hurd/ia32/pt-setup.c
@@ -1,4 +1,4 @@
-/* Setup thread stack. Hurd/i386 version.
+/* Setup thread stack. Viengoos/i386 version.
Copyright (C) 2000, 2002, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -96,14 +96,16 @@ __pthread_setup (struct __pthread *thread,
if (__pthread_num_threads == 1)
return 0;
- assert (! ADDR_IS_VOID (thread->exception_page.addr));
+ assert (! ADDR_IS_VOID (thread->exception_area[0]));
- struct exception_page *exception_page
- = ADDR_TO_PTR (addr_extend (thread->exception_page.addr,
- 0, PAGESIZE_LOG2));
+ struct exception_page *exception_page = thread->exception_area_va;
- /* SP is set to the end of the exception page. */
- exception_page->exception_handler_sp = (uintptr_t) exception_page + PAGESIZE;
+ /* 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;
diff --git a/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c b/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c
index bb6ac2a5..37ef8215 100644
--- a/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c
+++ b/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c
@@ -124,13 +124,13 @@ signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid,
struct hurd_thread_exregs_out out;
error_t err;
- err = rm_thread_exregs (ADDR_VOID, thread->object.addr,
+ 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.addr));
+ ADDR_PRINTF (thread->object));
intr_sp = out.sp;
@@ -205,7 +205,7 @@ signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid,
in.sp = sp;
in.ip = (uintptr_t) &_signal_dispatch_entry;
- rm_thread_exregs (ADDR_VOID, thread->object.addr,
+ rm_thread_exregs (ADDR_VOID, thread->object,
HURD_EXREGS_SET_SP_IP
| HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC,
in, &out);
diff --git a/sysdeps/l4/hurd/pt-setactivity-np.c b/sysdeps/l4/hurd/pt-setactivity-np.c
index dbadb68f..f2f07233 100644
--- a/sysdeps/l4/hurd/pt-setactivity-np.c
+++ b/sysdeps/l4/hurd/pt-setactivity-np.c
@@ -31,7 +31,7 @@ pthread_setactivity_np (addr_t activity)
in.activity = activity;
struct hurd_thread_exregs_out out;
- int err = rm_thread_exregs (ADDR_VOID, self->object.addr,
+ int err = rm_thread_exregs (ADDR_VOID, self->object,
HURD_EXREGS_SET_ACTIVITY,
in, &out);
diff --git a/sysdeps/l4/hurd/pt-sysdep.h b/sysdeps/l4/hurd/pt-sysdep.h
index 5c66330e..08bcd143 100644
--- a/sysdeps/l4/hurd/pt-sysdep.h
+++ b/sysdeps/l4/hurd/pt-sysdep.h
@@ -1,5 +1,5 @@
-/* Internal defenitions for pthreads library.
- Copyright (C) 2000, 2002, 2005, 2007 Free Software Foundation, Inc.
+/* 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
@@ -30,10 +30,18 @@
/* 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 \
- struct storage object; \
+ addr_t object; \
l4_thread_id_t threadid; \
- struct storage exception_page; \
+ addr_t exception_area[EXCEPTION_AREA_SIZE / PAGESIZE]; \
+ void *exception_area_va; \
l4_word_t my_errno;
extern inline struct __pthread *
diff --git a/sysdeps/l4/hurd/pt-thread-alloc.c b/sysdeps/l4/hurd/pt-thread-alloc.c
index daa13dba..6941e10e 100644
--- a/sysdeps/l4/hurd/pt-thread-alloc.c
+++ b/sysdeps/l4/hurd/pt-thread-alloc.c
@@ -1,4 +1,4 @@
-/* Allocate kernel thread. Hurd/L4 version.
+/* Allocate kernel thread. Viengoos version.
Copyright (C) 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -23,6 +23,8 @@
#include <hurd/startup.h>
#include <hurd/storage.h>
+#include <hurd/as.h>
+#include <hurd/addr.h>
#include <pt-internal.h>
@@ -36,40 +38,57 @@ __pthread_thread_alloc (struct __pthread *thread)
/* The main thread is already running of course. */
if (__pthread_num_threads == 1)
{
- thread->object.addr = __hurd_startup_data->thread;
- /* If the main thread exits, then we wait. Thus, we don't need
- the shadow cap. */
- thread->object.cap = NULL;
+ thread->object = __hurd_startup_data->thread;
thread->threadid = l4_myself ();
return 0;
}
else
{
- struct storage storage;
+ addr_t exception_area = as_alloc (EXCEPTION_AREA_SIZE_LOG2, 1, true);
- /* We can't don't use mmap as when the exception thread starts
- running and it accesses its stack, it will fault, which we
- naturally cannot handle. */
- storage = storage_alloc (ADDR_VOID, cap_page,
- STORAGE_UNKNOWN, OBJECT_POLICY_DEFAULT,
- ADDR_VOID);
- if (ADDR_IS_VOID (storage.addr))
- return EAGAIN;
+ thread->exception_area_va
+ = ADDR_TO_PTR (addr_extend (exception_area,
+ 0, EXCEPTION_AREA_SIZE_LOG2));
- thread->exception_page = storage;
+ 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_slot_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))
{
- storage_free (thread->exception_page.addr, false);
+ 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;
+ thread->object = storage.addr;
}
return 0;
diff --git a/sysdeps/l4/hurd/pt-thread-halt.c b/sysdeps/l4/hurd/pt-thread-halt.c
index 1e9a8ee6..98fefaab 100644
--- a/sysdeps/l4/hurd/pt-thread-halt.c
+++ b/sysdeps/l4/hurd/pt-thread-halt.c
@@ -1,5 +1,5 @@
-/* Deallocate the kernel thread resources. L4/Hurd version.
- Copyright (C) 2007 Software Foundation, Inc.
+/* 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
@@ -23,47 +23,75 @@
#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. */
-static struct storage saved_object;
+ss_mutex_t saved_object_lock;
+static addr_t saved_object;
void
__pthread_thread_halt (struct __pthread *thread, int need_dealloc)
{
- struct storage exception_page = thread->exception_page;
- thread->exception_page.addr = ADDR_VOID;
+ /* We may deallocate THREAD. First save any data we need. */
- struct storage object = thread->object;
+ 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);
- if (! ADDR_IS_VOID (saved_object.addr))
+ /* 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 ++)
{
- storage_free (saved_object.addr, false);
- saved_object.cap->type = cap_void;
- saved_object.addr = ADDR_VOID;
+ assert (! ADDR_IS_VOID (exception_area[i]));
+ storage_free (exception_area[i], false);
}
- /* Free the exception page. */
- assert (! ADDR_IS_VOID (exception_page.addr));
- exception_page_cleanup (ADDR_TO_PTR (addr_extend (exception_page.addr,
- 0, PAGESIZE_LOG2)));
- storage_free (exception_page.addr, 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. Thus, we add ourself to the pool of
- available objects. */
- saved_object = object;
- else
+ middle. That's no good. We set SAVED_OBJECT to our thread
+ object and the next thread in will free us. */
{
- storage_free (object.addr, false);
- object.cap->type = cap_void;
+ ss_mutex_lock (&saved_object_lock);
+ saved_object = object;
+ ss_mutex_unlock (&saved_object_lock);
}
+ else
+ storage_free (object, false);
if (tid == l4_myself ())
{
@@ -72,5 +100,5 @@ __pthread_thread_halt (struct __pthread *thread, int need_dealloc)
l4_thread_no (l4_myself ()), l4_version (l4_myself ()));
}
else
- thread_stop (object.addr);
+ thread_stop (object);
}
diff --git a/sysdeps/l4/hurd/pt-thread-start.c b/sysdeps/l4/hurd/pt-thread-start.c
index 131f59d6..9db399ce 100644
--- a/sysdeps/l4/hurd/pt-thread-start.c
+++ b/sysdeps/l4/hurd/pt-thread-start.c
@@ -48,13 +48,14 @@ __pthread_thread_start (struct __pthread *thread)
in.activity = ADDR_VOID;
- in.exception_page = thread->exception_page.addr;
+ 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.addr,
+ err = rm_thread_exregs (ADDR_VOID, thread->object,
HURD_EXREGS_SET_ASPACE
| HURD_EXREGS_SET_ACTIVITY
| HURD_EXREGS_SET_EXCEPTION_PAGE