summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-26 16:03:35 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-27 10:48:17 +0200
commit75f6d18ee0a470c092216249ab1dc6f3c5187dea (patch)
tree33691f1b1c80c0223fb8413eac92563c18fa8764
parentringbuf: Add SMP support (diff)
downloadrtems-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.h3
-rw-r--r--cpukit/rtems/include/rtems/rtems/asrimpl.h52
-rw-r--r--cpukit/rtems/src/signalcatch.c8
-rw-r--r--cpukit/rtems/src/signalsend.c4
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;