[rtems commit] rtems: Add SMP support for signals
Sebastian Huber
sebh at rtems.org
Tue Aug 27 08:44:49 UTC 2013
Module: rtems
Branch: master
Commit: 75f6d18ee0a470c092216249ab1dc6f3c5187dea
Changeset: http://git.rtems.org/rtems/commit/?id=75f6d18ee0a470c092216249ab1dc6f3c5187dea
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Mon Aug 26 16:03:35 2013 +0200
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.
---
cpukit/rtems/include/rtems/rtems/asr.h | 3 ++
cpukit/rtems/include/rtems/rtems/asrimpl.h | 52 ++++++++++++++++++----------
cpukit/rtems/src/signalcatch.c | 8 +----
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 225b0b9..f543b50 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 dc7da55..ebb4052 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 3493e72..a5e5ef8 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 f1c7b2c..c231235 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;
More information about the vc
mailing list