Removed alarm(), killinfo() and pause() because they are now in their own file.

This commit is contained in:
Joel Sherrill
1999-04-15 18:58:02 +00:00
parent 93994fdb80
commit da41ecbcfe
2 changed files with 2 additions and 744 deletions

View File

@@ -36,23 +36,11 @@
sigset_t _POSIX_signals_Pending;
void _POSIX_signals_Abormal_termination_handler( int signo )
void _POSIX_signals_Abnormal_termination_handler( int signo )
{
exit( 1 );
}
#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,
@@ -923,317 +911,6 @@ int sigwait(
return errno;
}
/*PAGE
*
* 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68
*
* NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS.
*/
#define _POSIX_signals_Is_interested( _api, _mask ) \
( ~(_api)->signals_blocked & (_mask) )
int killinfo(
pid_t pid,
int sig,
const union sigval *value
)
{
sigset_t mask;
POSIX_API_Control *api;
unsigned32 the_class;
unsigned32 index;
unsigned32 maximum;
Objects_Information *the_info;
Objects_Control **object_table;
Thread_Control *the_thread;
Thread_Control *interested_thread;
Priority_Control interested_priority;
Chain_Control *the_chain;
Chain_Node *the_node;
siginfo_t siginfo_struct;
siginfo_t *siginfo;
POSIX_signals_Siginfo_node *psiginfo;
/*
* Only supported for the "calling process" (i.e. this node).
*/
if( pid != getpid() )
set_errno_and_return_minus_one( ESRCH );
/*
* Validate the signal passed if not 0.
*/
if ( sig && !is_valid_signo(sig) )
{
set_errno_and_return_minus_one( EINVAL );
}
/*
* If the signal is being ignored, then we are out of here.
*/
if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
{
return 0;
}
/*
* P1003.1c/Draft 10, p. 33 says that certain signals should always
* be directed to the executing thread such as those caused by hardware
* faults.
*/
switch ( sig ) {
case SIGFPE:
case SIGILL:
case SIGSEGV:
return pthread_kill( pthread_self(), sig );
default:
break;
}
mask = signo_to_mask( sig );
/*
* Build up a siginfo structure
*/
siginfo = &siginfo_struct;
siginfo->si_signo = sig;
siginfo->si_code = SI_USER;
if ( !value ) {
siginfo->si_value.sival_int = 0;
} else {
siginfo->si_value = *value;
}
_Thread_Disable_dispatch();
/*
* Is the currently executing thread interested? If so then it will
* get it an execute it as soon as the dispatcher executes.
*/
the_thread = _Thread_Executing;
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ( _POSIX_signals_Is_interested( api, mask ) ) {
goto process_it;
}
/*
* Is an interested thread waiting for this signal (sigwait())?
*/
/* XXX violation of visibility -- need to define thread queue support */
for( index=0 ;
index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
index++ ) {
the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ];
for ( the_node = the_chain->first ;
!_Chain_Is_tail( the_chain, the_node ) ;
the_node = the_node->next ) {
the_thread = (Thread_Control *)the_node;
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) {
goto process_it;
}
}
}
/*
* Is any other thread interested? The highest priority interested
* thread is selected. In the event of a tie, then the following
* additional criteria is used:
*
* + ready thread over blocked
* + blocked on call interruptible by signal (can return EINTR)
* + blocked on call not interruptible by signal
*
* This looks at every thread in the system regardless of the creating API.
*
* NOTES:
*
* + rtems internal threads do not receive signals.
*/
interested_thread = NULL;
interested_priority = PRIORITY_MAXIMUM + 1;
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
the_class++ ) {
if ( the_class == OBJECTS_INTERNAL_THREADS )
continue;
the_info = _Objects_Information_table[ the_class ];
if ( !the_info ) /* manager not installed */
continue;
maximum = the_info->maximum;
object_table = the_info->local_table;
assert( object_table ); /* always at least 1 entry */
for ( index = 1 ; index <= maximum ; index++ ) {
the_thread = (Thread_Control *) object_table[ index ];
if ( !the_thread )
continue;
/*
* If this thread is of lower priority than the interested thread,
* go on to the next thread.
*/
if ( the_thread->current_priority > interested_priority )
continue;
/*
* If this thread is not interested, then go on to the next thread.
*/
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ( !api || !_POSIX_signals_Is_interested( api, mask ) )
continue;
/*
* Now we know the thread under connsideration is interested.
* If the thread under consideration is of higher priority, then
* it becomes the interested thread.
*/
if ( the_thread->current_priority < interested_priority ) {
interested_thread = the_thread;
interested_priority = the_thread->current_priority;
continue;
}
/*
* Now the thread and the interested thread have the same priority.
* If the interested thread is ready, then we don't need to send it
* to a blocked thread.
*/
if ( _States_Is_ready( interested_thread->current_state ) )
continue;
/*
* Now the interested thread is blocked.
* If the thread we are considering is not, the it becomes the
* interested thread.
*/
if ( _States_Is_ready( the_thread->current_state ) ) {
interested_thread = the_thread;
interested_priority = the_thread->current_priority;
continue;
}
/*
* Now we know both threads are blocked.
* If the interested thread is interruptible, then just use it.
*/
/* XXX need a new states macro */
if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL )
continue;
/*
* Now both threads are blocked and the interested thread is not
* interruptible.
* If the thread under consideration is interruptible by a signal,
* then it becomes the interested thread.
*/
/* XXX need a new states macro */
if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
interested_thread = the_thread;
interested_priority = the_thread->current_priority;
}
}
}
if ( interested_thread ) {
the_thread = interested_thread;
goto process_it;
}
/*
* OK so no threads were interested right now. It will be left on the
* global pending until a thread receives it. The global set of threads
* can change interest in this signal in one of the following ways:
*
* + a thread is created with the signal unblocked,
* + pthread_sigmask() unblocks the signal,
* + sigprocmask() unblocks the signal, OR
* + sigaction() which changes the handler to SIG_IGN.
*/
the_thread = NULL;
goto post_process_signal;
/*
* We found a thread which was interested, so now we mark that this
* thread needs to do the post context switch extension so it can
* evaluate the signals pending.
*/
process_it:
the_thread->do_post_task_switch_extension = TRUE;
/*
* Returns TRUE if the signal was synchronously given to a thread
* blocked waiting for the signal.
*/
if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) {
_Thread_Enable_dispatch();
return 0;
}
post_process_signal:
/*
* We may have woken up a thread but we definitely need to post the
* signal to the process wide information set.
*/
_POSIX_signals_Set_process_signals( mask );
if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {
psiginfo = (POSIX_signals_Siginfo_node *)
_Chain_Get( &_POSIX_signals_Inactive_siginfo );
if ( !psiginfo )
{
set_errno_and_return_minus_one( EAGAIN );
}
psiginfo->Info = *siginfo;
_Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );
}
_Thread_Enable_dispatch();
return 0;
}
/*
* 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78
*/
@@ -1306,51 +983,3 @@ int pthread_kill(
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
)
{
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;
}
/*
* 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81
*/
int pause( void )
{
sigset_t all_signals;
int status;
(void) sigfillset( &all_signals );
status = sigtimedwait( &all_signals, NULL, NULL );
return status;
}

