forked from Imagelibrary/rtems
first attempt at the routine which vectors signals.
This commit is contained in:
@@ -7,9 +7,11 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
#include <rtems/posix/threadsup.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
|
||||
/*
|
||||
* Currently 32 signals numbered 1-32 are defined
|
||||
@@ -21,14 +23,185 @@
|
||||
#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
|
||||
|
||||
#define is_valid_signo( _sig ) \
|
||||
((signo_to_mask(_sig) & SIGNAL_ALL_MASK) != 0 )
|
||||
((_sig) >= 1 && (_sig) <= 32 )
|
||||
|
||||
/*** PROCESS WIDE STUFF ****/
|
||||
|
||||
sigset_t _POSIX_signals_Blocked = SIGNAL_EMPTY_MASK;
|
||||
sigset_t _POSIX_signals_Pending = SIGNAL_EMPTY_MASK;
|
||||
sigset_t _POSIX_signals_Pending;
|
||||
sigset_t _POSIX_signals_Ignored;
|
||||
|
||||
struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
|
||||
#define _POSIX_signals_Abormal_termination_handler NULL
|
||||
#define _POSIX_signals_Stop_handler NULL
|
||||
#define _POSIX_signals_Continue_handler NULL
|
||||
|
||||
#define SIGACTION_TERMINATE \
|
||||
{ 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abormal_termination_handler} }
|
||||
#define SIGACTION_IGNORE \
|
||||
{ 0, SIGNAL_ALL_MASK, {SIG_IGN} }
|
||||
#define SIGACTION_STOP \
|
||||
{ 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} }
|
||||
#define SIGACTION_CONTINUE \
|
||||
{ 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} }
|
||||
|
||||
#define SIG_ARRAY_MAX (SIGRTMAX + 1)
|
||||
struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
|
||||
/* NO SIGNAL 0 */ SIGACTION_IGNORE,
|
||||
/* SIGABRT */ SIGACTION_TERMINATE,
|
||||
/* SIGALRM */ SIGACTION_TERMINATE,
|
||||
/* SIGFPE */ SIGACTION_TERMINATE,
|
||||
/* SIGHUP */ SIGACTION_TERMINATE,
|
||||
/* SIGILL */ SIGACTION_TERMINATE,
|
||||
/* SIGINT */ SIGACTION_TERMINATE,
|
||||
/* SIGKILL */ SIGACTION_TERMINATE,
|
||||
/* SIGPIPE */ SIGACTION_TERMINATE,
|
||||
/* SIGQUIT */ SIGACTION_TERMINATE,
|
||||
/* SIGSEGV */ SIGACTION_TERMINATE,
|
||||
/* SIGTERM */ SIGACTION_TERMINATE,
|
||||
/* SIGUSR1 */ SIGACTION_TERMINATE,
|
||||
/* SIGUSR2 */ SIGACTION_TERMINATE,
|
||||
/* SIGCHLD */ SIGACTION_IGNORE,
|
||||
/* SIGCONT */ SIGACTION_CONTINUE,
|
||||
/* SIGSTOP */ SIGACTION_STOP,
|
||||
/* SIGTSTP */ SIGACTION_STOP,
|
||||
/* SIGTTIN */ SIGACTION_STOP,
|
||||
/* SIGTTOU */ SIGACTION_STOP,
|
||||
/* SIGBUS */ SIGACTION_TERMINATE,
|
||||
/* SIGRTMIN 21 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 22 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 23 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 24 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 25 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 26 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 27 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 28 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 29 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 30 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 31 */ SIGACTION_IGNORE,
|
||||
/* SIGRTMAX 32 */ SIGACTION_IGNORE
|
||||
};
|
||||
|
||||
struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
|
||||
|
||||
Watchdog_Control _POSIX_signals_Alarm_timer;
|
||||
|
||||
typedef struct {
|
||||
Chain_Node Node;
|
||||
siginfo_t Info;
|
||||
} POSIX_signals_Siginfo_node;
|
||||
|
||||
Chain_Control _POSIX_signals_Inactive_siginfo;
|
||||
Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* XXX
|
||||
*/
|
||||
|
||||
boolean _POSIX_signals_Check_signal(
|
||||
POSIX_API_Control *api,
|
||||
int signo,
|
||||
boolean is_global
|
||||
)
|
||||
{
|
||||
sigset_t mask;
|
||||
ISR_Level level;
|
||||
boolean do_callout;
|
||||
siginfo_t *siginfo = NULL; /* really needs to be set below */
|
||||
siginfo_t siginfo_struct;
|
||||
|
||||
mask = signo_to_mask( signo );
|
||||
|
||||
do_callout = FALSE;
|
||||
|
||||
_ISR_Disable( level );
|
||||
if ( is_global ) {
|
||||
;
|
||||
/* XXX check right place for thread versus global */
|
||||
} else {
|
||||
if ( mask & (api->signals_pending & ~api->signals_blocked ) ) {
|
||||
api->signals_pending &= ~mask;
|
||||
do_callout = TRUE;
|
||||
}
|
||||
}
|
||||
_ISR_Enable( level );
|
||||
|
||||
if ( !do_callout )
|
||||
return FALSE;
|
||||
|
||||
switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
|
||||
case SA_SIGINFO:
|
||||
assert( 0 ); /* XXX we haven't completely implemented this yet */
|
||||
if ( !is_global ) {
|
||||
siginfo = &siginfo_struct;
|
||||
siginfo->si_signo = signo;
|
||||
siginfo->si_code = SI_USER;
|
||||
siginfo->si_value.sival_int = 0;
|
||||
}
|
||||
(*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
|
||||
signo,
|
||||
siginfo,
|
||||
NULL /* context is undefined per 1003.1b-1993, p. 66 */
|
||||
);
|
||||
break;
|
||||
default:
|
||||
(*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void _POSIX_signals_Run_Them(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
POSIX_API_Control *api;
|
||||
int signo;
|
||||
|
||||
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
/*
|
||||
* If we invoke any user code, there is the possibility that
|
||||
* a new signal has been posted that we should process.
|
||||
*/
|
||||
|
||||
/* XXX somewhere we need to see if all pending signals are gone and clear */
|
||||
/* XXX do_post_switch_extension */
|
||||
|
||||
restart:
|
||||
for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
|
||||
|
||||
if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
|
||||
goto restart;
|
||||
|
||||
if ( _POSIX_signals_Check_signal( api, signo, TRUE ) )
|
||||
goto restart;
|
||||
|
||||
}
|
||||
|
||||
for ( signo = SIGABRT ; signo <= SIGBUS ; signo++ ) {
|
||||
|
||||
if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
|
||||
goto restart;
|
||||
|
||||
if ( _POSIX_signals_Check_signal( api, signo, TRUE ) )
|
||||
goto restart;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _POSIX_signals_Alarm_TSR
|
||||
*/
|
||||
|
||||
void _POSIX_signals_Alarm_TSR(
|
||||
Objects_Id id,
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
kill( getpid(), SIGALRM );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
@@ -37,7 +210,57 @@ struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
|
||||
|
||||
void _POSIX_signals_Manager_Initialization( void )
|
||||
{
|
||||
/* XXX install default actions for all vectors */
|
||||
unsigned32 signo;
|
||||
|
||||
/*
|
||||
* Insure we have the same number of vectors and default vector entries
|
||||
*/
|
||||
|
||||
assert(
|
||||
sizeof(_POSIX_signals_Vectors) == sizeof(_POSIX_signals_Default_vectors)
|
||||
);
|
||||
|
||||
memcpy(
|
||||
_POSIX_signals_Vectors,
|
||||
_POSIX_signals_Default_vectors,
|
||||
sizeof( _POSIX_signals_Vectors )
|
||||
);
|
||||
|
||||
/*
|
||||
* Initialize the set of pending signals for the entire process
|
||||
*/
|
||||
|
||||
sigemptyset( &_POSIX_signals_Pending );
|
||||
|
||||
/*
|
||||
* Calculate the mask for the set of signals which are being ignored.
|
||||
*/
|
||||
|
||||
sigemptyset( &_POSIX_signals_Ignored );
|
||||
|
||||
for ( signo=1 ; signo<= SIGRTMAX ; signo++ )
|
||||
if ( _POSIX_signals_Default_vectors[ signo ].sa_handler == SIG_IGN )
|
||||
sigaddset( &_POSIX_signals_Ignored, signo );
|
||||
|
||||
/*
|
||||
* Initialize the timer used to implement alarm().
|
||||
*/
|
||||
|
||||
_Watchdog_Initialize(
|
||||
&_POSIX_signals_Alarm_timer,
|
||||
_POSIX_signals_Alarm_TSR,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
/*
|
||||
* XXX Allocate the siginfo pools.
|
||||
*/
|
||||
|
||||
for ( signo=1 ; signo<= SIGRTMAX ; signo++ )
|
||||
_Chain_Initialize_empty( &_POSIX_signals_Siginfo[ signo ] );
|
||||
|
||||
/* XXX especially the inactive pool */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -149,6 +372,7 @@ int sigaction(
|
||||
*oact = _POSIX_signals_Vectors[ sig ];
|
||||
|
||||
/* XXX need to interpret some stuff here */
|
||||
/* XXX some signals cannot be ignored */
|
||||
|
||||
_POSIX_signals_Vectors[ sig ] = *act;
|
||||
|
||||
@@ -188,6 +412,9 @@ int pthread_sigmask(
|
||||
)
|
||||
{
|
||||
POSIX_API_Control *api;
|
||||
boolean evaluate_signals;
|
||||
|
||||
/* XXX some signals can not be ignored */
|
||||
|
||||
if ( !set && !oset )
|
||||
set_errno_and_return_minus_one( EFAULT );
|
||||
@@ -200,9 +427,12 @@ int pthread_sigmask(
|
||||
if ( !set )
|
||||
set_errno_and_return_minus_one( EFAULT );
|
||||
|
||||
evaluate_signals = TRUE;
|
||||
|
||||
switch ( how ) {
|
||||
case SIG_BLOCK:
|
||||
api->signals_blocked |= *set;
|
||||
evaluate_signals = FALSE;
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
api->signals_blocked &= ~*set;
|
||||
@@ -214,9 +444,20 @@ int pthread_sigmask(
|
||||
set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
/* XXX are there critical section problems here? */
|
||||
|
||||
/* XXX evaluate the new set */
|
||||
|
||||
return POSIX_NOT_IMPLEMENTED();
|
||||
if ( evaluate_signals == TRUE ) {
|
||||
if ( ~api->signals_blocked &
|
||||
(api->signals_pending | _POSIX_signals_Pending) ) {
|
||||
api->signals_global_pending &= _POSIX_signals_Pending;
|
||||
_Thread_Executing->do_post_task_switch_extension = TRUE;
|
||||
_Thread_Dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -227,7 +468,16 @@ int sigpending(
|
||||
sigset_t *set
|
||||
)
|
||||
{
|
||||
return POSIX_NOT_IMPLEMENTED();
|
||||
POSIX_API_Control *api;
|
||||
|
||||
if ( !set )
|
||||
set_errno_and_return_minus_one( EFAULT );
|
||||
|
||||
api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
*set = api->signals_pending | _POSIX_signals_Pending;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -312,9 +562,13 @@ int kill(
|
||||
* Only supported for the "calling process" (i.e. this node).
|
||||
*/
|
||||
|
||||
assert( pid == getpid() );
|
||||
if( pid != getpid() );
|
||||
set_errno_and_return_minus_one( ESRCH );
|
||||
|
||||
/* SIGABRT comes from abort via assert */
|
||||
if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
|
||||
return 0;
|
||||
|
||||
/* SIGABRT comes from abort via assert and must work no matter what */
|
||||
if ( sig == SIGABRT ) {
|
||||
exit( 1 );
|
||||
}
|
||||
@@ -330,18 +584,78 @@ int pthread_kill(
|
||||
int sig
|
||||
)
|
||||
{
|
||||
return POSIX_NOT_IMPLEMENTED();
|
||||
POSIX_API_Control *api;
|
||||
Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
if ( sig && !is_valid_signo(sig) )
|
||||
set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
|
||||
return 0;
|
||||
|
||||
the_thread = _POSIX_Threads_Get( thread, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE:
|
||||
return ESRCH;
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* If sig == 0 then just validate arguments
|
||||
*/
|
||||
|
||||
api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
if ( sig ) {
|
||||
|
||||
/* XXX critical section */
|
||||
|
||||
api->signals_pending |= signo_to_mask( sig );
|
||||
|
||||
if ( api->signals_pending & ~api->signals_blocked ) {
|
||||
the_thread->do_post_task_switch_extension = TRUE;
|
||||
|
||||
/* XXX may have to unblock the task */
|
||||
|
||||
}
|
||||
}
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
|
||||
/*
|
||||
* 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
|
||||
*/
|
||||
|
||||
Watchdog_Control _POSIX_signals_Alarm_timer;
|
||||
|
||||
unsigned int alarm(
|
||||
unsigned int seconds
|
||||
)
|
||||
{
|
||||
return POSIX_NOT_IMPLEMENTED();
|
||||
unsigned int remaining = 0;
|
||||
Watchdog_Control *the_timer;
|
||||
|
||||
the_timer = &_POSIX_signals_Alarm_timer;
|
||||
|
||||
switch ( _Watchdog_Remove( the_timer ) ) {
|
||||
case WATCHDOG_INACTIVE:
|
||||
case WATCHDOG_BEING_INSERTED:
|
||||
break;
|
||||
|
||||
case WATCHDOG_ACTIVE:
|
||||
case WATCHDOG_REMOVE_IT:
|
||||
remaining = the_timer->initial -
|
||||
(the_timer->stop_time - the_timer->start_time);
|
||||
break;
|
||||
}
|
||||
|
||||
_Watchdog_Insert_seconds( the_timer, seconds );
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -29,7 +29,7 @@ const pthread_attr_t _POSIX_Threads_Default_attributes = {
|
||||
NULL, /* stackaddr */
|
||||
STACK_MINIMUM_SIZE, /* stacksize */
|
||||
PTHREAD_SCOPE_PROCESS, /* contentionscope */
|
||||
PTHREAD_INHERIT_SCHED, /* inheritsched */
|
||||
PTHREAD_EXPLICIT_SCHED, /* inheritsched */
|
||||
SCHED_FIFO, /* schedpolicy */
|
||||
{ /* schedparam */
|
||||
128, /* sched_priority */
|
||||
@@ -123,6 +123,8 @@ boolean _POSIX_Threads_Create_extension(
|
||||
api->schedparam.sched_priority =
|
||||
_POSIX_Priority_From_core( created->current_priority );
|
||||
|
||||
/* XXX set signal parameters -- block all signals for non-posix threads */
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&api->Join_List,
|
||||
OBJECTS_NO_CLASS, /* only used for proxy operations */
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
#include <rtems/posix/threadsup.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
|
||||
/*
|
||||
* Currently 32 signals numbered 1-32 are defined
|
||||
@@ -21,14 +23,185 @@
|
||||
#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
|
||||
|
||||
#define is_valid_signo( _sig ) \
|
||||
((signo_to_mask(_sig) & SIGNAL_ALL_MASK) != 0 )
|
||||
((_sig) >= 1 && (_sig) <= 32 )
|
||||
|
||||
/*** PROCESS WIDE STUFF ****/
|
||||
|
||||
sigset_t _POSIX_signals_Blocked = SIGNAL_EMPTY_MASK;
|
||||
sigset_t _POSIX_signals_Pending = SIGNAL_EMPTY_MASK;
|
||||
sigset_t _POSIX_signals_Pending;
|
||||
sigset_t _POSIX_signals_Ignored;
|
||||
|
||||
struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
|
||||
#define _POSIX_signals_Abormal_termination_handler NULL
|
||||
#define _POSIX_signals_Stop_handler NULL
|
||||
#define _POSIX_signals_Continue_handler NULL
|
||||
|
||||
#define SIGACTION_TERMINATE \
|
||||
{ 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abormal_termination_handler} }
|
||||
#define SIGACTION_IGNORE \
|
||||
{ 0, SIGNAL_ALL_MASK, {SIG_IGN} }
|
||||
#define SIGACTION_STOP \
|
||||
{ 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} }
|
||||
#define SIGACTION_CONTINUE \
|
||||
{ 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} }
|
||||
|
||||
#define SIG_ARRAY_MAX (SIGRTMAX + 1)
|
||||
struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
|
||||
/* NO SIGNAL 0 */ SIGACTION_IGNORE,
|
||||
/* SIGABRT */ SIGACTION_TERMINATE,
|
||||
/* SIGALRM */ SIGACTION_TERMINATE,
|
||||
/* SIGFPE */ SIGACTION_TERMINATE,
|
||||
/* SIGHUP */ SIGACTION_TERMINATE,
|
||||
/* SIGILL */ SIGACTION_TERMINATE,
|
||||
/* SIGINT */ SIGACTION_TERMINATE,
|
||||
/* SIGKILL */ SIGACTION_TERMINATE,
|
||||
/* SIGPIPE */ SIGACTION_TERMINATE,
|
||||
/* SIGQUIT */ SIGACTION_TERMINATE,
|
||||
/* SIGSEGV */ SIGACTION_TERMINATE,
|
||||
/* SIGTERM */ SIGACTION_TERMINATE,
|
||||
/* SIGUSR1 */ SIGACTION_TERMINATE,
|
||||
/* SIGUSR2 */ SIGACTION_TERMINATE,
|
||||
/* SIGCHLD */ SIGACTION_IGNORE,
|
||||
/* SIGCONT */ SIGACTION_CONTINUE,
|
||||
/* SIGSTOP */ SIGACTION_STOP,
|
||||
/* SIGTSTP */ SIGACTION_STOP,
|
||||
/* SIGTTIN */ SIGACTION_STOP,
|
||||
/* SIGTTOU */ SIGACTION_STOP,
|
||||
/* SIGBUS */ SIGACTION_TERMINATE,
|
||||
/* SIGRTMIN 21 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 22 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 23 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 24 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 25 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 26 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 27 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 28 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 29 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 30 */ SIGACTION_IGNORE,
|
||||
/* SIGRT 31 */ SIGACTION_IGNORE,
|
||||
/* SIGRTMAX 32 */ SIGACTION_IGNORE
|
||||
};
|
||||
|
||||
struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
|
||||
|
||||
Watchdog_Control _POSIX_signals_Alarm_timer;
|
||||
|
||||
typedef struct {
|
||||
Chain_Node Node;
|
||||
siginfo_t Info;
|
||||
} POSIX_signals_Siginfo_node;
|
||||
|
||||
Chain_Control _POSIX_signals_Inactive_siginfo;
|
||||
Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* XXX
|
||||
*/
|
||||
|
||||
boolean _POSIX_signals_Check_signal(
|
||||
POSIX_API_Control *api,
|
||||
int signo,
|
||||
boolean is_global
|
||||
)
|
||||
{
|
||||
sigset_t mask;
|
||||
ISR_Level level;
|
||||
boolean do_callout;
|
||||
siginfo_t *siginfo = NULL; /* really needs to be set below */
|
||||
siginfo_t siginfo_struct;
|
||||
|
||||
mask = signo_to_mask( signo );
|
||||
|
||||
do_callout = FALSE;
|
||||
|
||||
_ISR_Disable( level );
|
||||
if ( is_global ) {
|
||||
;
|
||||
/* XXX check right place for thread versus global */
|
||||
} else {
|
||||
if ( mask & (api->signals_pending & ~api->signals_blocked ) ) {
|
||||
api->signals_pending &= ~mask;
|
||||
do_callout = TRUE;
|
||||
}
|
||||
}
|
||||
_ISR_Enable( level );
|
||||
|
||||
if ( !do_callout )
|
||||
return FALSE;
|
||||
|
||||
switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
|
||||
case SA_SIGINFO:
|
||||
assert( 0 ); /* XXX we haven't completely implemented this yet */
|
||||
if ( !is_global ) {
|
||||
siginfo = &siginfo_struct;
|
||||
siginfo->si_signo = signo;
|
||||
siginfo->si_code = SI_USER;
|
||||
siginfo->si_value.sival_int = 0;
|
||||
}
|
||||
(*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
|
||||
signo,
|
||||
siginfo,
|
||||
NULL /* context is undefined per 1003.1b-1993, p. 66 */
|
||||
);
|
||||
break;
|
||||
default:
|
||||
(*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void _POSIX_signals_Run_Them(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
POSIX_API_Control *api;
|
||||
int signo;
|
||||
|
||||
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
/*
|
||||
* If we invoke any user code, there is the possibility that
|
||||
* a new signal has been posted that we should process.
|
||||
*/
|
||||
|
||||
/* XXX somewhere we need to see if all pending signals are gone and clear */
|
||||
/* XXX do_post_switch_extension */
|
||||
|
||||
restart:
|
||||
for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
|
||||
|
||||
if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
|
||||
goto restart;
|
||||
|
||||
if ( _POSIX_signals_Check_signal( api, signo, TRUE ) )
|
||||
goto restart;
|
||||
|
||||
}
|
||||
|
||||
for ( signo = SIGABRT ; signo <= SIGBUS ; signo++ ) {
|
||||
|
||||
if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
|
||||
goto restart;
|
||||
|
||||
if ( _POSIX_signals_Check_signal( api, signo, TRUE ) )
|
||||
goto restart;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _POSIX_signals_Alarm_TSR
|
||||
*/
|
||||
|
||||
void _POSIX_signals_Alarm_TSR(
|
||||
Objects_Id id,
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
kill( getpid(), SIGALRM );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
@@ -37,7 +210,57 @@ struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
|
||||
|
||||
void _POSIX_signals_Manager_Initialization( void )
|
||||
{
|
||||
/* XXX install default actions for all vectors */
|
||||
unsigned32 signo;
|
||||
|
||||
/*
|
||||
* Insure we have the same number of vectors and default vector entries
|
||||
*/
|
||||
|
||||
assert(
|
||||
sizeof(_POSIX_signals_Vectors) == sizeof(_POSIX_signals_Default_vectors)
|
||||
);
|
||||
|
||||
memcpy(
|
||||
_POSIX_signals_Vectors,
|
||||
_POSIX_signals_Default_vectors,
|
||||
sizeof( _POSIX_signals_Vectors )
|
||||
);
|
||||
|
||||
/*
|
||||
* Initialize the set of pending signals for the entire process
|
||||
*/
|
||||
|
||||
sigemptyset( &_POSIX_signals_Pending );
|
||||
|
||||
/*
|
||||
* Calculate the mask for the set of signals which are being ignored.
|
||||
*/
|
||||
|
||||
sigemptyset( &_POSIX_signals_Ignored );
|
||||
|
||||
for ( signo=1 ; signo<= SIGRTMAX ; signo++ )
|
||||
if ( _POSIX_signals_Default_vectors[ signo ].sa_handler == SIG_IGN )
|
||||
sigaddset( &_POSIX_signals_Ignored, signo );
|
||||
|
||||
/*
|
||||
* Initialize the timer used to implement alarm().
|
||||
*/
|
||||
|
||||
_Watchdog_Initialize(
|
||||
&_POSIX_signals_Alarm_timer,
|
||||
_POSIX_signals_Alarm_TSR,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
/*
|
||||
* XXX Allocate the siginfo pools.
|
||||
*/
|
||||
|
||||
for ( signo=1 ; signo<= SIGRTMAX ; signo++ )
|
||||
_Chain_Initialize_empty( &_POSIX_signals_Siginfo[ signo ] );
|
||||
|
||||
/* XXX especially the inactive pool */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -149,6 +372,7 @@ int sigaction(
|
||||
*oact = _POSIX_signals_Vectors[ sig ];
|
||||
|
||||
/* XXX need to interpret some stuff here */
|
||||
/* XXX some signals cannot be ignored */
|
||||
|
||||
_POSIX_signals_Vectors[ sig ] = *act;
|
||||
|
||||
@@ -188,6 +412,9 @@ int pthread_sigmask(
|
||||
)
|
||||
{
|
||||
POSIX_API_Control *api;
|
||||
boolean evaluate_signals;
|
||||
|
||||
/* XXX some signals can not be ignored */
|
||||
|
||||
if ( !set && !oset )
|
||||
set_errno_and_return_minus_one( EFAULT );
|
||||
@@ -200,9 +427,12 @@ int pthread_sigmask(
|
||||
if ( !set )
|
||||
set_errno_and_return_minus_one( EFAULT );
|
||||
|
||||
evaluate_signals = TRUE;
|
||||
|
||||
switch ( how ) {
|
||||
case SIG_BLOCK:
|
||||
api->signals_blocked |= *set;
|
||||
evaluate_signals = FALSE;
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
api->signals_blocked &= ~*set;
|
||||
@@ -214,9 +444,20 @@ int pthread_sigmask(
|
||||
set_errno_and_return_minus_one( EINVAL );
|
||||
}
|
||||
|
||||
/* XXX are there critical section problems here? */
|
||||
|
||||
/* XXX evaluate the new set */
|
||||
|
||||
return POSIX_NOT_IMPLEMENTED();
|
||||
if ( evaluate_signals == TRUE ) {
|
||||
if ( ~api->signals_blocked &
|
||||
(api->signals_pending | _POSIX_signals_Pending) ) {
|
||||
api->signals_global_pending &= _POSIX_signals_Pending;
|
||||
_Thread_Executing->do_post_task_switch_extension = TRUE;
|
||||
_Thread_Dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -227,7 +468,16 @@ int sigpending(
|
||||
sigset_t *set
|
||||
)
|
||||
{
|
||||
return POSIX_NOT_IMPLEMENTED();
|
||||
POSIX_API_Control *api;
|
||||
|
||||
if ( !set )
|
||||
set_errno_and_return_minus_one( EFAULT );
|
||||
|
||||
api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
*set = api->signals_pending | _POSIX_signals_Pending;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -312,9 +562,13 @@ int kill(
|
||||
* Only supported for the "calling process" (i.e. this node).
|
||||
*/
|
||||
|
||||
assert( pid == getpid() );
|
||||
if( pid != getpid() );
|
||||
set_errno_and_return_minus_one( ESRCH );
|
||||
|
||||
/* SIGABRT comes from abort via assert */
|
||||
if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
|
||||
return 0;
|
||||
|
||||
/* SIGABRT comes from abort via assert and must work no matter what */
|
||||
if ( sig == SIGABRT ) {
|
||||
exit( 1 );
|
||||
}
|
||||
@@ -330,18 +584,78 @@ int pthread_kill(
|
||||
int sig
|
||||
)
|
||||
{
|
||||
return POSIX_NOT_IMPLEMENTED();
|
||||
POSIX_API_Control *api;
|
||||
Thread_Control *the_thread;
|
||||
Objects_Locations location;
|
||||
|
||||
if ( sig && !is_valid_signo(sig) )
|
||||
set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
|
||||
return 0;
|
||||
|
||||
the_thread = _POSIX_Threads_Get( thread, &location );
|
||||
switch ( location ) {
|
||||
case OBJECTS_ERROR:
|
||||
case OBJECTS_REMOTE:
|
||||
return ESRCH;
|
||||
case OBJECTS_LOCAL:
|
||||
/*
|
||||
* If sig == 0 then just validate arguments
|
||||
*/
|
||||
|
||||
api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
if ( sig ) {
|
||||
|
||||
/* XXX critical section */
|
||||
|
||||
api->signals_pending |= signo_to_mask( sig );
|
||||
|
||||
if ( api->signals_pending & ~api->signals_blocked ) {
|
||||
the_thread->do_post_task_switch_extension = TRUE;
|
||||
|
||||
/* XXX may have to unblock the task */
|
||||
|
||||
}
|
||||
}
|
||||
_Thread_Enable_dispatch();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return POSIX_BOTTOM_REACHED();
|
||||
}
|
||||
|
||||
/*
|
||||
* 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
|
||||
*/
|
||||
|
||||
Watchdog_Control _POSIX_signals_Alarm_timer;
|
||||
|
||||
unsigned int alarm(
|
||||
unsigned int seconds
|
||||
)
|
||||
{
|
||||
return POSIX_NOT_IMPLEMENTED();
|
||||
unsigned int remaining = 0;
|
||||
Watchdog_Control *the_timer;
|
||||
|
||||
the_timer = &_POSIX_signals_Alarm_timer;
|
||||
|
||||
switch ( _Watchdog_Remove( the_timer ) ) {
|
||||
case WATCHDOG_INACTIVE:
|
||||
case WATCHDOG_BEING_INSERTED:
|
||||
break;
|
||||
|
||||
case WATCHDOG_ACTIVE:
|
||||
case WATCHDOG_REMOVE_IT:
|
||||
remaining = the_timer->initial -
|
||||
(the_timer->stop_time - the_timer->start_time);
|
||||
break;
|
||||
}
|
||||
|
||||
_Watchdog_Insert_seconds( the_timer, seconds );
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -29,7 +29,7 @@ const pthread_attr_t _POSIX_Threads_Default_attributes = {
|
||||
NULL, /* stackaddr */
|
||||
STACK_MINIMUM_SIZE, /* stacksize */
|
||||
PTHREAD_SCOPE_PROCESS, /* contentionscope */
|
||||
PTHREAD_INHERIT_SCHED, /* inheritsched */
|
||||
PTHREAD_EXPLICIT_SCHED, /* inheritsched */
|
||||
SCHED_FIFO, /* schedpolicy */
|
||||
{ /* schedparam */
|
||||
128, /* sched_priority */
|
||||
@@ -123,6 +123,8 @@ boolean _POSIX_Threads_Create_extension(
|
||||
api->schedparam.sched_priority =
|
||||
_POSIX_Priority_From_core( created->current_priority );
|
||||
|
||||
/* XXX set signal parameters -- block all signals for non-posix threads */
|
||||
|
||||
_Thread_queue_Initialize(
|
||||
&api->Join_List,
|
||||
OBJECTS_NO_CLASS, /* only used for proxy operations */
|
||||
|
||||
Reference in New Issue
Block a user