diff options
-rw-r--r-- | cpukit/posix/include/rtems/posix/psignalimpl.h | 12 | ||||
-rw-r--r-- | cpukit/posix/src/psignal.c | 8 | ||||
-rw-r--r-- | cpukit/posix/src/psignalchecksignal.c | 2 | ||||
-rw-r--r-- | cpukit/posix/src/psignalclearsignals.c | 14 | ||||
-rw-r--r-- | cpukit/posix/src/psignalsetprocesssignals.c | 4 | ||||
-rw-r--r-- | cpukit/posix/src/sigtimedwait.c | 20 | ||||
-rw-r--r-- | testsuites/psxtests/psxsignal05/init.c | 3 |
7 files changed, 46 insertions, 17 deletions
diff --git a/cpukit/posix/include/rtems/posix/psignalimpl.h b/cpukit/posix/include/rtems/posix/psignalimpl.h index 2dd1ed6739..c496fd33bd 100644 --- a/cpukit/posix/include/rtems/posix/psignalimpl.h +++ b/cpukit/posix/include/rtems/posix/psignalimpl.h @@ -32,6 +32,7 @@ #include <rtems/posix/pthread.h> #include <rtems/posix/sigset.h> #include <rtems/score/apiext.h> +#include <rtems/score/isrlock.h> #include <rtems/score/threadq.h> #define _States_Is_interruptible_signal( _states ) \ @@ -54,6 +55,8 @@ * Variables */ +extern ISR_lock_Control _POSIX_signals_Lock; + extern sigset_t _POSIX_signals_Pending; extern const struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ]; @@ -77,6 +80,12 @@ extern API_extensions_Post_switch_control _POSIX_signals_Post_switch; */ void _POSIX_signals_Manager_Initialization(void); +#define _POSIX_signals_Acquire( level ) \ + _ISR_lock_ISR_disable_and_acquire( &_POSIX_signals_Lock, level ) + +#define _POSIX_signals_Release( level ) \ + _ISR_lock_Release_and_ISR_enable( &_POSIX_signals_Lock, level ) + static inline void _POSIX_signals_Add_post_switch_extension(void) { _API_extensions_Add_post_switch( &_POSIX_signals_Post_switch ); @@ -110,7 +119,8 @@ bool _POSIX_signals_Clear_signals( int signo, siginfo_t *info, bool is_global, - bool check_blocked + bool check_blocked, + bool do_signals_acquire_release ); int killinfo( diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c index 1778cece17..5258b2bf9e 100644 --- a/cpukit/posix/src/psignal.c +++ b/cpukit/posix/src/psignal.c @@ -45,6 +45,8 @@ RTEMS_STATIC_ASSERT( /*** PROCESS WIDE STUFF ****/ +ISR_lock_Control _POSIX_signals_Lock = ISR_LOCK_INITIALIZER; + sigset_t _POSIX_signals_Pending; void _POSIX_signals_Abnormal_termination_handler( @@ -144,13 +146,13 @@ static void _POSIX_signals_Post_switch_hook( * processed at all. No point in doing this loop otherwise. */ while (1) { - _ISR_Disable( level ); + _POSIX_signals_Acquire( level ); if ( !(~api->signals_blocked & (api->signals_pending | _POSIX_signals_Pending)) ) { - _ISR_Enable( level ); + _POSIX_signals_Release( level ); break; } - _ISR_Enable( level ); + _POSIX_signals_Release( level ); for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { _POSIX_signals_Check_signal( api, signo, false ); diff --git a/cpukit/posix/src/psignalchecksignal.c b/cpukit/posix/src/psignalchecksignal.c index cb3703e3eb..468fd62f0a 100644 --- a/cpukit/posix/src/psignalchecksignal.c +++ b/cpukit/posix/src/psignalchecksignal.c @@ -49,7 +49,7 @@ bool _POSIX_signals_Check_signal( Thread_Control *executing; if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct, - is_global, true ) ) + is_global, true, true ) ) return false; /* diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c index 389c3352bd..88de41c788 100644 --- a/cpukit/posix/src/psignalclearsignals.c +++ b/cpukit/posix/src/psignalclearsignals.c @@ -42,7 +42,8 @@ bool _POSIX_signals_Clear_signals( int signo, siginfo_t *info, bool is_global, - bool check_blocked + bool check_blocked, + bool do_signals_acquire_release ) { sigset_t mask; @@ -67,7 +68,10 @@ bool _POSIX_signals_Clear_signals( /* XXX is this right for siginfo type signals? */ /* XXX are we sure they can be cleared the same way? */ - _ISR_Disable( level ); + if ( do_signals_acquire_release ) { + _POSIX_signals_Acquire( level ); + } + if ( is_global ) { if ( mask & (_POSIX_signals_Pending & signals_blocked) ) { if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) { @@ -97,6 +101,10 @@ bool _POSIX_signals_Clear_signals( do_callout = true; } } - _ISR_Enable( level ); + + if ( do_signals_acquire_release ) { + _POSIX_signals_Release( level ); + } + return do_callout; } diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c index 3ad1c8ae31..9cce233ec8 100644 --- a/cpukit/posix/src/psignalsetprocesssignals.c +++ b/cpukit/posix/src/psignalsetprocesssignals.c @@ -39,7 +39,7 @@ void _POSIX_signals_Set_process_signals( { ISR_Level level; - _ISR_Disable( level ); + _POSIX_signals_Acquire( level ); _POSIX_signals_Pending |= mask; - _ISR_Enable( level ); + _POSIX_signals_Release( level ); } diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c index 65454ac7a3..a7fbc1f7d3 100644 --- a/cpukit/posix/src/sigtimedwait.c +++ b/cpukit/posix/src/sigtimedwait.c @@ -117,7 +117,7 @@ int sigtimedwait( /* API signals pending? */ - _ISR_Disable( level ); + _POSIX_signals_Acquire( level ); if ( *set & api->signals_pending ) { /* XXX real info later */ the_info->si_signo = _POSIX_signals_Get_lowest( api->signals_pending ); @@ -126,9 +126,10 @@ int sigtimedwait( the_info->si_signo, the_info, false, + false, false ); - _ISR_Enable( level ); + _POSIX_signals_Release( level ); the_info->si_code = SI_USER; the_info->si_value.sival_int = 0; @@ -139,8 +140,8 @@ int sigtimedwait( if ( *set & _POSIX_signals_Pending ) { signo = _POSIX_signals_Get_lowest( _POSIX_signals_Pending ); - _POSIX_signals_Clear_signals( api, signo, the_info, true, false ); - _ISR_Enable( level ); + _POSIX_signals_Clear_signals( api, signo, the_info, true, false, false ); + _POSIX_signals_Release( level ); the_info->si_signo = signo; the_info->si_code = SI_USER; @@ -156,7 +157,7 @@ int sigtimedwait( executing->Wait.option = *set; executing->Wait.return_argument = the_info; _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue ); - _ISR_Enable( level ); + _POSIX_signals_Release( level ); _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, executing, interval ); _Thread_Enable_dispatch(); @@ -165,7 +166,14 @@ int sigtimedwait( * the signal. */ - _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false ); + _POSIX_signals_Clear_signals( + api, + the_info->si_signo, + the_info, + false, + false, + true + ); /* Set errno only if return code is not EINTR or * if EINTR was caused by a signal being caught, which diff --git a/testsuites/psxtests/psxsignal05/init.c b/testsuites/psxtests/psxsignal05/init.c index dbd812c560..73c25a4251 100644 --- a/testsuites/psxtests/psxsignal05/init.c +++ b/testsuites/psxtests/psxsignal05/init.c @@ -79,7 +79,8 @@ void *POSIX_Init( SIGNAL_ONE, &info, true, /* is_global */ - false /* check_blocked */ + false, /* check_blocked */ + true /* do_signals_acquire_release */ ); rtems_test_assert( bc ); |