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:
Ingo Weinhold
2011-06-12 00:00:23 +00:00
parent ccd31b93f1
commit 24df65921b
235 changed files with 14975 additions and 6594 deletions
@@ -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)
+43
View File
@@ -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 */
+31 -10
View File
@@ -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,
+12 -11
View File
@@ -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 */
-1
View File
@@ -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()
+9 -3
View File
@@ -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;
};
+50
View File
@@ -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 */