[RTEMS Project] #1748: SPARC BSPs nanoseconds skipping back when counter wraps during get TOD or uptime call
RTEMS trac
trac at rtems.org
Sun Nov 23 19:13:01 UTC 2014
#1748: SPARC BSPs nanoseconds skipping back when counter wraps during get TOD or
uptime call
-----------------------------+----------------------------
Reporter: rolf.schroedter | Owner: joel.sherrill
Type: defect | Status: closed
Priority: normal | Milestone: 4.10
Component: bsps | Version: 4.10
Severity: normal | Resolution: fixed
Keywords: |
-----------------------------+----------------------------
Changes (by joel.sherrill):
* version: unknown => 4.10
Old description:
> I'm running RTEMS on a LEON3 (sparc) platform.
> It's downloaded from Gaisler and claims to be
> rtems-4.9.99.0(SPARC/w/FPU/leon3)
>
> The function rtems_clock_get_uptime() fails when it
> is called during a timer tick. In this case a single time value is
> wrong, the time is skipping backwards by 1 millisecond (TICK). The next
> call returns a correct time.
>
> The problem can be demonstrated using the following code, storing the
> original return of rtems_clock_get_uptime() in an array and calculating a
> microsecond value from that return. At the end all time values are
> printed showing the problem:
>
> Code:
> RTEMS running with 1 millisecond TICK.
> {
> #define LOOPS 1000
>
> int i;
> uint32_t uptime_usec[LOOPS], t0=0;
> struct timespec uptime[LOOPS];
>
> for ( i=0; i<LOOPS; i++ )
> {
> rtems_clock_get_uptime( &uptime[i] );
> uptime_usec[i] = ((uint32_t)uptime[i].tv_sec * 1000000) +
> ((uint32_t)uptime[i].tv_nsec / 1000);
> }
> for ( i=0; i<LOOPS; i++ )
> {
> unsigned t1, usec, msec, sec;
>
> t1 = uptime_usec[i];
> usec = t1 % 1000;
> msec = (t1 / 1000) % 1000;
> sec = t1 / 1000000;
>
> printf("TEST:rtems=%u.%09u t=%u.%03u.%03u dt=%u\n",
> uptime[i].tv_sec, uptime[i].tv_nsec, sec, msec, usec, (t1-t0));
> t0 = t1;
> }
> }
>
> Output:
> - Lines #616 and #686 show the time skipping backwards.
> - The nanoseconds uptime shows that rtems_clock_get_uptime() has
> probably been called during a clock TICK.
>
> 000: uptime=0.445817000 sec=0.445.817 dt=445817
> 001: uptime=0.445835000 sec=0.445.835 dt=18
> 002: uptime=0.445849000 sec=0.445.849 dt=14
> 003: uptime=0.445863000 sec=0.445.863 dt=14
> ...
> 616: uptime=0.454973000 sec=0.454.973 dt=14
> 617: uptime=0.454988000 sec=0.454.988 dt=15
> 618: uptime=0.454002000 sec=0.454.002 dt=4294966310
> 619: uptime=0.455042000 sec=0.455.042 dt=1040
> 620: uptime=0.455056000 sec=0.455.056 dt=14
> 621: uptime=0.455070000 sec=0.455.070 dt=14
> ...
> 684: uptime=0.455972000 sec=0.455.972 dt=14
> 685: uptime=0.455987000 sec=0.455.987 dt=15
> 686: uptime=0.455001000 sec=0.455.001 dt=4294966310
> 687: uptime=0.456042000 sec=0.456.042 dt=1041
> 688: uptime=0.456056000 sec=0.456.056 dt=14
> 689: uptime=0.456071000 sec=0.456.071 dt=15
> ...
New description:
I'm running RTEMS on a LEON3 (sparc) platform.
It's downloaded from Gaisler and claims to be
rtems-4.9.99.0(SPARC/w/FPU/leon3)
The function rtems_clock_get_uptime() fails when it
is called during a timer tick. In this case a single time value is
wrong, the time is skipping backwards by 1 millisecond (TICK). The next
call returns a correct time.
The problem can be demonstrated using the following code, storing the
original return of rtems_clock_get_uptime() in an array and calculating a
microsecond value from that return. At the end all time values are printed
showing the problem:
Code:
RTEMS running with 1 millisecond TICK.
{
#define LOOPS 1000
int i;
uint32_t uptime_usec[LOOPS], t0=0;
struct timespec uptime[LOOPS];
for ( i=0; i<LOOPS; i++ )
{
rtems_clock_get_uptime( &uptime[i] );
uptime_usec[i] = ((uint32_t)uptime[i].tv_sec * 1000000) +
((uint32_t)uptime[i].tv_nsec / 1000);
}
for ( i=0; i<LOOPS; i++ )
{
unsigned t1, usec, msec, sec;
t1 = uptime_usec[i];
usec = t1 % 1000;
msec = (t1 / 1000) % 1000;
sec = t1 / 1000000;
printf("TEST:rtems=%u.%09u t=%u.%03u.%03u dt=%u\n",
uptime[i].tv_sec, uptime[i].tv_nsec, sec, msec, usec, (t1-t0));
t0 = t1;
}
}
Output:
- Lines #616 and #686 show the time skipping backwards.
- The nanoseconds uptime shows that rtems_clock_get_uptime() has
probably been called during a clock TICK.
000: uptime=0.445817000 sec=0.445.817 dt=445817
001: uptime=0.445835000 sec=0.445.835 dt=18
002: uptime=0.445849000 sec=0.445.849 dt=14
003: uptime=0.445863000 sec=0.445.863 dt=14
...
616: uptime=0.454973000 sec=0.454.973 dt=14
617: uptime=0.454988000 sec=0.454.988 dt=15
618: uptime=0.454002000 sec=0.454.002 dt=4294966310
619: uptime=0.455042000 sec=0.455.042 dt=1040
620: uptime=0.455056000 sec=0.455.056 dt=14
621: uptime=0.455070000 sec=0.455.070 dt=14
...
684: uptime=0.455972000 sec=0.455.972 dt=14
685: uptime=0.455987000 sec=0.455.987 dt=15
686: uptime=0.455001000 sec=0.455.001 dt=4294966310
687: uptime=0.456042000 sec=0.456.042 dt=1041
688: uptime=0.456056000 sec=0.456.056 dt=14
689: uptime=0.456071000 sec=0.456.071 dt=15
...
--
--
Ticket URL: <http://devel.rtems.org/ticket/1748#comment:6>
RTEMS Project <http://www.rtems.org/>
RTEMS Project
More information about the bugs
mailing list