#2180 closed defect (fixed)

_TOD_Get_with_nanoseconds() is broken on SMP

Reported by: Sebastian Huber Owned by: Sebastian Huber
Priority: normal Milestone: 4.11
Component: score Version: 4.11
Severity: blocker Keywords:
Cc: Blocked By:
Blocking:

Description (last modified by Joel Sherrill)

We have

Timestamp_Control *_TOD_Get_with_nanoseconds(

Timestamp_Control *snapshot,
const Timestamp_Control *clock

)
{

TOD_Control *tod = &_TOD;
ISR_lock_Context lock_context;
Timestamp_Control offset;
Timestamp_Control now;
uint32_t nanoseconds;

_TOD_Acquire( tod, &lock_context );

nanoseconds = ( *tod->nanoseconds_since_last_tick )();
now = *clock;

_TOD_Release( tod, &lock_context );

_Timestamp_Set( &offset, 0, nanoseconds );
_Timestamp_Add_to( &now, &offset );

*snapshot = now;

return snapshot;

}

and

void _TOD_Tickle_ticks( void )
{

TOD_Control *tod = &_TOD;
ISR_lock_Context lock_context;
Timestamp_Control tick;
uint32_t nanoseconds_per_tick;

nanoseconds_per_tick = rtems_configuration_get_nanoseconds_per_tick();

/* Convert the tick quantum to a timestamp */
_Timestamp_Set( &tick, 0, nanoseconds_per_tick );

/* Update the counter of ticks since boot */
_Watchdog_Ticks_since_boot += 1;

_TOD_Acquire( tod, &lock_context );

/* Update the uptime */
_Timestamp_Add_to( &tod->uptime, &tick );

/* Update the current TOD */
_Timestamp_Add_to( &tod->now, &tick );

_TOD_Release( tod, &lock_context );

_TOD.seconds_trigger += nanoseconds_per_tick;
if ( _TOD.seconds_trigger >= 1000000000UL ) {

_TOD.seconds_trigger -= 1000000000UL;
_Watchdog_Tickle_seconds();

}

}

and (standard Clock driver)

#if defined(BSP_FEATURE_IRQ_EXTENSION)

(CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)

