tested blocking a signal, sending it to self, then unblocking it.

make minimum stack size for posix threads double that of the cpu's minimum
requirement.
This commit is contained in:
Joel Sherrill
1996-06-11 20:43:55 +00:00
parent fb39f191da
commit c8f5ab5d2e
4 changed files with 122 additions and 64 deletions

View File

@@ -59,14 +59,14 @@ struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
/* SIGTERM */ SIGACTION_TERMINATE, /* SIGTERM */ SIGACTION_TERMINATE,
/* SIGUSR1 */ SIGACTION_TERMINATE, /* SIGUSR1 */ SIGACTION_TERMINATE,
/* SIGUSR2 */ SIGACTION_TERMINATE, /* SIGUSR2 */ SIGACTION_TERMINATE,
/* SIGCHLD */ SIGACTION_IGNORE, /* SIGRTMIN 14 */ SIGACTION_IGNORE,
/* SIGCONT */ SIGACTION_CONTINUE, /* SIGRT 15 */ SIGACTION_IGNORE,
/* SIGSTOP */ SIGACTION_STOP, /* SIGRT 16 */ SIGACTION_IGNORE,
/* SIGTSTP */ SIGACTION_STOP, /* SIGRT 17 */ SIGACTION_IGNORE,
/* SIGTTIN */ SIGACTION_STOP, /* SIGRT 18 */ SIGACTION_IGNORE,
/* SIGTTOU */ SIGACTION_STOP, /* SIGRT 19 */ SIGACTION_IGNORE,
/* SIGBUS */ SIGACTION_TERMINATE, /* SIGRT 20 */ SIGACTION_IGNORE,
/* SIGRTMIN 21 */ SIGACTION_IGNORE, /* SIGRT 21 */ SIGACTION_IGNORE,
/* SIGRT 22 */ SIGACTION_IGNORE, /* SIGRT 22 */ SIGACTION_IGNORE,
/* SIGRT 23 */ SIGACTION_IGNORE, /* SIGRT 23 */ SIGACTION_IGNORE,
/* SIGRT 24 */ SIGACTION_IGNORE, /* SIGRT 24 */ SIGACTION_IGNORE,
@@ -108,6 +108,7 @@ boolean _POSIX_signals_Check_signal(
boolean do_callout; boolean do_callout;
siginfo_t *siginfo = NULL; /* really needs to be set below */ siginfo_t *siginfo = NULL; /* really needs to be set below */
siginfo_t siginfo_struct; siginfo_t siginfo_struct;
sigset_t saved_signals_blocked;
mask = signo_to_mask( signo ); mask = signo_to_mask( signo );
@@ -136,6 +137,20 @@ boolean _POSIX_signals_Check_signal(
assert( _POSIX_signals_Vectors[ signo ].sa_handler || assert( _POSIX_signals_Vectors[ signo ].sa_handler ||
_POSIX_signals_Vectors[ signo ].sa_sigaction ); _POSIX_signals_Vectors[ signo ].sa_sigaction );
/*
* Just to prevent sending a signal which is currently being ignored.
*/
if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN )
return FALSE;
/*
* Block the signals requested in sa_mask
*/
saved_signals_blocked = api->signals_blocked;
api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask;
switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) { switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
case SA_SIGINFO: case SA_SIGINFO:
assert( 0 ); /* XXX we haven't completely implemented this yet */ assert( 0 ); /* XXX we haven't completely implemented this yet */
@@ -155,6 +170,13 @@ boolean _POSIX_signals_Check_signal(
(*_POSIX_signals_Vectors[ signo ].sa_handler)( signo ); (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
break; break;
} }
/*
* Restore the previous set of blocked signals
*/
api->signals_blocked = saved_signals_blocked;
return TRUE; return TRUE;
} }
@@ -164,18 +186,26 @@ void _POSIX_signals_Post_switch_extension(
{ {
POSIX_API_Control *api; POSIX_API_Control *api;
int signo; int signo;
ISR_Level level;
api = the_thread->API_Extensions[ THREAD_API_POSIX ]; api = the_thread->API_Extensions[ THREAD_API_POSIX ];
/* /*
* If we invoke any user code, there is the possibility that * If we invoke any user code, there is the possibility that
* a new signal has been posted that we should process. * a new signal has been posted that we should process so we
* restart the loop if a signal handler was invoked.
*
* The first thing done is to check there are any signals to be
* processed at all. No point in doing this loop otherwise.
*/ */
/* XXX somewhere we need to see if all pending signals are gone and clear */
/* XXX do_post_switch_extension */
restart: restart:
_ISR_Disable( level );
if ( !(~api->signals_blocked &
(api->signals_pending | _POSIX_signals_Pending)) )
return;
_ISR_Enable( level );
for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
if ( _POSIX_signals_Check_signal( api, signo, FALSE ) ) if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
@@ -186,7 +216,7 @@ restart:
} }
for ( signo = SIGABRT ; signo <= SIGBUS ; signo++ ) { for ( signo = SIGABRT ; signo <= __SIGLASTNOTRT ; signo++ ) {
if ( _POSIX_signals_Check_signal( api, signo, FALSE ) ) if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
goto restart; goto restart;
@@ -370,19 +400,24 @@ int sigaction(
struct sigaction *oact struct sigaction *oact
) )
{ {
if ( !act )
set_errno_and_return_minus_one( EFAULT );
if ( !is_valid_signo(sig) ) if ( !is_valid_signo(sig) )
set_errno_and_return_minus_one( EINVAL ); set_errno_and_return_minus_one( EINVAL );
if ( oact ) if ( oact )
*oact = _POSIX_signals_Vectors[ sig ]; *oact = _POSIX_signals_Vectors[ sig ];
/* XXX need to interpret some stuff here */
/* XXX some signals cannot be ignored */ /* XXX some signals cannot be ignored */
/* XXX can't find this in spec -- ignore calls on SIGKILL and SIGSTOP */
/* XXX we don't do SIGSTOP */
_POSIX_signals_Vectors[ sig ] = *act; if ( sig == SIGKILL )
set_errno_and_return_minus_one( EINVAL );
/* XXX need to interpret some stuff here */
if ( act ) {
_POSIX_signals_Vectors[ sig ] = *act;
}
return 0; return 0;
} }
@@ -420,7 +455,6 @@ int pthread_sigmask(
) )
{ {
POSIX_API_Control *api; POSIX_API_Control *api;
boolean evaluate_signals;
/* XXX some signals can not be ignored */ /* XXX some signals can not be ignored */
@@ -435,12 +469,9 @@ int pthread_sigmask(
if ( !set ) if ( !set )
set_errno_and_return_minus_one( EFAULT ); set_errno_and_return_minus_one( EFAULT );
evaluate_signals = TRUE;
switch ( how ) { switch ( how ) {
case SIG_BLOCK: case SIG_BLOCK:
api->signals_blocked |= *set; api->signals_blocked |= *set;
evaluate_signals = FALSE;
break; break;
case SIG_UNBLOCK: case SIG_UNBLOCK:
api->signals_blocked &= ~*set; api->signals_blocked &= ~*set;
@@ -456,13 +487,11 @@ int pthread_sigmask(
/* XXX evaluate the new set */ /* XXX evaluate the new set */
if ( evaluate_signals == TRUE ) { if ( ~api->signals_blocked &
if ( ~api->signals_blocked & (api->signals_pending | _POSIX_signals_Pending) ) {
(api->signals_pending | _POSIX_signals_Pending) ) { api->signals_global_pending &= _POSIX_signals_Pending;
api->signals_global_pending &= _POSIX_signals_Pending; _Thread_Executing->do_post_task_switch_extension = TRUE;
_Thread_Executing->do_post_task_switch_extension = TRUE; _Thread_Dispatch();
_Thread_Dispatch();
}
} }
return 0; return 0;
@@ -622,9 +651,9 @@ int pthread_kill(
if ( api->signals_pending & ~api->signals_blocked ) { if ( api->signals_pending & ~api->signals_blocked ) {
the_thread->do_post_task_switch_extension = TRUE; the_thread->do_post_task_switch_extension = TRUE;
/* XXX may have to unblock the task -- this is a kludge -- fix it */ /* XXX unblock the task -- this is a kludge -- fix it */
if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) { if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
the_thread->Wait.return_code = EINTR; the_thread->Wait.return_code = EINTR;
if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) ) if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) )

View File

@@ -28,7 +28,7 @@
const pthread_attr_t _POSIX_Threads_Default_attributes = { const pthread_attr_t _POSIX_Threads_Default_attributes = {
TRUE, /* is_initialized */ TRUE, /* is_initialized */
NULL, /* stackaddr */ NULL, /* stackaddr */
STACK_MINIMUM_SIZE, /* stacksize */ STACK_MINIMUM_SIZE * 2, /* stacksize */
PTHREAD_SCOPE_PROCESS, /* contentionscope */ PTHREAD_SCOPE_PROCESS, /* contentionscope */
PTHREAD_EXPLICIT_SCHED, /* inheritsched */ PTHREAD_EXPLICIT_SCHED, /* inheritsched */
SCHED_FIFO, /* schedpolicy */ SCHED_FIFO, /* schedpolicy */

View File

@@ -59,14 +59,14 @@ struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
/* SIGTERM */ SIGACTION_TERMINATE, /* SIGTERM */ SIGACTION_TERMINATE,
/* SIGUSR1 */ SIGACTION_TERMINATE, /* SIGUSR1 */ SIGACTION_TERMINATE,
/* SIGUSR2 */ SIGACTION_TERMINATE, /* SIGUSR2 */ SIGACTION_TERMINATE,
/* SIGCHLD */ SIGACTION_IGNORE, /* SIGRTMIN 14 */ SIGACTION_IGNORE,
/* SIGCONT */ SIGACTION_CONTINUE, /* SIGRT 15 */ SIGACTION_IGNORE,
/* SIGSTOP */ SIGACTION_STOP, /* SIGRT 16 */ SIGACTION_IGNORE,
/* SIGTSTP */ SIGACTION_STOP, /* SIGRT 17 */ SIGACTION_IGNORE,
/* SIGTTIN */ SIGACTION_STOP, /* SIGRT 18 */ SIGACTION_IGNORE,
/* SIGTTOU */ SIGACTION_STOP, /* SIGRT 19 */ SIGACTION_IGNORE,
/* SIGBUS */ SIGACTION_TERMINATE, /* SIGRT 20 */ SIGACTION_IGNORE,
/* SIGRTMIN 21 */ SIGACTION_IGNORE, /* SIGRT 21 */ SIGACTION_IGNORE,
/* SIGRT 22 */ SIGACTION_IGNORE, /* SIGRT 22 */ SIGACTION_IGNORE,
/* SIGRT 23 */ SIGACTION_IGNORE, /* SIGRT 23 */ SIGACTION_IGNORE,
/* SIGRT 24 */ SIGACTION_IGNORE, /* SIGRT 24 */ SIGACTION_IGNORE,
@@ -108,6 +108,7 @@ boolean _POSIX_signals_Check_signal(
boolean do_callout; boolean do_callout;
siginfo_t *siginfo = NULL; /* really needs to be set below */ siginfo_t *siginfo = NULL; /* really needs to be set below */
siginfo_t siginfo_struct; siginfo_t siginfo_struct;
sigset_t saved_signals_blocked;
mask = signo_to_mask( signo ); mask = signo_to_mask( signo );
@@ -136,6 +137,20 @@ boolean _POSIX_signals_Check_signal(
assert( _POSIX_signals_Vectors[ signo ].sa_handler || assert( _POSIX_signals_Vectors[ signo ].sa_handler ||
_POSIX_signals_Vectors[ signo ].sa_sigaction ); _POSIX_signals_Vectors[ signo ].sa_sigaction );
/*
* Just to prevent sending a signal which is currently being ignored.
*/
if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN )
return FALSE;
/*
* Block the signals requested in sa_mask
*/
saved_signals_blocked = api->signals_blocked;
api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask;
switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) { switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
case SA_SIGINFO: case SA_SIGINFO:
assert( 0 ); /* XXX we haven't completely implemented this yet */ assert( 0 ); /* XXX we haven't completely implemented this yet */
@@ -155,6 +170,13 @@ boolean _POSIX_signals_Check_signal(
(*_POSIX_signals_Vectors[ signo ].sa_handler)( signo ); (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
break; break;
} }
/*
* Restore the previous set of blocked signals
*/
api->signals_blocked = saved_signals_blocked;
return TRUE; return TRUE;
} }
@@ -164,18 +186,26 @@ void _POSIX_signals_Post_switch_extension(
{ {
POSIX_API_Control *api; POSIX_API_Control *api;
int signo; int signo;
ISR_Level level;
api = the_thread->API_Extensions[ THREAD_API_POSIX ]; api = the_thread->API_Extensions[ THREAD_API_POSIX ];
/* /*
* If we invoke any user code, there is the possibility that * If we invoke any user code, there is the possibility that
* a new signal has been posted that we should process. * a new signal has been posted that we should process so we
* restart the loop if a signal handler was invoked.
*
* The first thing done is to check there are any signals to be
* processed at all. No point in doing this loop otherwise.
*/ */
/* XXX somewhere we need to see if all pending signals are gone and clear */
/* XXX do_post_switch_extension */
restart: restart:
_ISR_Disable( level );
if ( !(~api->signals_blocked &
(api->signals_pending | _POSIX_signals_Pending)) )
return;
_ISR_Enable( level );
for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
if ( _POSIX_signals_Check_signal( api, signo, FALSE ) ) if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
@@ -186,7 +216,7 @@ restart:
} }
for ( signo = SIGABRT ; signo <= SIGBUS ; signo++ ) { for ( signo = SIGABRT ; signo <= __SIGLASTNOTRT ; signo++ ) {
if ( _POSIX_signals_Check_signal( api, signo, FALSE ) ) if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
goto restart; goto restart;
@@ -370,19 +400,24 @@ int sigaction(
struct sigaction *oact struct sigaction *oact
) )
{ {
if ( !act )
set_errno_and_return_minus_one( EFAULT );
if ( !is_valid_signo(sig) ) if ( !is_valid_signo(sig) )
set_errno_and_return_minus_one( EINVAL ); set_errno_and_return_minus_one( EINVAL );
if ( oact ) if ( oact )
*oact = _POSIX_signals_Vectors[ sig ]; *oact = _POSIX_signals_Vectors[ sig ];
/* XXX need to interpret some stuff here */
/* XXX some signals cannot be ignored */ /* XXX some signals cannot be ignored */
/* XXX can't find this in spec -- ignore calls on SIGKILL and SIGSTOP */
/* XXX we don't do SIGSTOP */
_POSIX_signals_Vectors[ sig ] = *act; if ( sig == SIGKILL )
set_errno_and_return_minus_one( EINVAL );
/* XXX need to interpret some stuff here */
if ( act ) {
_POSIX_signals_Vectors[ sig ] = *act;
}
return 0; return 0;
} }
@@ -420,7 +455,6 @@ int pthread_sigmask(
) )
{ {
POSIX_API_Control *api; POSIX_API_Control *api;
boolean evaluate_signals;
/* XXX some signals can not be ignored */ /* XXX some signals can not be ignored */
@@ -435,12 +469,9 @@ int pthread_sigmask(
if ( !set ) if ( !set )
set_errno_and_return_minus_one( EFAULT ); set_errno_and_return_minus_one( EFAULT );
evaluate_signals = TRUE;
switch ( how ) { switch ( how ) {
case SIG_BLOCK: case SIG_BLOCK:
api->signals_blocked |= *set; api->signals_blocked |= *set;
evaluate_signals = FALSE;
break; break;
case SIG_UNBLOCK: case SIG_UNBLOCK:
api->signals_blocked &= ~*set; api->signals_blocked &= ~*set;
@@ -456,13 +487,11 @@ int pthread_sigmask(
/* XXX evaluate the new set */ /* XXX evaluate the new set */
if ( evaluate_signals == TRUE ) { if ( ~api->signals_blocked &
if ( ~api->signals_blocked & (api->signals_pending | _POSIX_signals_Pending) ) {
(api->signals_pending | _POSIX_signals_Pending) ) { api->signals_global_pending &= _POSIX_signals_Pending;
api->signals_global_pending &= _POSIX_signals_Pending; _Thread_Executing->do_post_task_switch_extension = TRUE;
_Thread_Executing->do_post_task_switch_extension = TRUE; _Thread_Dispatch();
_Thread_Dispatch();
}
} }
return 0; return 0;
@@ -622,9 +651,9 @@ int pthread_kill(
if ( api->signals_pending & ~api->signals_blocked ) { if ( api->signals_pending & ~api->signals_blocked ) {
the_thread->do_post_task_switch_extension = TRUE; the_thread->do_post_task_switch_extension = TRUE;
/* XXX may have to unblock the task -- this is a kludge -- fix it */ /* XXX unblock the task -- this is a kludge -- fix it */
if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) { if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
the_thread->Wait.return_code = EINTR; the_thread->Wait.return_code = EINTR;
if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) ) if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) )

View File

@@ -28,7 +28,7 @@
const pthread_attr_t _POSIX_Threads_Default_attributes = { const pthread_attr_t _POSIX_Threads_Default_attributes = {
TRUE, /* is_initialized */ TRUE, /* is_initialized */
NULL, /* stackaddr */ NULL, /* stackaddr */
STACK_MINIMUM_SIZE, /* stacksize */ STACK_MINIMUM_SIZE * 2, /* stacksize */
PTHREAD_SCOPE_PROCESS, /* contentionscope */ PTHREAD_SCOPE_PROCESS, /* contentionscope */
PTHREAD_EXPLICIT_SCHED, /* inheritsched */ PTHREAD_EXPLICIT_SCHED, /* inheritsched */
SCHED_FIFO, /* schedpolicy */ SCHED_FIFO, /* schedpolicy */