[rtems commit] posix: Add and use _POSIX_signals_Acquire()
Sebastian Huber
sebh at rtems.org
Tue Aug 27 10:45:34 UTC 2013
Module: rtems
Branch: master
Commit: 7d9fff6e283e4adb114dee487a56f6e55a393a9e
Changeset: http://git.rtems.org/rtems/commit/?id=7d9fff6e283e4adb114dee487a56f6e55a393a9e
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Mon Aug 26 17:39:00 2013 +0200
posix: Add and use _POSIX_signals_Acquire()
Add and use _POSIX_signals_Release(). The post-switch handler is not
protected by disabled thread dispatching. Use proper SMP lock for
signal management.
---
cpukit/posix/include/rtems/posix/psignalimpl.h | 12 +++++++++++-
cpukit/posix/src/psignal.c | 8 +++++---
cpukit/posix/src/psignalchecksignal.c | 2 +-
cpukit/posix/src/psignalclearsignals.c | 14 +++++++++++---
cpukit/posix/src/psignalsetprocesssignals.c | 4 ++--
cpukit/posix/src/sigtimedwait.c | 20 ++++++++++++++------
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 2dd1ed6..c496fd3 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 1778cec..5258b2b 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 cb3703e..468fd62 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 389c335..88de41c 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 3ad1c8a..9cce233 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 65454ac..a7fbc1f 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 dbd812c..73c25a4 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 );
More information about the vc
mailing list