View File

@@ -36,23 +36,11 @@
sigset_t _POSIX_signals_Pending;
void _POSIX_signals_Abormal_termination_handler( int signo )
void _POSIX_signals_Abnormal_termination_handler( int signo )
{
exit( 1 );
}
#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,
@@ -923,317 +911,6 @@ int sigwait(
return errno;
}
/*PAGE
*
* 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68
*
* NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS.
*/
#define _POSIX_signals_Is_interested( _api, _mask ) \
( ~(_api)->signals_blocked & (_mask) )
int killinfo(
pid_t pid,
int sig,
const union sigval *value
)
{
sigset_t mask;
POSIX_API_Control *api;
unsigned32 the_class;
unsigned32 index;
unsigned32 maximum;
Objects_Information *the_info;
Objects_Control **object_table;
Thread_Control *the_thread;
Thread_Control *interested_thread;
Priority_Control interested_priority;
Chain_Control *the_chain;
Chain_Node *the_node;
siginfo_t siginfo_struct;
siginfo_t *siginfo;
POSIX_signals_Siginfo_node *psiginfo;
/*
* Only supported for the "calling process" (i.e. this node).
*/
if( pid != getpid() )
set_errno_and_return_minus_one( ESRCH );
/*
* Validate the signal passed if not 0.
*/
if ( sig && !is_valid_signo(sig) )
{
set_errno_and_return_minus_one( EINVAL );
}
/*
* If the signal is being ignored, then we are out of here.
*/
if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
{
return 0;
}
/*
* P1003.1c/Draft 10, p. 33 says that certain signals should always
* be directed to the executing thread such as those caused by hardware
* faults.
*/
switch ( sig ) {
case SIGFPE:
case SIGILL:
case SIGSEGV:
return pthread_kill( pthread_self(), sig );
default:
break;
}
mask = signo_to_mask( sig );
/*
* Build up a siginfo structure
*/
siginfo = &siginfo_struct;
siginfo->si_signo = sig;
siginfo->si_code = SI_USER;
if ( !value ) {
siginfo->si_value.sival_int = 0;
} else {
siginfo->si_value = *value;
}
_Thread_Disable_dispatch();
/*
* Is the currently executing thread interested? If so then it will
* get it an execute it as soon as the dispatcher executes.
*/
the_thread = _Thread_Executing;
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ( _POSIX_signals_Is_interested( api, mask ) ) {
goto process_it;
}
/*
* Is an interested thread waiting for this signal (sigwait())?
*/
/* XXX violation of visibility -- need to define thread queue support */
for( index=0 ;
index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
index++ ) {
the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ];
for ( the_node = the_chain->first ;
!_Chain_Is_tail( the_chain, the_node ) ;
the_node = the_node->next ) {
the_thread = (Thread_Control *)the_node;
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) {
goto process_it;
}
}
}
/*
* Is any other thread interested? The highest priority interested
* thread is selected. In the event of a tie, then the following
* additional criteria is used:
*
* + ready thread over blocked
* + blocked on call interruptible by signal (can return EINTR)
* + blocked on call not interruptible by signal
*
* This looks at every thread in the system regardless of the creating API.
*
* NOTES:
*
* + rtems internal threads do not receive signals.
*/
interested_thread = NULL;
interested_priority = PRIORITY_MAXIMUM + 1;
for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
the_class++ ) {
if ( the_class == OBJECTS_INTERNAL_THREADS )
continue;
the_info = _Objects_Information_table[ the_class ];
if ( !the_info ) /* manager not installed */
continue;
maximum = the_info->maximum;
object_table = the_info->local_table;
assert( object_table ); /* always at least 1 entry */
for ( index = 1 ; index <= maximum ; index++ ) {
the_thread = (Thread_Control *) object_table[ index ];
if ( !the_thread )
continue;
/*
* If this thread is of lower priority than the interested thread,
* go on to the next thread.
*/
if ( the_thread->current_priority > interested_priority )
continue;
/*
* If this thread is not interested, then go on to the next thread.
*/
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
if ( !api || !_POSIX_signals_Is_interested( api, mask ) )
continue;
/*
* Now we know the thread under connsideration is interested.
* If the thread under consideration is of higher priority, then
* it becomes the interested thread.
*/
if ( the_thread->current_priority < interested_priority ) {
interested_thread = the_thread;
interested_priority = the_thread->current_priority;
continue;
}
/*
* Now the thread and the interested thread have the same priority.
* If the interested thread is ready, then we don't need to send it
* to a blocked thread.
*/
if ( _States_Is_ready( interested_thread->current_state ) )
continue;
/*
* Now the interested thread is blocked.
* If the thread we are considering is not, the it becomes the
* interested thread.
*/
if ( _States_Is_ready( the_thread->current_state ) ) {
interested_thread = the_thread;
interested_priority = the_thread->current_priority;
continue;
}
/*
* Now we know both threads are blocked.
* If the interested thread is interruptible, then just use it.
*/
/* XXX need a new states macro */
if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL )
continue;
/*
* Now both threads are blocked and the interested thread is not
* interruptible.
* If the thread under consideration is interruptible by a signal,
* then it becomes the interested thread.
*/
/* XXX need a new states macro */
if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
interested_thread = the_thread;
interested_priority = the_thread->current_priority;
}
}
}
if ( interested_thread ) {
the_thread = interested_thread;
goto process_it;
}
/*
* OK so no threads were interested right now. It will be left on the
* global pending until a thread receives it. The global set of threads
* can change interest in this signal in one of the following ways:
*
* + a thread is created with the signal unblocked,
* + pthread_sigmask() unblocks the signal,
* + sigprocmask() unblocks the signal, OR
* + sigaction() which changes the handler to SIG_IGN.
*/
the_thread = NULL;
goto post_process_signal;
/*
* We found a thread which was interested, so now we mark that this
* thread needs to do the post context switch extension so it can
* evaluate the signals pending.
*/
process_it:
the_thread->do_post_task_switch_extension = TRUE;
/*
* Returns TRUE if the signal was synchronously given to a thread
* blocked waiting for the signal.
*/
if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) {
_Thread_Enable_dispatch();
return 0;
}
post_process_signal:
/*
* We may have woken up a thread but we definitely need to post the
* signal to the process wide information set.
*/
_POSIX_signals_Set_process_signals( mask );
if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {
psiginfo = (POSIX_signals_Siginfo_node *)
_Chain_Get( &_POSIX_signals_Inactive_siginfo );
if ( !psiginfo )
{
set_errno_and_return_minus_one( EAGAIN );
}
psiginfo->Info = *siginfo;
_Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );
}
_Thread_Enable_dispatch();
return 0;
}
/*
* 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78
*/
@@ -1306,51 +983,3 @@ int pthread_kill(
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
)
{
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;
}
/*
* 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81
*/
int pause( void )
{
sigset_t all_signals;
int status;
(void) sigfillset( &all_signals );
status = sigtimedwait( &all_signals, NULL, NULL );
return status;
}