summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-26 17:39:00 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-27 12:51:46 +0200
commit7d9fff6e283e4adb114dee487a56f6e55a393a9e (patch)
tree8e87cc80bce58f41d2b4a37cd24ef3ddcbfeec17
parentscore: Add SMP support to _Watchdog_Report_chain() (diff)
downloadrtems-7d9fff6e283e4adb114dee487a56f6e55a393a9e.tar.bz2
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.
-rw-r--r--cpukit/posix/include/rtems/posix/psignalimpl.h12
-rw-r--r--cpukit/posix/src/psignal.c8
-rw-r--r--cpukit/posix/src/psignalchecksignal.c2
-rw-r--r--cpukit/posix/src/psignalclearsignals.c14
-rw-r--r--cpukit/posix/src/psignalsetprocesssignals.c4
-rw-r--r--cpukit/posix/src/sigtimedwait.c20
-rw-r--r--testsuites/psxtests/psxsignal05/init.c3
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 );