Hello,
I am porting the openPOWERLINK stack (Industrial Ethernet protocol
implementation) to RTEMS. Because RTEMS includes the POSIX layer, I
tried to reuse most of the Linux implementation of openPOWERLINK.
When it came to the timers, I discovered some differences of the POSIX
timer behaviour in RTEMS in respect to Linux. I don't know what the
POSIX standard says in that regard.
I adapted the RTEMS POSIX timers implementation to match Linux a little
bit more. The patches for RTEMS are provided as attachment.
If you need more information, or if you have any particular question,
feel free to contact me any time!
Best regards,
Daniel Krüger
--
SYS TEC electronic GmbH
Am Windrad 2
08468 Heinsdorfergrund
Telefon : +49 (0) 3765 38600-0
Fax : +49 (0) 3765 38600-4100
Email : daniel.krue...@systec-electronic.com
Website : http://www.systec-electronic.com
Managing Director : Dipl.-Phys. Siegmar Schmidt
Commercial registry : Amtsgericht Chemnitz, HRB 28082
>From c5946a3cba3bd85288b1177c3710ca1951d7b0b9 Mon Sep 17 00:00:00 2001
From: Daniel Krueger <daniel.krue...@systec-electronic.com>
Date: Fri, 28 Nov 2014 10:52:05 +0000
Subject: [PATCH 1/6] posix timer: Forward signal to all threads
Previously, the signal was sent only to the thread which created the
timer. But this semantic does not match the Linux one.
Signed-off-by: Daniel Krueger <daniel.krue...@systec-electronic.com>
---
cpukit/posix/src/timertsr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpukit/posix/src/timertsr.c b/cpukit/posix/src/timertsr.c
index fbbdf59..a9c1fce 100644
--- a/cpukit/posix/src/timertsr.c
+++ b/cpukit/posix/src/timertsr.c
@@ -72,7 +72,7 @@ void _POSIX_Timer_TSR(
* specified for that signal is simulated
*/
- if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) {
+ if ( kill ( getpid(), ptimer->inf.sigev_signo ) ) {
/* XXX error handling */
}
--
1.7.9.5
>From 2a7175600aaffd371a98653a5fd752bf9c726a99 Mon Sep 17 00:00:00 2001
From: Daniel Krueger <daniel.krue...@systec-electronic.com>
Date: Fri, 28 Nov 2014 10:57:04 +0000
Subject: [PATCH 2/6] testsuites/psxtimer01: Adapt to posix timer signal
forwarding change
Timer signals are forwarded to all threads now, so we need distinct
signals for the different threads.
Signed-off-by: Daniel Krueger <daniel.krue...@systec-electronic.com>
---
testsuites/psxtests/psxtimer01/psxtimer.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/testsuites/psxtests/psxtimer01/psxtimer.c b/testsuites/psxtests/psxtimer01/psxtimer.c
index 032e9f8..4cf5370 100644
--- a/testsuites/psxtests/psxtimer01/psxtimer.c
+++ b/testsuites/psxtests/psxtimer01/psxtimer.c
@@ -350,6 +350,8 @@ void *POSIX_Init (
/* mask signal */
sigemptyset (&set);
sigaddset (&set,SIGALRM);
+ sigaddset (&set,SIGRTMIN);
+ sigaddset (&set,SIGRTMIN+1);
pthread_sigmask (SIG_BLOCK,&set,NULL);
/* set mutex attributes */
@@ -421,7 +423,7 @@ void *POSIX_Init (
params_b.period.tv_sec = 2; /* seconds */
params_b.period.tv_nsec = 000000000; /* nanoseconds */
params_b.count = 10;
- params_b.signo = SIGALRM;
+ params_b.signo = SIGRTMIN;
if (pthread_create (&tb, &attr, task_b, ¶ms_b) != 0) {
perror ("Error in thread create for task b\n");
}
@@ -437,7 +439,7 @@ void *POSIX_Init (
params_c.period.tv_sec = 3; /* seconds */
params_c.period.tv_nsec = 000000000; /* nanoseconds */
params_c.count = 6;
- params_c.signo = SIGALRM;
+ params_c.signo = SIGRTMIN+1;
if (pthread_create (&tc, &attr, task_c, ¶ms_c) != 0) {
perror ("Error in thread create for task c\n");
}
@@ -450,7 +452,7 @@ void *POSIX_Init (
params_c1.period.tv_sec = 0; /* seconds */
params_c1.period.tv_nsec = 500000000; /* nanoseconds */
params_c1.count = 6;
- params_c1.signo = SIGALRM;
+ params_c1.signo = SIGRTMIN+1;
if (pthread_create (&tc1, &attr, task_c, ¶ms_c1) != 0) {
perror ("Error in thread create for task c1\n");
}
--
1.7.9.5
>From 928436068bad970b907d63ec6cb53160c570541e Mon Sep 17 00:00:00 2001
From: Daniel Krueger <daniel.krue...@systec-electronic.com>
Date: Fri, 28 Nov 2014 12:23:38 +0000
Subject: [PATCH 3/6] posix timer: Forward sigev_value to sigwaitinfo()
Signed-off-by: Daniel Krueger <daniel.krue...@systec-electronic.com>
---
cpukit/posix/src/timertsr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpukit/posix/src/timertsr.c b/cpukit/posix/src/timertsr.c
index a9c1fce..315e738 100644
--- a/cpukit/posix/src/timertsr.c
+++ b/cpukit/posix/src/timertsr.c
@@ -72,7 +72,7 @@ void _POSIX_Timer_TSR(
* specified for that signal is simulated
*/
- if ( kill ( getpid(), ptimer->inf.sigev_signo ) ) {
+ if ( killinfo ( getpid(), ptimer->inf.sigev_signo, &ptimer->inf.sigev_value ) ) {
/* XXX error handling */
}
--
1.7.9.5
>From c466a655048690ca650e3bc6008b1e0090d89cf4 Mon Sep 17 00:00:00 2001
From: Daniel Krueger <daniel.krue...@systec-electronic.com>
Date: Tue, 9 Dec 2014 16:10:09 +0000
Subject: [PATCH 4/6] Posix signals [1]: Put siginfo always into queue
even if there is no sigaction registered to this signal. This change
enables multiple timer signals (with the very same signal number) to
be queued and fetched with sigtimedwait().
Signed-off-by: Daniel Krueger <daniel.krue...@systec-electronic.com>
---
cpukit/posix/src/killinfo.c | 19 ++++++--------
cpukit/posix/src/psignalclearprocesssignals.c | 6 ++---
cpukit/posix/src/psignalclearsignals.c | 35 +++++++++++--------------
3 files changed, 26 insertions(+), 34 deletions(-)
diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c
index 5d3dded..0e464ea 100644
--- a/cpukit/posix/src/killinfo.c
+++ b/cpukit/posix/src/killinfo.c
@@ -336,19 +336,16 @@ post_process_signal:
*/
_POSIX_signals_Set_process_signals( mask );
- if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {
-
- psiginfo = (POSIX_signals_Siginfo_node *)
- _Chain_Get( &_POSIX_signals_Inactive_siginfo );
- if ( !psiginfo ) {
- _Thread_Enable_dispatch();
- rtems_set_errno_and_return_minus_one( EAGAIN );
- }
+ psiginfo = (POSIX_signals_Siginfo_node *)
+ _Chain_Get( &_POSIX_signals_Inactive_siginfo );
+ if ( !psiginfo ) {
+ _Thread_Enable_dispatch();
+ rtems_set_errno_and_return_minus_one( EAGAIN );
+ }
- psiginfo->Info = *siginfo;
+ psiginfo->Info = *siginfo;
- _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );
- }
+ _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );
DEBUG_STEP("\n");
_Thread_Enable_dispatch();
diff --git a/cpukit/posix/src/psignalclearprocesssignals.c b/cpukit/posix/src/psignalclearprocesssignals.c
index 2ec1bbe..037d7f6 100644
--- a/cpukit/posix/src/psignalclearprocesssignals.c
+++ b/cpukit/posix/src/psignalclearprocesssignals.c
@@ -33,10 +33,8 @@ void _POSIX_signals_Clear_process_signals(
clear_signal = true;
mask = signo_to_mask( signo );
- if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) {
- if ( !_Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) )
- clear_signal = false;
- }
+ if ( !_Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) )
+ clear_signal = false;
if ( clear_signal ) {
_POSIX_signals_Pending &= ~mask;
diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c
index 8999145..8b82d69 100644
--- a/cpukit/posix/src/psignalclearsignals.c
+++ b/cpukit/posix/src/psignalclearsignals.c
@@ -74,26 +74,23 @@ bool _POSIX_signals_Clear_signals(
if ( is_global ) {
if ( mask & (_POSIX_signals_Pending & signals_blocked) ) {
- if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) {
- psiginfo = (POSIX_signals_Siginfo_node *)
- _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] );
- _POSIX_signals_Clear_process_signals( signo );
- /*
- * It may be impossible to get here with an empty chain
- * BUT until that is proven we need to be defensive and
- * protect against it.
- */
- if ( psiginfo ) {
- *info = psiginfo->Info;
- _Chain_Append_unprotected(
- &_POSIX_signals_Inactive_siginfo,
- &psiginfo->Node
- );
- } else
- do_callout = false;
- }
+ psiginfo = (POSIX_signals_Siginfo_node *)
+ _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] );
_POSIX_signals_Clear_process_signals( signo );
- do_callout = true;
+ /*
+ * It may be impossible to get here with an empty chain
+ * BUT until that is proven we need to be defensive and
+ * protect against it.
+ */
+ if ( psiginfo ) {
+ *info = psiginfo->Info;
+ _Chain_Append_unprotected(
+ &_POSIX_signals_Inactive_siginfo,
+ &psiginfo->Node
+ );
+ do_callout = true;
+ } else
+ do_callout = false;
}
} else {
if ( mask & (api->signals_pending & signals_blocked) ) {
--
1.7.9.5
>From 854f237ea94321afa9f6e9559485bf3954387dd0 Mon Sep 17 00:00:00 2001
From: Daniel Krueger <daniel.krue...@systec-electronic.com>
Date: Tue, 9 Dec 2014 16:13:17 +0000
Subject: [PATCH 5/6] Posix signals [2]: Use siginfo from queue in
sigtimedwait()
If siginfo structure is set by _POSIX_signals_Clear_signals(), then
use it. Especially the element si_value is important. si_code is
currently always SI_USER, because it is not set properly by producer.
Signed-off-by: Daniel Krueger <daniel.krue...@systec-electronic.com>
---
cpukit/posix/src/sigtimedwait.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c
index 4c456dd..21f79af 100644
--- a/cpukit/posix/src/sigtimedwait.c
+++ b/cpukit/posix/src/sigtimedwait.c
@@ -117,6 +117,8 @@ int sigtimedwait(
/* API signals pending? */
+ the_info->si_signo = -1;
+
_POSIX_signals_Acquire( &lock_context );
if ( *set & api->signals_pending ) {
/* XXX real info later */
@@ -143,14 +145,14 @@ int sigtimedwait(
_POSIX_signals_Clear_signals( api, signo, the_info, true, false, false );
_POSIX_signals_Release( &lock_context );
- the_info->si_signo = signo;
- the_info->si_code = SI_USER;
- the_info->si_value.sival_int = 0;
+ if (the_info->si_signo == -1) {
+ the_info->si_signo = signo;
+ the_info->si_code = SI_USER;
+ the_info->si_value.sival_int = 0;
+ }
return signo;
}
- the_info->si_signo = -1;
-
_Thread_Disable_dispatch();
executing->Wait.queue = &_POSIX_signals_Wait_queue;
executing->Wait.return_code = EINTR;
--
1.7.9.5
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel