[Bug 565] New: Periodicity of thread not guaranteed under (preempt-rt) gnulinux

For more infomation about this bug, visit
Summary: Periodicity of thread not guaranteed under (preempt-rt)
gnulinux
Product: RTT
Version: 1.4.0
Platform: All
OS/Version: GNU/Linux
Status: NEW
Severity: major
Priority: P2
Component: Operating System Abstraction - Portability
AssignedTo: orocos-dev [..] ...
ReportedBy: peter [dot] soetens [..] ...
CC: orocos-dev [..] ...
Estimated Hours: 0.0

The following code in gnulinux/fosi_internal.cpp contains a race condition,
which disturbs deterministic periodic execution, even under PREEMPT-RT.

INTERNAL_QUAL int rtos_task_wait_period( RTOS_TASK* task )
{
if ( task->period == 0 )
return 0;

//rtos_printf("Time is %lld nsec, Mark is %lld
nsec.\n",rtos_get_time_ns(), task->periodMark );
// CALCULATE in nsecs
NANO_TIME timeRemaining = task->periodMark - rtos_get_time_ns();
// set next wake-up time :
task->periodMark += task->period;

// XXX Racecondition bug:
// if interrupted by another thread here, we will nanosleep to long !
// is there a better Linux API??

if ( timeRemaining > 0 ) {
//rtos_printf("Waiting for %lld nsec\n",timeRemaining);
TIME_SPEC ts( ticks2timespec( timeRemaining ) );
// see nanosleep man page for this construct:
while ( rtos_nanosleep( &ts , &ts ) == -1 && errno == EINTR ) {
errno = 0;
}
return 0;
}

return 0;
}

And I don't want any signals as these are per-process and not per-thread.

Peter

