diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-08-26 16:03:35 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-08-27 10:48:17 +0200 |
commit | 75f6d18ee0a470c092216249ab1dc6f3c5187dea (patch) | |
tree | 33691f1b1c80c0223fb8413eac92563c18fa8764 | |
parent | ringbuf: Add SMP support (diff) | |
download | rtems-75f6d18ee0a470c092216249ab1dc6f3c5187dea.tar.bz2 |
rtems: Add SMP support for signals
Add and use _ASR_Get_posted_signals(). The post-switch handler is not
protected by disabled thread dispatching. Use proper SMP lock for
signal management.
-rw-r--r-- | cpukit/rtems/include/rtems/rtems/asr.h | 3 | ||||
-rw-r--r-- | cpukit/rtems/include/rtems/rtems/asrimpl.h | 52 | ||||
-rw-r--r-- | cpukit/rtems/src/signalcatch.c | 8 | ||||
-rw-r--r-- | cpukit/rtems/src/signalsend.c | 4 |
4 files changed, 40 insertions, 27 deletions
diff --git a/cpukit/rtems/include/rtems/rtems/asr.h b/cpukit/rtems/include/rtems/rtems/asr.h index 225b0b9e37..f543b5053c 100644 --- a/cpukit/rtems/include/rtems/rtems/asr.h +++ b/cpukit/rtems/include/rtems/rtems/asr.h @@ -22,6 +22,7 @@ #ifndef _RTEMS_RTEMS_ASR_H #define _RTEMS_RTEMS_ASR_H +#include <rtems/score/isrlock.h> #include <rtems/rtems/modes.h> #ifdef __cplusplus @@ -73,6 +74,8 @@ typedef struct { rtems_signal_set signals_pending; /** This field indicates if nest level of signals being processed */ uint32_t nest_level; + /** Lock to protect this structure */ + ISR_lock_Control Lock; } ASR_Information; /* diff --git a/cpukit/rtems/include/rtems/rtems/asrimpl.h b/cpukit/rtems/include/rtems/rtems/asrimpl.h index dc7da55dfe..ebb405279b 100644 --- a/cpukit/rtems/include/rtems/rtems/asrimpl.h +++ b/cpukit/rtems/include/rtems/rtems/asrimpl.h @@ -18,7 +18,6 @@ #define _RTEMS_RTEMS_ASRIMPL_H #include <rtems/rtems/asr.h> -#include <rtems/score/isrlevel.h> #ifdef __cplusplus extern "C" { @@ -38,15 +37,16 @@ extern "C" { * This routine initializes the given RTEMS_ASR information record. */ RTEMS_INLINE_ROUTINE void _ASR_Initialize ( - ASR_Information *information + ASR_Information *asr ) { - information->is_enabled = false; - information->handler = NULL; - information->mode_set = RTEMS_DEFAULT_MODES; - information->signals_posted = 0; - information->signals_pending = 0; - information->nest_level = 0; + asr->is_enabled = false; + asr->handler = NULL; + asr->mode_set = RTEMS_DEFAULT_MODES; + asr->signals_posted = 0; + asr->signals_pending = 0; + asr->nest_level = 0; + _ISR_lock_Initialize( &asr->Lock ); } /** @@ -57,17 +57,17 @@ RTEMS_INLINE_ROUTINE void _ASR_Initialize ( * way that the RTEMS_ASR disable/enable flag changes. */ RTEMS_INLINE_ROUTINE void _ASR_Swap_signals ( - ASR_Information *information + ASR_Information *asr ) { rtems_signal_set _signals; ISR_Level _level; - _ISR_Disable( _level ); - _signals = information->signals_pending; - information->signals_pending = information->signals_posted; - information->signals_posted = _signals; - _ISR_Enable( _level ); + _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level ); + _signals = asr->signals_pending; + asr->signals_pending = asr->signals_posted; + asr->signals_posted = _signals; + _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level ); } /** @@ -90,10 +90,10 @@ RTEMS_INLINE_ROUTINE bool _ASR_Is_null_handler ( * given RTEMS_ASR information record and FALSE otherwise. */ RTEMS_INLINE_ROUTINE bool _ASR_Are_signals_pending ( - ASR_Information *information + ASR_Information *asr ) { - return information->signals_posted != 0; + return asr->signals_posted != 0; } /** @@ -105,15 +105,31 @@ RTEMS_INLINE_ROUTINE bool _ASR_Are_signals_pending ( * NOTE: This must be implemented as a macro. */ RTEMS_INLINE_ROUTINE void _ASR_Post_signals( + ASR_Information *asr, rtems_signal_set signals, rtems_signal_set *signal_set ) { ISR_Level _level; - _ISR_Disable( _level ); + _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level ); *signal_set |= signals; - _ISR_Enable( _level ); + _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level ); +} + +RTEMS_INLINE_ROUTINE rtems_signal_set _ASR_Get_posted_signals( + ASR_Information *asr +) +{ + rtems_signal_set signal_set; + ISR_Level _level; + + _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level ); + signal_set = asr->signals_posted; + asr->signals_posted = 0; + _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level ); + + return signal_set; } /**@}*/ diff --git a/cpukit/rtems/src/signalcatch.c b/cpukit/rtems/src/signalcatch.c index 3493e729e2..a5e5ef88f4 100644 --- a/cpukit/rtems/src/signalcatch.c +++ b/cpukit/rtems/src/signalcatch.c @@ -27,7 +27,6 @@ static void _RTEMS_signal_Post_switch_hook( Thread_Control *executing ) { - ISR_Level level; RTEMS_API_Control *api; ASR_Information *asr; rtems_signal_set signal_set; @@ -42,12 +41,7 @@ static void _RTEMS_signal_Post_switch_hook( Thread_Control *executing ) */ asr = &api->Signal; - - _ISR_Disable( level ); - signal_set = asr->signals_posted; - asr->signals_posted = 0; - _ISR_Enable( level ); - + signal_set = _ASR_Get_posted_signals( asr ); if ( !signal_set ) /* similar to _ASR_Are_signals_pending( asr ) */ return; diff --git a/cpukit/rtems/src/signalsend.c b/cpukit/rtems/src/signalsend.c index f1c7b2c254..c231235cd9 100644 --- a/cpukit/rtems/src/signalsend.c +++ b/cpukit/rtems/src/signalsend.c @@ -46,10 +46,10 @@ rtems_status_code rtems_signal_send( if ( ! _ASR_Is_null_handler( asr->handler ) ) { if ( asr->is_enabled ) { - _ASR_Post_signals( signal_set, &asr->signals_posted ); + _ASR_Post_signals( asr, signal_set, &asr->signals_posted ); _Thread_Signal_notification( the_thread ); } else { - _ASR_Post_signals( signal_set, &asr->signals_pending ); + _ASR_Post_signals( asr, signal_set, &asr->signals_pending ); } _Objects_Put( &the_thread->Object ); return RTEMS_SUCCESSFUL; |