void Clock_isr(void *arg)
{
#else
rtems_isr Clock_isr(rtems_vector_number vector);
rtems_isr Clock_isr(

rtems_vector_number vector

)
{
#endif

/*

  • Accurate count of ISRs */

Clock_driver_ticks += 1;

#if CLOCK_DRIVER_USE_FAST_IDLE

do {

rtems_clock_tick();

} while (

_Thread_Heir == _Thread_Executing

&& _Thread_Executing->Start.entry_point

rtems_configuration_get_idle_task()

);

Clock_driver_support_at_tick();
return;

#else

/*

  • Do the hardware specific per-tick action. *
  • The counter/timer may or may not be set to automatically reload. */

Clock_driver_support_at_tick();

#if CLOCK_DRIVER_ISRS_PER_TICK

/*

  • The driver is multiple ISRs per clock tick. */

if ( !Clock_driver_isrs ) {

rtems_clock_tick();

Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK;

}
Clock_driver_isrs--;

#else

/*

  • The driver is one ISR per clock tick. */

rtems_clock_tick();

#endif

#endif

}

Suppose we are between Clock_driver_support_at_tick() and _TOD_Tickle_ticks(). Now call _TOD_Get_with_nanoseconds() on another processor. With most nanoseconds extensions we observe now a serviced hardware clock interrupt and the old _TOD.uptime value.

Change History (8)

comment:1 Changed on Jun 5, 2014 at 12:29:08 PM by Sebastian Huber

We have

Timestamp_Control *_TOD_Get_with_nanoseconds(

Timestamp_Control *snapshot,
const Timestamp_Control *clock

)
{

TOD_Control *tod = &_TOD;
ISR_lock_Context lock_context;
Timestamp_Control offset;
Timestamp_Control now;
uint32_t nanoseconds;

_TOD_Acquire( tod, &lock_context );

nanoseconds = ( *tod->nanoseconds_since_last_tick )();
now = *clock;

_TOD_Release( tod, &lock_context );

_Timestamp_Set( &offset, 0, nanoseconds );
_Timestamp_Add_to( &now, &offset );

*snapshot = now;

return snapshot;

}

and

void _TOD_Tickle_ticks( void )
{

TOD_Control *tod = &_TOD;
ISR_lock_Context lock_context;
Timestamp_Control tick;
uint32_t nanoseconds_per_tick;

nanoseconds_per_tick = rtems_configuration_get_nanoseconds_per_tick();

/* Convert the tick quantum to a timestamp */
_Timestamp_Set( &tick, 0, nanoseconds_per_tick );

/* Update the counter of ticks since boot */
_Watchdog_Ticks_since_boot += 1;

_TOD_Acquire( tod, &lock_context );

/* Update the uptime */
_Timestamp_Add_to( &tod->uptime, &tick );

/* Update the current TOD */
_Timestamp_Add_to( &tod->now, &tick );

_TOD_Release( tod, &lock_context );

_TOD.seconds_trigger += nanoseconds_per_tick;
if ( _TOD.seconds_trigger >= 1000000000UL ) {

_TOD.seconds_trigger -= 1000000000UL;
_Watchdog_Tickle_seconds();

}

}

and (standard Clock driver)

#if defined(BSP_FEATURE_IRQ_EXTENSION)

(CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)

void Clock_isr(void *arg)
{
#else
rtems_isr Clock_isr(rtems_vector_number vector);
rtems_isr Clock_isr(

rtems_vector_number vector

)
{
#endif

/*

  • Accurate count of ISRs */

Clock_driver_ticks += 1;

#if CLOCK_DRIVER_USE_FAST_IDLE

do {

rtems_clock_tick();

} while (

_Thread_Heir == _Thread_Executing

&& _Thread_Executing->Start.entry_point

rtems_configuration_get_idle_task()

);

Clock_driver_support_at_tick();
return;

#else

/*

  • Do the hardware specific per-tick action. *
  • The counter/timer may or may not be set to automatically reload. */

Clock_driver_support_at_tick();

#if CLOCK_DRIVER_ISRS_PER_TICK

/*

  • The driver is multiple ISRs per clock tick. */

if ( !Clock_driver_isrs ) {

rtems_clock_tick();

Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK;

}
Clock_driver_isrs--;

#else

/*

  • The driver is one ISR per clock tick. */

rtems_clock_tick();

#endif

#endif

}

Suppose we are between Clock_driver_support_at_tick() and _TOD_Tickle_ticks(). Now call _TOD_Get_with_nanoseconds() on another processor. With most nanoseconds extensions we observe now a serviced hardware clock interrupt and the old _TOD.uptime value.

comment:2 Changed on Dec 11, 2014 at 7:06:55 AM by Sebastian Huber

Description: modified (diff)
Milestone: 4.115.0
Owner: changed from Joel Sherrill to Sebastian Huber
Status: newassigned

comment:3 Changed on Feb 16, 2015 at 5:08:48 PM by Joel Sherrill

Component: cpukitSMP
Description: modified (diff)

comment:4 Changed on Feb 18, 2015 at 2:31:45 PM by Sebastian Huber

Status: assignedaccepted

This bug depends on #2271.

comment:5 Changed on May 16, 2015 at 9:29:14 AM by Sebastian Huber

Milestone: 5.04.11
Severity: normalblocker

comment:6 Changed on May 20, 2015 at 7:30:10 AM by Sebastian Huber

Resolution: fixed
Status: acceptedclosed

Fixed via #2271.

comment:7 Changed on Oct 10, 2017 at 6:27:10 AM by Sebastian Huber

Component: SMPscore

comment:8 Changed on Oct 10, 2017 at 6:29:01 AM by Sebastian Huber

Component: scorecpukit
Note: See TracTickets for help on using tickets.