summaryrefslogtreecommitdiff
path: root/sysdeps/l4/hurd/pt-thread-alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/l4/hurd/pt-thread-alloc.c')
-rw-r--r--sysdeps/l4/hurd/pt-thread-alloc.c53
1 files changed, 36 insertions, 17 deletions
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;