Merged signals-merge branch into trunk with the following changes:
* Reorganized the kernel locking related to threads and teams. * We now discriminate correctly between process and thread signals. Signal handlers have been moved to teams. Fixes #5679. * Implemented real-time signal support, including signal queuing, SA_SIGINFO support, sigqueue(), sigwaitinfo(), sigtimedwait(), waitid(), and the addition of the real-time signal range. Closes #1935 and #2695. * Gave SIGBUS a separate signal number. Fixes #6704. * Implemented <time.h> clock and timer support, and fixed/completed alarm() and [set]itimer(). Closes #5682. * Implemented support for thread cancellation. Closes #5686. * Moved send_signal() from <signal.h> to <OS.h>. Fixes #7554. * Lots over smaller more or less related changes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42116 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -12,6 +12,10 @@
|
||||
#define COMMPAGE_ENTRY_X86_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
|
||||
#define COMMPAGE_ENTRY_X86_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1)
|
||||
#define COMMPAGE_ENTRY_X86_MEMSET (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 2)
|
||||
#define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER \
|
||||
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3)
|
||||
#define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS \
|
||||
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 4)
|
||||
|
||||
#define ARCH_USER_COMMPAGE_ADDR (0xffff0000)
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYSTEM_SIGNAL_DEFS_H
|
||||
#define _SYSTEM_SIGNAL_DEFS_H
|
||||
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
// The total number of signals a process may have queued at receivers at any
|
||||
// time.
|
||||
#define MAX_QUEUED_SIGNALS _POSIX_SIGQUEUE_MAX
|
||||
|
||||
// realtime signal number range
|
||||
#define SIGNAL_REALTIME_MIN 33
|
||||
#define SIGNAL_REALTIME_MAX 40
|
||||
|
||||
// greatest actually supported signal number
|
||||
#define MAX_SIGNAL_NUMBER SIGNAL_REALTIME_MAX
|
||||
|
||||
// additional send_signal_etc() flags
|
||||
#define SIGNAL_FLAG_QUEUING_REQUIRED (0x10000)
|
||||
// force signal queuing, i.e. fail instead of falling back to unqueued
|
||||
// signals, when queuing isn't possible
|
||||
#define SIGNAL_FLAG_SEND_TO_THREAD (0x20000)
|
||||
// interpret the the given ID as a thread_id rather than a team_id (syscall
|
||||
// use only)
|
||||
|
||||
// additional sigaction::sa_flags flag
|
||||
#define SA_BEOS_COMPATIBLE_HANDLER 0x80000000
|
||||
// BeOS compatible signal handler, i.e. the vregs argument is passed
|
||||
// per-value, not per-pointer
|
||||
|
||||
#define SIGNAL_TO_MASK(signal) ((sigset_t)1 << ((signal) - 1))
|
||||
#define SIGNAL_RANGE_TO_MASK(first, last) \
|
||||
((((SIGNAL_TO_MASK(last) - 1) << 1) | 1) & ~(SIGNAL_TO_MASK(first) - 1))
|
||||
// Note: The last mask computation looks that way to avoid an overflow for
|
||||
// last == 64.
|
||||
|
||||
#endif /* _SYSTEM_SIGNAL_DEFS_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010, Haiku Inc. All rights reserved.
|
||||
* Copyright 2004-2011, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYSTEM_SYSCALLS_H
|
||||
@@ -35,8 +35,10 @@ struct _sem_t;
|
||||
struct sembuf;
|
||||
union semun;
|
||||
struct sigaction;
|
||||
struct signal_frame_data;
|
||||
struct stat;
|
||||
struct system_profiler_parameters;
|
||||
struct user_timer_info;
|
||||
|
||||
struct disk_device_job_progress_info;
|
||||
struct partitionable_space_data;
|
||||
@@ -134,8 +136,8 @@ extern void __NO_RETURN _kern_exit_team(status_t returnValue);
|
||||
extern status_t _kern_kill_team(team_id team);
|
||||
extern team_id _kern_get_current_team();
|
||||
extern status_t _kern_wait_for_team(team_id team, status_t *_returnCode);
|
||||
extern thread_id _kern_wait_for_child(thread_id child, uint32 flags,
|
||||
int32 *_reason, status_t *_returnCode);
|
||||
extern pid_t _kern_wait_for_child(thread_id child, uint32 flags,
|
||||
siginfo_t* info);
|
||||
extern status_t _kern_exec(const char *path, const char* const* flatArgs,
|
||||
size_t flatArgsSize, int32 argCount, int32 envCount,
|
||||
mode_t umask);
|
||||
@@ -155,6 +157,8 @@ extern status_t _kern_set_thread_priority(thread_id thread,
|
||||
int32 newPriority);
|
||||
extern status_t _kern_kill_thread(thread_id thread);
|
||||
extern void _kern_exit_thread(status_t returnValue);
|
||||
extern status_t _kern_cancel_thread(thread_id threadID,
|
||||
void (*cancelFunction)(int));
|
||||
extern void _kern_thread_yield(void);
|
||||
extern status_t _kern_wait_for_thread(thread_id thread,
|
||||
status_t *_returnCode);
|
||||
@@ -163,7 +167,8 @@ extern status_t _kern_send_data(thread_id thread, int32 code,
|
||||
const void *buffer, size_t bufferSize);
|
||||
extern int32 _kern_receive_data(thread_id *_sender, void *buffer,
|
||||
size_t bufferSize);
|
||||
extern int64 _kern_restore_signal_frame();
|
||||
extern int64 _kern_restore_signal_frame(
|
||||
struct signal_frame_data* signalFrameData);
|
||||
|
||||
extern status_t _kern_get_thread_info(thread_id id, thread_info *info);
|
||||
extern status_t _kern_get_next_thread_info(team_id team, int32 *cookie,
|
||||
@@ -198,13 +203,14 @@ extern ssize_t _kern_getgroups(int groupCount, gid_t* groupList);
|
||||
extern status_t _kern_setgroups(int groupCount, const gid_t* groupList);
|
||||
|
||||
// signal functions
|
||||
extern status_t _kern_send_signal(pid_t tid, uint sig);
|
||||
extern status_t _kern_sigprocmask(int how, const sigset_t *set,
|
||||
extern status_t _kern_send_signal(int32 id, uint32 signal,
|
||||
const union sigval* userValue, uint32 flags);
|
||||
extern status_t _kern_set_signal_mask(int how, const sigset_t *set,
|
||||
sigset_t *oldSet);
|
||||
extern status_t _kern_sigaction(int sig, const struct sigaction *action,
|
||||
struct sigaction *oldAction);
|
||||
extern bigtime_t _kern_set_alarm(bigtime_t time, uint32 mode);
|
||||
extern status_t _kern_sigwait(const sigset_t *set, int *_signal);
|
||||
extern status_t _kern_sigwait(const sigset_t *set, siginfo_t *info,
|
||||
uint32 flags, bigtime_t timeout);
|
||||
extern status_t _kern_sigsuspend(const sigset_t *mask);
|
||||
extern status_t _kern_sigpending(sigset_t *set);
|
||||
extern status_t _kern_set_signal_stack(const stack_t *newStack,
|
||||
@@ -370,7 +376,7 @@ extern status_t _kern_stop_watching(dev_t device, ino_t node, port_id port,
|
||||
uint32 token);
|
||||
|
||||
// time functions
|
||||
extern status_t _kern_set_real_time_clock(uint32 time);
|
||||
extern status_t _kern_set_real_time_clock(bigtime_t time);
|
||||
extern status_t _kern_set_timezone(int32 timezoneOffset, const char *name,
|
||||
size_t nameLength);
|
||||
extern status_t _kern_get_timezone(int32 *_timezoneOffset, char *name,
|
||||
@@ -378,8 +384,23 @@ extern status_t _kern_get_timezone(int32 *_timezoneOffset, char *name,
|
||||
extern status_t _kern_set_real_time_clock_is_gmt(bool isGMT);
|
||||
extern status_t _kern_get_real_time_clock_is_gmt(bool *_isGMT);
|
||||
|
||||
extern status_t _kern_get_clock(clockid_t clockID, bigtime_t* _time);
|
||||
extern status_t _kern_set_clock(clockid_t clockID, bigtime_t time);
|
||||
|
||||
extern bigtime_t _kern_system_time();
|
||||
extern status_t _kern_snooze_etc(bigtime_t time, int timebase, int32 flags);
|
||||
extern status_t _kern_snooze_etc(bigtime_t time, int timebase, int32 flags,
|
||||
bigtime_t* _remainingTime);
|
||||
|
||||
extern int32 _kern_create_timer(clockid_t clockID, thread_id threadID,
|
||||
uint32 flags, const struct sigevent* event,
|
||||
const struct thread_creation_attributes*
|
||||
threadAttributes);
|
||||
extern status_t _kern_delete_timer(int32 timerID, thread_id threadID);
|
||||
extern status_t _kern_get_timer(int32 timerID, thread_id threadID,
|
||||
struct user_timer_info* info);
|
||||
extern status_t _kern_set_timer(int32 timerID, thread_id threadID,
|
||||
bigtime_t startTime, bigtime_t interval, uint32 flags,
|
||||
struct user_timer_info* oldInfo);
|
||||
|
||||
// area functions
|
||||
extern area_id _kern_create_area(const char *name, void **address,
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||
* Copyright 2008-2011, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYSTEM_THREAD_DEFS_H
|
||||
#define _SYSTEM_THREAD_DEFS_H
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
#define THREAD_RETURN_EXIT 0x1
|
||||
#define THREAD_RETURN_INTERRUPTED 0x2
|
||||
#define THREAD_STOPPED 0x3
|
||||
#define THREAD_CONTINUED 0x4
|
||||
|
||||
/** Size of the stack given to teams in user space */
|
||||
#define USER_STACK_GUARD_PAGES 4 // 16 kB
|
||||
#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024 \
|
||||
@@ -39,18 +37,21 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
#define THREAD_CREATION_FLAG_DEFER_SIGNALS 0x01
|
||||
// create the thread with signals deferred, i.e. with
|
||||
// user_thread::defer_signals set to 1
|
||||
|
||||
|
||||
struct thread_creation_attributes {
|
||||
int32 (*entry)(thread_func, void *);
|
||||
int32 (*entry)(void*, void*);
|
||||
const char* name;
|
||||
int32 priority;
|
||||
void* args1;
|
||||
void* args2;
|
||||
void* stack_address;
|
||||
size_t stack_size;
|
||||
|
||||
// when calling from kernel only
|
||||
team_id team;
|
||||
thread_id thread;
|
||||
pthread_t pthread;
|
||||
uint32 flags;
|
||||
};
|
||||
|
||||
#endif /* _SYSTEM_THREAD_DEFS_H */
|
||||
|
||||
@@ -19,7 +19,6 @@ enum {
|
||||
TLS_ERRNO_SLOT,
|
||||
TLS_ON_EXIT_THREAD_SLOT,
|
||||
TLS_USER_THREAD_SLOT,
|
||||
TLS_PTHREAD_SLOT,
|
||||
|
||||
// Note: these entries can safely be changed between
|
||||
// releases; 3rd party code always calls tls_allocate()
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||
* Copyright 2008-2011, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYSTEM_USER_THREAD_DEFS_H
|
||||
#define _SYSTEM_USER_THREAD_DEFS_H
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
struct user_thread {
|
||||
pthread_t pthread; // pthread pointer
|
||||
uint32 flags;
|
||||
status_t wait_status; // wait status for thread blocking
|
||||
int32 defer_signals; // counter; 0 == signals allowed
|
||||
uint32 pending_signals; // signals that are pending, when
|
||||
sigset_t pending_signals; // signals that are pending, when
|
||||
// signals are deferred
|
||||
status_t wait_status;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYSTEM_USER_TIMER_DEFS_H
|
||||
#define _SYSTEM_USER_TIMER_DEFS_H
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
#define CLOCK_PROCESS_USER_CPUTIME_ID ((clockid_t)-4)
|
||||
/* clock measuring the used user CPU time of the current process */
|
||||
|
||||
// limits
|
||||
#define MAX_USER_TIMERS_PER_TEAM _POSIX_TIMER_MAX
|
||||
// maximum numbers of user-defined user timers (timer_create())
|
||||
#define MAX_USER_TIMER_OVERRUN_COUNT INT_MAX
|
||||
// cap value of a timer's overrun counter
|
||||
|
||||
#if MAX_USER_TIMER_OVERRUN_COUNT < _POSIX_DELAYTIMER_MAX
|
||||
# error "MAX_USER_TIMER_OVERRUN_COUNT < _POSIX_DELAYTIMER_MAX"
|
||||
#endif
|
||||
|
||||
#define USER_TIMER_REAL_TIME_ID 0
|
||||
// predefined ID for the real time timer
|
||||
#define USER_TIMER_TEAM_TOTAL_TIME_ID 1
|
||||
// predefined ID for the team's total (kernel + user) time timer
|
||||
#define USER_TIMER_TEAM_USER_TIME_ID 2
|
||||
// predefined ID for the team's user time timer
|
||||
#define USER_TIMER_FIRST_USER_DEFINED_ID 3
|
||||
// first ID assigned to a user-defined timer (timer_create())
|
||||
|
||||
// _kern_create_user_timer() flag:
|
||||
#define USER_TIMER_SIGNAL_THREAD 0x01
|
||||
// send the signal to the thread instead of the team (valid only for thread
|
||||
// timers)
|
||||
|
||||
|
||||
struct user_timer_info {
|
||||
bigtime_t remaining_time;
|
||||
bigtime_t interval;
|
||||
uint32 overrun_count;
|
||||
};
|
||||
|
||||
|
||||
#endif /* _SYSTEM_USER_TIMER_DEFS_H */
|
||||
Reference in New Issue
Block a user