* 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:
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user