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:
@@ -37,12 +37,11 @@ void __init_heap_post_env(void);
|
||||
void __init_time(void);
|
||||
void __arch_init_time(struct real_time_data *data, bool setDefaults);
|
||||
bigtime_t __arch_get_system_time_offset(struct real_time_data *data);
|
||||
bigtime_t __get_system_time_offset();
|
||||
void __init_pwd_backend(void);
|
||||
void __reinit_pwd_backend_after_fork(void);
|
||||
void* __arch_get_caller(void);
|
||||
|
||||
void __init_pthread(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -11,6 +11,17 @@
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
// _pthread_thread::flags values
|
||||
#define THREAD_DETACHED 0x01
|
||||
#define THREAD_DEAD 0x02
|
||||
#define THREAD_CANCELED 0x04
|
||||
#define THREAD_CANCEL_ENABLED 0x08
|
||||
#define THREAD_CANCEL_ASYNCHRONOUS 0x10
|
||||
|
||||
|
||||
struct thread_creation_attributes;
|
||||
|
||||
// The public *_t types are only pointers to these structures
|
||||
// This way, we are completely free to change them, which might be
|
||||
// necessary in the future (not only due to the incomplete implementation
|
||||
@@ -55,9 +66,6 @@ typedef struct _pthread_thread {
|
||||
void *(*entry)(void*);
|
||||
void *entry_argument;
|
||||
void *exit_value;
|
||||
int cancel_state;
|
||||
int cancel_type;
|
||||
bool cancelled;
|
||||
struct pthread_key_data specific[PTHREAD_KEYS_MAX];
|
||||
struct __pthread_cleanup_handler *cleanup_handlers;
|
||||
} pthread_thread;
|
||||
@@ -69,7 +77,13 @@ extern "C" {
|
||||
|
||||
void __pthread_key_call_destructors(pthread_thread *thread);
|
||||
void __pthread_destroy_thread(void);
|
||||
pthread_thread *__allocate_pthread(void *data);
|
||||
pthread_thread *__allocate_pthread(void* (*entry)(void*), void *data);
|
||||
void __init_pthread(pthread_thread* thread, void* (*entry)(void*), void* data);
|
||||
status_t __pthread_init_creation_attributes(
|
||||
const pthread_attr_t* pthreadAttributes, pthread_t thread,
|
||||
status_t (*entryFunction)(void*, void*), void* argument1,
|
||||
void* argument2, const char* name,
|
||||
struct thread_creation_attributes* attributes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _LIBROOT_SIGNAL_PRIVATE_H
|
||||
#define _LIBROOT_SIGNAL_PRIVATE_H
|
||||
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <signal_defs.h>
|
||||
|
||||
|
||||
#define MAX_SIGNAL_NUMBER_BEOS 29
|
||||
|
||||
|
||||
typedef __haiku_int32 sigset_t_beos;
|
||||
|
||||
struct sigaction_beos {
|
||||
__sighandler_t sa_handler;
|
||||
sigset_t_beos sa_mask;
|
||||
int sa_flags;
|
||||
void* sa_userdata;
|
||||
};
|
||||
|
||||
|
||||
static inline sigset_t_beos
|
||||
to_beos_sigset(sigset_t set)
|
||||
{
|
||||
// restrict to BeOS signals
|
||||
sigset_t_beos beosSet = (sigset_t_beos)(set
|
||||
& SIGNAL_RANGE_TO_MASK(1, MAX_SIGNAL_NUMBER_BEOS));
|
||||
|
||||
// if SIGBUS is set, set SIGSEGV, since they have the same number in BeOS
|
||||
if ((set & SIGNAL_TO_MASK(SIGBUS)) != 0)
|
||||
beosSet |= SIGNAL_TO_MASK(SIGSEGV);
|
||||
|
||||
return beosSet;
|
||||
}
|
||||
|
||||
|
||||
static inline sigset_t
|
||||
from_beos_sigset(sigset_t_beos beosSet)
|
||||
{
|
||||
sigset_t set = beosSet;
|
||||
|
||||
// if SIGSEGV is set, set SIGBUS, since they have the same number in BeOS
|
||||
if ((set & SIGNAL_TO_MASK(SIGSEGV)) != 0)
|
||||
set |= SIGNAL_TO_MASK(SIGBUS);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
|
||||
__sighandler_t __signal_beos(int signal, __sighandler_t signalHandler);
|
||||
__sighandler_t __signal(int signal, __sighandler_t signalHandler);
|
||||
|
||||
int __sigaction_beos(int signal, const struct sigaction_beos* beosAction,
|
||||
struct sigaction_beos* beosOldAction);
|
||||
int __sigaction(int signal, const struct sigaction* action,
|
||||
struct sigaction* oldAction);
|
||||
|
||||
__sighandler_t __sigset_beos(int signal, __sighandler_t signalHandler);
|
||||
__sighandler_t __sigset(int signal, __sighandler_t signalHandler);
|
||||
|
||||
int __sigignore_beos(int signal);
|
||||
int __sigignore(int signal);
|
||||
|
||||
int __sighold_beos(int signal);
|
||||
int __sighold(int signal);
|
||||
|
||||
int __sigrelse_beos(int signal);
|
||||
int __sigrelse(int signal);
|
||||
|
||||
int __sigpause_beos(int signal);
|
||||
int __sigpause(int signal);
|
||||
|
||||
int __siginterrupt_beos(int signal, int flag);
|
||||
int __siginterrupt(int signal, int flag);
|
||||
|
||||
int __pthread_sigmask_beos(int how, const sigset_t_beos* beosSet,
|
||||
sigset_t_beos* beosOldSet);
|
||||
int __sigprocmask_beos(int how, const sigset_t_beos* beosSet,
|
||||
sigset_t_beos* beosOldSet);
|
||||
|
||||
int __pthread_sigmask(int how, const sigset_t* set, sigset_t* oldSet);
|
||||
int __sigprocmask(int how, const sigset_t* set, sigset_t* oldSet);
|
||||
|
||||
int __sigpending_beos(sigset_t_beos* beosSet);
|
||||
int __sigpending(sigset_t* set);
|
||||
|
||||
int __sigsuspend_beos(const sigset_t_beos* beosMask);
|
||||
int __sigsuspend(const sigset_t* mask);
|
||||
|
||||
int __sigwait_beos(const sigset_t_beos* beosSet, int* _signal);
|
||||
int __sigwait(const sigset_t* set, int* _signal);
|
||||
|
||||
int __sigemptyset_beos(sigset_t_beos* set);
|
||||
int __sigfillset_beos(sigset_t_beos* set);
|
||||
int __sigismember_beos(const sigset_t_beos* set, int signal);
|
||||
int __sigaddset_beos(sigset_t_beos* set, int signal);
|
||||
int __sigdelset_beos(sigset_t_beos* set, int signal);
|
||||
|
||||
int __sigemptyset(sigset_t* set);
|
||||
int __sigfillset(sigset_t* set);
|
||||
int __sigismember(const sigset_t* set, int signal);
|
||||
int __sigaddset(sigset_t* set, int signal);
|
||||
int __sigdelset(sigset_t* set, int signal);
|
||||
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
||||
#endif // _LIBROOT_SIGNAL_PRIVATE_H
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _LIBROOT_TIME_PRIVATE_H
|
||||
#define _LIBROOT_TIME_PRIVATE_H
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#define CLOCKS_PER_SEC_BEOS 1000
|
||||
#define CLK_TCK_BEOS CLOCKS_PER_SEC_BEOS
|
||||
|
||||
#define MICROSECONDS_PER_CLOCK_TICK (1000000 / CLOCKS_PER_SEC)
|
||||
#define MICROSECONDS_PER_CLOCK_TICK_BEOS (1000000 / CLOCKS_PER_SEC_BEOS)
|
||||
|
||||
|
||||
struct __timer_t {
|
||||
int32 id;
|
||||
thread_id thread;
|
||||
|
||||
void SetTo(int32 id, thread_id thread)
|
||||
{
|
||||
this->id = id;
|
||||
this->thread = thread;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static inline void
|
||||
bigtime_to_timespec(bigtime_t time, timespec& spec)
|
||||
{
|
||||
spec.tv_sec = time / 1000000;
|
||||
spec.tv_nsec = (time % 1000000) * 1000;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
timespec_to_bigtime(const timespec& spec, bigtime_t& _time)
|
||||
{
|
||||
if (spec.tv_sec < 0 || spec.tv_nsec < 0 || spec.tv_nsec >= 1000000000)
|
||||
return false;
|
||||
|
||||
_time = (bigtime_t)spec.tv_sec * 1000000 + (spec.tv_nsec + 999) / 1000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
timeval_to_timespec(const timeval& val, timespec& spec)
|
||||
{
|
||||
if (val.tv_sec < 0 || val.tv_usec < 0 || val.tv_usec >= 1000000)
|
||||
return false;
|
||||
|
||||
spec.tv_sec = val.tv_sec;
|
||||
spec.tv_nsec = val.tv_usec * 1000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
timespec_to_timeval(const timespec& spec, timeval& val)
|
||||
{
|
||||
val.tv_sec = spec.tv_sec;
|
||||
val.tv_usec = spec.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
|
||||
clock_t __clock_beos(void);
|
||||
clock_t __clock(void);
|
||||
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
||||
#endif // _LIBROOT_TIME_PRIVATE_H
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _LIBROOT_TIMES_PRIVATE_H
|
||||
#define _LIBROOT_TIMES_PRIVATE_H
|
||||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
|
||||
clock_t __times_beos(struct tms* tms);
|
||||
clock_t __times(struct tms* tms);
|
||||
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
||||
#endif // _LIBROOT_TIMES_PRIVATE_H
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _LIBROOT_UNISTD_PRIVATE_H
|
||||
#define _LIBROOT_UNISTD_PRIVATE_H
|
||||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
|
||||
long __sysconf_beos(int name);
|
||||
long __sysconf(int name);
|
||||
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
||||
#endif // _LIBROOT_UNISTD_PRIVATE_H
|
||||
Reference in New Issue
Block a user