[Bug 565] Periodicity of thread not guaranteed under (preempt-rt

For more infomation about this bug, visit

Peter Soetens

<peter [dot] soetens [..] ...> changed:

What |Removed |Added
--------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution| |FIXED
Target Milestone|--- |1.6.0

--- Comment #6 from Peter Soetens

<peter [dot] soetens [..] ...> 2008-06-06 16:22:07 ---
Fixed on trunk/rtt

$ svn ci src/os/gnulinux/fosi.h src/os/gnulinux/fosi_internal.cpp -m"Fix bug
#565: Periodicity of thread not guaranteed under (preempt-rt) gnulinux
> Applied patch for using clock_nanosleep()
> "
Sending src/os/gnulinux/fosi.h
Sending src/os/gnulinux/fosi_internal.cpp
Transmitting file data ..
Committed revision 29372.

[Bug 565] Periodicity of thread not guaranteed under (preempt-rt

For more infomation about this bug, visit

--- Comment #5 from Peter Soetens

<peter [dot] soetens [..] ...> 2008-06-06 10:44:58 ---
(In reply to comment #4)
>
> Could you agree that each thread stores a RTOS_TASK* and uses that with
> rtos_wait_period()?

Yes, the thread may only pass its own RTOS_TASK to rtos_task_wait_period().

>
> Asuming this, one thread can't call rtos_wait_period() with some other thread's
> RTOS_TASK*. This makes rtos_wait_period() reentrant as far the RTOS_TASK*
> argument is concerned. In other words: rtos_wait_period() can be interrupted by
> an other thread but the RTOS_TASK* _will be_ different.

This is how it is implemented and will stay as such.

Peter

[Bug 565] Periodicity of thread not guaranteed under (preempt-rt

For more infomation about this bug, visit

--- Comment #4 from sander <sander [dot] vandenbroucke [..] ...> 2008-06-06 10:01:40 ---
(In reply to comment #3)
> Because we need to support different OS APIs, we need to pass the OS-specific
> RTOS_TASK struct to this function such that it can extract itself the necessary
> data. For example, RTAI will use no data at all and just use the preprogrammed
> period in rt_task_period_wait(void). Others, like gnulinux, store the period in
> this RTOS_TASK struct and use a nanosleep.
> In both cases, the calling thread is suspended though.
> Peter

Ok, I see.

Could you agree that each thread stores a RTOS_TASK* and uses that with
rtos_wait_period()?

Asuming this, one thread can't call rtos_wait_period() with some other thread's
RTOS_TASK*. This makes rtos_wait_period() reentrant as far the RTOS_TASK*
argument is concerned. In other words: rtos_wait_period() can be interrupted by
an other thread but the RTOS_TASK* _will be_ different.

Sander.

[Bug 565] Periodicity of thread not guaranteed under (preempt-rt

For more infomation about this bug, visit

--- Comment #3 from Peter Soetens

<peter [dot] soetens [..] ...> 2008-06-06 09:47:26 ---
(In reply to comment #2)
> An other thought: What is rtos_task_wait_period() supposed to do anyway?
> Is it supposed to suspend the thread represented by 'RTOS_TASK* task' or is it
> to suspend the calling thread?
>
> It seems to be the second so I wonder if
> int rtos_task_wait_period( NANO_TIME period )
> is a better definition to cover the function's semantics?

Because we need to support different OS APIs, we need to pass the OS-specific
RTOS_TASK struct to this function such that it can extract itself the necessary
data. For example, RTAI will use no data at all and just use the preprogrammed
period in rt_task_period_wait(void). Others, like gnulinux, store the period in
this RTOS_TASK struct and use a nanosleep.

In both cases, the calling thread is suspended though.

Peter

[Bug 565] Periodicity of thread not guaranteed under (preempt-rt

For more infomation about this bug, visit

sander <sander [dot] vandenbroucke [..] ...> changed:

What |Removed |Added
--------------------------------------------------------------------------
CC| |sander.vandenbroucke@vandewi
| |ele.be

--- Comment #2 from sander <sander [dot] vandenbroucke [..] ...> 2008-06-06 08:44:09 ---
An other thought: What is rtos_task_wait_period() supposed to do anyway?
Is it supposed to suspend the thread represented by 'RTOS_TASK* task' or is it
to suspend the calling thread?

It seems to be the second so I wonder if
int rtos_task_wait_period( NANO_TIME period )
is a better definition to cover the function's semantics?

Sander.

[Bug 565] Periodicity of thread not guaranteed under (preempt-rt

For more infomation about this bug, visit

--- Comment #1 from Peter Soetens

<peter [dot] soetens [..] ...> 2008-06-05 15:13:04 ---
Created an attachment (id=317)
--> (https://www.fmtc.be/bugzilla/orocos/attachment.cgi?id=317)
Now we're talking !

As suggested on the mailinglist, clock_nanosleep() is just what we need. Also,
used CLOCK_MONOTONIC to avoid time running backwards in some reported cases...

How does this fit into MacOSX ?

[Bug 565] Periodicity of thread not guaranteed under (preempt-rt

> --> (https://www.fmtc.be/bugzilla/orocos/attachment.cgi?id=317)
> Now we're talking !
>
> As suggested on the mailinglist, clock_nanosleep() is just what we
> need. Also,
> used CLOCK_MONOTONIC to avoid time running backwards in some
> reported cases...

We use CLOCK_REALTIME and I have very very rarely seen some issues
like this. Not sure if time ran backwards per se, but some funky stuff
for sure ...

> How does this fit into MacOSX ?

It doesn't. :-(( No such thing on the Mac. We usually get around it by
doing what you're currently doing with nanosleep, and dealing with the
occaisonal non-real-time problem. The Mac isn't real-time to start
with, so c'iest la vie.
S

[Bug 565] Periodicity of thread not guaranteed under (preempt-rt

On Thu, 5 Jun 2008, S Roderick wrote:
>> --> (https://www.fmtc.be/bugzilla/orocos/attachment.cgi?id=317)
>> Now we're talking !
>>
>> As suggested on the mailinglist, clock_nanosleep() is just what we need.
>> Also,
>> used CLOCK_MONOTONIC to avoid time running backwards in some reported
>> cases...
>
> We use CLOCK_REALTIME and I have very very rarely seen some issues like this.
> Not sure if time ran backwards per se, but some funky stuff for sure ...
>
>> How does this fit into MacOSX ?
>
> It doesn't. :-(( No such thing on the Mac. We usually get around it by doing
> what you're currently doing with nanosleep, and dealing with the occaisonal
> non-real-time problem. The Mac isn't real-time to start with, so c'iest la
> vie.

Since we left the POSIX compliant trail anyway for the port, maybe there's also a solution in native, e.g.

However, this sure ain't high on my priority list :-]

Klaas

[Bug 565] New: Periodicity of thread not guaranteed under (preem

On Jun 5, 2008, at 05:26 , Peter Soetens wrote:

> For more infomation about this bug, visit > >
> Summary: Periodicity of thread not guaranteed under
> (preempt-rt)
> gnulinux
> Product: RTT
> Version: 1.4.0
> Platform: All
> OS/Version: GNU/Linux
> Status: NEW
> Severity: major
> Priority: P2
> Component: Operating System Abstraction - Portability
> AssignedTo: orocos-dev [..] ...
> ReportedBy: peter [dot] soetens [..] ...
> CC: orocos-dev [..] ...
> Estimated Hours: 0.0
>
> The following code in gnulinux/fosi_internal.cpp contains a race
> condition,
> which disturbs deterministic periodic execution, even under PREEMPT-
> RT.
>
> INTERNAL_QUAL int rtos_task_wait_period( RTOS_TASK* task )
> {
> if ( task->period == 0 )
> return 0;
>
> //rtos_printf("Time is %lld nsec, Mark is %lld
> nsec.\n",rtos_get_time_ns(), task->periodMark );
> // CALCULATE in nsecs
> NANO_TIME timeRemaining = task->periodMark -
> rtos_get_time_ns();
> // set next wake-up time :
> task->periodMark += task->period;
>
> // XXX Racecondition bug:
> // if interrupted by another thread here, we will nanosleep
> to long !
> // is there a better Linux API??
>
> if ( timeRemaining > 0 ) {
> //rtos_printf("Waiting for %lld nsec\n",timeRemaining);
> TIME_SPEC ts( ticks2timespec( timeRemaining ) );
> // see nanosleep man page for this construct:
> while ( rtos_nanosleep( &ts , &ts ) == -1 && errno ==
> EINTR ) {
> errno = 0;
> }
> return 0;
> }
>
> return 0;
> }
>
> And I don't want any signals as these are per-process and not per-
> thread.

Would clock_nanosleep(..., TIMER_ABS, ...) help?
S

[Bug 565] New: Periodicity of thread not guaranteed under (preem

[...]
> And I don't want any signals as these are per-process and not per-thread.

Out of interest: Can you elaborate on what's the exact problem you
have with signals?


Klaas

[Bug 565] New: Periodicity of thread not guaranteed under (preem

On Thursday 05 June 2008 11:55:34 Klaas Gadeyne wrote:
> [...]
>
> > And I don't want any signals as these are per-process and not per-thread.
>
> Out of interest: Can you elaborate on what's the exact problem you
> have with signals?

Another practical issue is that when you debug a program with gdb which uses
signals, the delivery of a signal works as a breakpoint. Very annoying if you
are debugging a periodic execution program which uses signals... SIGALRM is
ignored though, I don't know about the 'real-time' signals...

Peter

[Bug 565] New: Periodicity of thread not guaranteed under (preem

On Thu, 5 Jun 2008, Peter Soetens wrote:
> On Thursday 05 June 2008 11:55:34 Klaas Gadeyne wrote:
>> [...]
>>
>>> And I don't want any signals as these are per-process and not per-thread.
>>
>> Out of interest: Can you elaborate on what's the exact problem you
>> have with signals?
>
> Another practical issue is that when you debug a program with gdb which uses
> signals, the delivery of a signal works as a breakpoint. Very annoying if you
> are debugging a periodic execution program which uses signals...

Typically, I use this

to avoid Ctrl-C is intercepted by gdb for programs containing a pause() statement.
$ handle SIGINT nostop pass

Should work too I guess?

Klaas

[Bug 565] New: Periodicity of thread not guaranteed under (preem

On Thursday 05 June 2008 11:55:34 Klaas Gadeyne wrote:
> [...]
>
> > And I don't want any signals as these are per-process and not per-thread.
>
> Out of interest: Can you elaborate on what's the exact problem you
> have with signals?
>
>
> >/examples/simple/playing_with_timers.c>

That's a kernel module ? I think the API they are using is not fully available
in user space. I believe setitimer() must be used in user space... and that
one only sends SIGALRM to the whole process (there is also only one timer for
the whole process)

'man 7 signal' provides also details. Ironically, pthread_* functions used in
this link are not guaranteed to be safe in signal handlers (ymmv). Also,
there is a limit of 29 available real-time signals == max 29 threads.
However, I could not find how to program multiple timers (yet).

Peter