summaryrefslogtreecommitdiff
path: root/sysdeps/l4
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2008-05-29 20:45:48 +0000
committerThomas Schwinge <tschwinge@gnu.org>2009-04-07 23:16:14 +0200
commitba1501075d81ce42c88707021eb8c2befa0fe4a4 (patch)
tree9e96100971636a5604027cc28be766389558e35d /sysdeps/l4
parent9acc87073cfc18eaa2ea5b46fa81f239d6b32b31 (diff)
libhurd-mm/
2008-05-29 Neal H. Walfield <neal@gnu.org> * exceptions.c (exception_handler_activated): Assume the fault is on the stack if it is one page above or three pages below the stack pointer. (exception_handler_init): Allocate an area of address space EXCEPTION_STACK_SIZE bytes larges. Fill it with pages. Set the first page as the thread's exception page and the top of the area minus one word as the stack pointer. Set the last word to the location of the exception page. * ia32-exception-entry.S: Include <hurd/exceptions.h>. (PAGESIZE): Don't define. (_exception_handler_entry): Rewrite to not assume that the exception page is at the start of the page in which the stack pointer is, but at the location stored in the word after the bottom of the stack. * Makefile.am (libhurd_mm_a_CCASFLAGS): New variable. * pager.c (ensure_stack): Change SPACE to be EXCEPTION_STACK_SIZE - PAGESIZE bytes large. Write to each page. libpthread/ 2008-05-29 Neal H. Walfield <neal@gnu.org> * sysdeps/l4/hurd/pt-sysdep.h Include <hurd/exceptions.h>. (EXCEPTION_AREA_SIZE): Define. (EXCEPTION_AREA_SIZE_LOG2): Likewise. (EXCEPTION_PAGE): Likewise. (PTHREAD_SYSDEP_MEMBERS): Change object's type to an addr_t. Update users. Remove field exception_page, replace with exception_area. Add field exception_area_va. * sysdeps/l4/hurd/pt-thread-alloc.c: Include <hurd/as.h> and <hurd/addr.h>. (__pthread_thread_alloc): Allocate EXCEPTION_AREA_SIZE bytes of address space. Save it in THREAD->EXCEPTION_AREA_VA. Allocate a page for each page in that area. Save them in THREAD->EXCEPTION_AREA. * sysdeps/l4/hurd/ia32/pt-setup.c (__pthread_setup): Set EXCEPTION_PAGE->EXCEPTION_HANDLER_SP to the end of EXCEPTION_PAGE->EXCEPTION_HANDLER_SP minus one word, in which we save the address of the exception page. * sysdeps/l4/hurd/pt-thread-start.c (__pthread_thread_start): Set IN.EXCEPTION_PAGE to the first page in THREAD->EXCEPTION_AREA_VA. * sysdeps/l4/hurd/pt-thread-halt.c: Include <hurd/mutex.h>, <hurd/as.h> and <hurd/addr.h>. (saved_object_lock): New variable. (__pthread_thread_halt): Lock SAVED_OBJECT_LOCK when accessing SAVED_OBJECT. Free the address space used by the exception area (THREAD->EXCEPTION_AREA_VA) and its associated storage (THREAD->EXCEPTION_AREA). hurd/ 2008-05-29 Neal H. Walfield <neal@gnu.org> * exceptions.h: Include <hurd/stddef.h>. [ASM]: Only define relevant macros. (EXCEPTION_STACK_SIZE_LOG2): Define. (EXCEPTION_STACK_SIZE): Define. * stddef.h [ASM]: Only define relevant macros. (PAGESIZE): Don't append C type specifier. (PAGESIZE_LOG2): Likewise. viengoos/ 2008-05-29 Neal H. Walfield <neal@gnu.org> * as.c: Include <hurd/exceptions.h>. (ensure_stack): Change SPACE to be EXCEPTION_STACK_SIZE - PAGESIZE bytes large. Write to each page. * cap-lookup.c: Include <hurd/exceptions.h>. (ensure_stack): Change SPACE to be EXCEPTION_STACK_SIZE - PAGESIZE bytes large. Write to each page. * zalloc.c (ZONE_SIZE): Add suffix the 1 with a U type qualifier. (ZONES): Include one less zone.
Diffstat (limited to 'sysdeps/l4')
-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