* For each userland team the kernel creates an area in the userland

address space that is fully locked and marked B_KERNEL_AREA. It can
  thus be accessed by the kernel without additional checks.
* For each userland thread we do create a user_thread structure in that
  area. The structure is accessible from userland via TLS, using the
  private get_user_thread() function.
* Introduced private userland functions [un]defer_signals(). They can be
  used to cheaply disable/re-enable signal delivery. They use the
  user_thread::defer_signals/pending_signals fields which are
  checked/updated by the kernel.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25451 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-05-11 16:25:35 +00:00
parent 58148e2e02
commit d648afb8d7
10 changed files with 256 additions and 13 deletions
@@ -32,7 +32,8 @@
#define USER_SIZE (KERNEL_BASE - 0x10000)
#define USER_TOP (USER_BASE + USER_SIZE)
#define USER_STACK_REGION 0x70000000
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
#define KERNEL_USER_DATA_BASE 0x6fff0000
#define USER_STACK_REGION 0x70000000
#define USER_STACK_REGION_SIZE (USER_TOP - USER_STACK_REGION)
#endif /* _KERNEL_ARCH_x86_KERNEL_H */
+3
View File
@@ -47,6 +47,9 @@ status_t start_watching_team(team_id team, void (*hook)(team_id, void *),
status_t stop_watching_team(team_id team, void (*hook)(team_id, void *),
void *data);
struct user_thread* team_allocate_user_thread(struct team* team);
void team_free_user_thread(struct thread* thread);
// used in syscalls.c
thread_id _user_load_image(int32 argCount, const char **args, int32 envCount,
const char **env, int32 priority, uint32 flags,
+17 -3
View File
@@ -71,6 +71,7 @@ enum {
struct image; // defined in image.c
struct realtime_sem_context; // defined in realtime_sem.cpp
struct select_info;
struct user_thread; // defined in libroot/user_thread.h
struct death_entry {
struct list_link link;
@@ -165,6 +166,11 @@ struct team_dead_children : team_job_control_children {
#endif // __cplusplus
struct free_user_thread {
struct free_user_thread* next;
struct user_thread* thread;
};
struct team {
struct team *next; // next in hash
struct team *siblings_next;
@@ -199,6 +205,12 @@ struct team {
struct list watcher_list;
struct arch_team arch_info;
addr_t user_data;
area_id user_data_area;
size_t user_data_size;
size_t used_user_data;
struct free_user_thread* free_user_threads;
struct team_debug_info debug_info;
bigtime_t dead_threads_kernel_time;
@@ -239,13 +251,15 @@ struct thread {
size_t signal_stack_size;
bool signal_stack_enabled;
bool in_kernel;
bool was_yielded;
struct user_thread* user_thread;
struct {
uint8 parameters[32];
} syscall_restart;
bool in_kernel;
bool was_yielded;
struct {
status_t status; // current wait status
uint32 flags; // interrupable flags
+1
View File
@@ -17,6 +17,7 @@ enum {
TLS_THREAD_ID_SLOT,
TLS_ERRNO_SLOT,
TLS_ON_EXIT_THREAD_SLOT,
TLS_USER_THREAD_SLOT,
// Note: these entries can safely be changed between
// releases; 3rd party code always calls tls_allocate()
+48
View File
@@ -0,0 +1,48 @@
/*
* Copyright 2008, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _LIBROOT_USER_THREAD_H
#define _LIBROOT_USER_THREAD_H
#include <OS.h>
#include <TLS.h>
#include <tls.h> /* kernel header */
struct user_thread {
int32 defer_signals; // counter; 0 == signals allowed
uint32 pending_signals; // signals that are pending, when
// signals are deferred
status_t wait_status;
};
static inline user_thread*
get_user_thread()
{
return (user_thread*)tls_get(TLS_USER_THREAD_SLOT);
}
static void inline
defer_signals()
{
get_user_thread()->defer_signals++;
}
static void inline
undefer_signals()
{
user_thread* thread = get_user_thread();
if (--thread->defer_signals == 0 && thread->pending_signals != 0) {
// signals shall no longer be deferred -- call a dummy syscall to handle
// the pending ones
is_computer_on();
}
}
#endif /* _LIBROOT_USER_THREAD_H */