[PATCH 4/4] score: New timer server implementation

Gedare Bloom gedare at rtems.org
Fri Apr 17 14:17:46 UTC 2015


Tested on / results?

On Fri, Apr 17, 2015 at 4:55 AM, Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
> Use mostly the standard watchdog operations.  Use a system event for
> synchronization.  This implementation is simpler and offers better SMP
> performance.
>
> Update #2307.
> ---
>  cpukit/rtems/include/rtems/rtems/event.h           |   5 +
>  cpukit/rtems/include/rtems/rtems/timerimpl.h       |  51 +-
>  cpukit/rtems/src/timerserver.c                     | 570 +++++++--------------
>  cpukit/score/Makefile.am                           |   2 +-
>  cpukit/score/include/rtems/score/watchdogimpl.h    |  59 ++-
>  cpukit/score/src/watchdogadjust.c                  |  35 +-
>  cpukit/score/src/watchdogadjusttochain.c           |  75 ---
>  cpukit/score/src/watchdoginsert.c                  |  21 +-
>  testsuites/sptests/spintrcritical17/init.c         | 163 +++---
>  .../sptests/spintrcritical17/spintrcritical17.doc  |   6 +-
>  10 files changed, 370 insertions(+), 617 deletions(-)
>  delete mode 100644 cpukit/score/src/watchdogadjusttochain.c
>
> diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h
> index dce7de1..012452a 100644
> --- a/cpukit/rtems/include/rtems/rtems/event.h
> +++ b/cpukit/rtems/include/rtems/rtems/event.h
> @@ -319,6 +319,11 @@ rtems_status_code rtems_event_receive (
>  #define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26
>
>  /**
> + * @brief Reserved system event for the timer server.
> + */
> +#define RTEMS_EVENT_SYSTEM_TIMER_SERVER RTEMS_EVENT_30
> +
> +/**
>   * @brief Reserved system event for transient usage.
>   */
>  #define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_31
> diff --git a/cpukit/rtems/include/rtems/rtems/timerimpl.h b/cpukit/rtems/include/rtems/rtems/timerimpl.h
> index 4f200ef..e5b37aa 100644
> --- a/cpukit/rtems/include/rtems/rtems/timerimpl.h
> +++ b/cpukit/rtems/include/rtems/rtems/timerimpl.h
> @@ -65,24 +65,43 @@ typedef struct {
>    Watchdog_Control System_watchdog;
>
>    /**
> +   * @brief Remaining delta of the system watchdog.
> +   */
> +  Watchdog_Interval system_watchdog_delta;
> +
> +  /**
> +   * @brief Unique identifier of the context which deals currently with the
> +   * system watchdog.
> +   */
> +  Thread_Control *system_watchdog_helper;
> +
> +  /**
> +   * @brief Each insert and tickle operation increases the generation count so
> +   * that the system watchdog dealer notices updates of the watchdog chain.
> +   */
> +  uint32_t generation;
> +
> +  /**
>     * @brief Watchdog header managed by the timer server.
>     */
>    Watchdog_Header Header;
>
>    /**
> -   * @brief Last known time snapshot of the timer server.
> +   * @brief Last time snapshot of the timer server.
>     *
>     * The units may be ticks or seconds.
>     */
> -  Watchdog_Interval volatile last_snapshot;
> -} Timer_server_Watchdogs;
> +  Watchdog_Interval last_snapshot;
>
> -struct Timer_server_Control {
>    /**
> -   * @brief Timer server thread.
> +   * @brief Current time snapshot of the timer server.
> +   *
> +   * The units may be ticks or seconds.
>     */
> -  Thread_Control *thread;
> +  Watchdog_Interval current_snapshot;
> +} Timer_server_Watchdogs;
>
> +struct Timer_server_Control {
>    /**
>     * @brief The cancel method of the timer server.
>     */
> @@ -102,26 +121,6 @@ struct Timer_server_Control {
>     * @brief TOD watchdogs triggered by the timer server.
>     */
>    Timer_server_Watchdogs TOD_watchdogs;
> -
> -  /**
> -   * @brief Chain of timers scheduled for insert.
> -   *
> -   * This pointer is not @c NULL whenever the interval and TOD chains are
> -   * processed.  After the processing this list will be checked and if
> -   * necessary the processing will be restarted.  Processing of these chains
> -   * can be only interrupted through interrupts.
> -   */
> -  Chain_Control *volatile insert_chain;
> -
> -  /**
> -   * @brief Indicates that the timer server is active or not.
> -   *
> -   * The server is active after the delay on a system watchdog.  The activity
> -   * period of the server ends when no more watchdogs managed by the server
> -   * fire.  The system watchdogs must not be manipulated when the server is
> -   * active.
> -   */
> -  bool volatile active;
>  };
>
>  /**
> diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c
> index 15cbdfd..db38f48 100644
> --- a/cpukit/rtems/src/timerserver.c
> +++ b/cpukit/rtems/src/timerserver.c
> @@ -15,7 +15,7 @@
>  /*  COPYRIGHT (c) 1989-2008.
>   *  On-Line Applications Research Corporation (OAR).
>   *
> - *  Copyright (c) 2009 embedded brains GmbH.
> + *  Copyright (c) 2009-2015 embedded brains GmbH.
>   *
>   *  The license and distribution terms for this file may be
>   *  found in the file LICENSE in this distribution or at
> @@ -26,200 +26,128 @@
>  #include "config.h"
>  #endif
>
> +#include <rtems.h>
>  #include <rtems/rtems/timerimpl.h>
>  #include <rtems/rtems/tasksimpl.h>
> -#include <rtems/score/isrlevel.h>
> -#include <rtems/score/threadimpl.h>
>  #include <rtems/score/todimpl.h>
>
>  static Timer_server_Control _Timer_server_Default;
>
> -static void _Timer_server_Stop_interval_system_watchdog(
> -  Timer_server_Control *ts
> +static void _Timer_server_Cancel_method(
> +  Timer_server_Control *ts,
> +  Timer_Control *timer
>  )
>  {
> -  _Watchdog_Remove_ticks( &ts->Interval_watchdogs.System_watchdog );
> +  if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
> +    _Watchdog_Remove( &ts->Interval_watchdogs.Header, &timer->Ticker );
> +  } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
> +    _Watchdog_Remove( &ts->TOD_watchdogs.Header, &timer->Ticker );
> +  }
>  }
>
> -static void _Timer_server_Reset_interval_system_watchdog(
> -  Timer_server_Control *ts
> -)
> +static Watchdog_Interval _Timer_server_Get_ticks( void )
>  {
> -  ISR_Level level;
> -
> -  _Timer_server_Stop_interval_system_watchdog( ts );
> -
> -  _ISR_Disable( level );
> -  if ( !_Watchdog_Is_empty( &ts->Interval_watchdogs.Header ) ) {
> -    Watchdog_Interval delta_interval =
> -      _Watchdog_First( &ts->Interval_watchdogs.Header )->delta_interval;
> -    _ISR_Enable( level );
> -
> -    /*
> -     *  The unit is TICKS here.
> -     */
> -    _Watchdog_Insert_ticks(
> -      &ts->Interval_watchdogs.System_watchdog,
> -      delta_interval
> -    );
> -  } else {
> -    _ISR_Enable( level );
> -  }
> +  return _Watchdog_Ticks_since_boot;
>  }
>
> -static void _Timer_server_Stop_tod_system_watchdog(
> -  Timer_server_Control *ts
> -)
> +static Watchdog_Interval _Timer_server_Get_seconds( void )
>  {
> -  _Watchdog_Remove_seconds( &ts->TOD_watchdogs.System_watchdog );
> +  return _TOD_Seconds_since_epoch();
>  }
>
> -static void _Timer_server_Reset_tod_system_watchdog(
> -  Timer_server_Control *ts
> +static void _Timer_server_Update_system_watchdog(
> +  Timer_server_Watchdogs *watchdogs,
> +  Watchdog_Header *system_header
>  )
>  {
> -  ISR_Level level;
> +  ISR_lock_Context lock_context;
>
> -  _Timer_server_Stop_tod_system_watchdog( ts );
> +  _Watchdog_Acquire( &watchdogs->Header, &lock_context );
>
> -  _ISR_Disable( level );
> -  if ( !_Watchdog_Is_empty( &ts->TOD_watchdogs.Header ) ) {
> -    Watchdog_Interval delta_interval =
> -      _Watchdog_First( &ts->TOD_watchdogs.Header )->delta_interval;
> -    _ISR_Enable( level );
> +  if ( watchdogs->system_watchdog_helper == NULL ) {
> +    Thread_Control *executing;
> +    uint32_t my_generation;
>
> -    /*
> -     *  The unit is SECONDS here.
> -     */
> -    _Watchdog_Insert_seconds(
> -      &ts->TOD_watchdogs.System_watchdog,
> -      delta_interval
> -    );
> -  } else {
> -    _ISR_Enable( level );
> -  }
> -}
> +    executing = _Thread_Executing;
> +    watchdogs->system_watchdog_helper = executing;
>
> -static void _Timer_server_Insert_timer(
> -  Timer_server_Control *ts,
> -  Timer_Control *timer
> -)
> -{
> -  if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
> -    _Watchdog_Insert( &ts->Interval_watchdogs.Header, &timer->Ticker );
> -  } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
> -    _Watchdog_Insert( &ts->TOD_watchdogs.Header, &timer->Ticker );
> +    do {
> +      my_generation = watchdogs->generation;
> +
> +      if ( !_Watchdog_Is_empty( &watchdogs->Header ) ) {
> +        Watchdog_Control *first;
> +        Watchdog_Interval delta;
> +
> +        first = _Watchdog_First( &watchdogs->Header );
> +        delta = first->delta_interval;
> +
> +        if (
> +          watchdogs->System_watchdog.state == WATCHDOG_INACTIVE
> +            || delta != watchdogs->system_watchdog_delta
> +        ) {
> +          watchdogs->system_watchdog_delta = delta;
> +          _Watchdog_Release( &watchdogs->Header, &lock_context );
> +
> +          _Watchdog_Remove( system_header, &watchdogs->System_watchdog );
> +          watchdogs->System_watchdog.initial = delta;
> +          _Watchdog_Insert( system_header, &watchdogs->System_watchdog );
> +
> +          _Watchdog_Acquire( &watchdogs->Header, &lock_context );
> +        }
> +      }
> +    } while ( watchdogs->generation != my_generation );
> +
> +    watchdogs->system_watchdog_helper = NULL;
>    }
> +
> +  _Watchdog_Release( &watchdogs->Header, &lock_context );
>  }
>
> -static void _Timer_server_Insert_timer_and_make_snapshot(
> -  Timer_server_Control *ts,
> -  Timer_Control *timer
> +static void _Timer_server_Insert_timer(
> +  Timer_server_Watchdogs *watchdogs,
> +  Timer_Control *timer,
> +  Watchdog_Header *system_header,
> +  Watchdog_Interval (*get_ticks)( void )
>  )
>  {
> -  Watchdog_Control *first_watchdog;
> -  Watchdog_Interval delta_interval;
> -  Watchdog_Interval last_snapshot;
> -  Watchdog_Interval snapshot;
> +  ISR_lock_Context lock_context;
> +  Watchdog_Interval now;
>    Watchdog_Interval delta;
> -  ISR_Level level;
>
> -  /*
> -   *  We have to update the time snapshots here, because otherwise we may have
> -   *  problems with the integer range of the delta values.  The time delta DT
> -   *  from the last snapshot to now may be arbitrarily long.  The last snapshot
> -   *  is the reference point for the delta chain.  Thus if we do not update the
> -   *  reference point we have to add DT to the initial delta of the watchdog
> -   *  being inserted.  This could result in an integer overflow.
> -   */
> +  _Watchdog_Acquire( &watchdogs->Header, &lock_context );
>
> -  _Thread_Disable_dispatch();
> +  now = (*get_ticks)();
> +  delta = now - watchdogs->last_snapshot;
> +  watchdogs->last_snapshot = now;
> +  watchdogs->current_snapshot = now;
>
> -  if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
> -    /*
> -     *  We have to advance the last known ticks value of the server and update
> -     *  the watchdog chain accordingly.
> -     */
> -    _ISR_Disable( level );
> -    snapshot = _Watchdog_Ticks_since_boot;
> -    last_snapshot = ts->Interval_watchdogs.last_snapshot;
> -    if ( !_Watchdog_Is_empty( &ts->Interval_watchdogs.Header ) ) {
> -      first_watchdog = _Watchdog_First( &ts->Interval_watchdogs.Header );
> -
> -      /*
> -       *  We assume adequate unsigned arithmetic here.
> -       */
> -      delta = snapshot - last_snapshot;
> -
> -      delta_interval = first_watchdog->delta_interval;
> -      if (delta_interval > delta) {
> -        delta_interval -= delta;
> -      } else {
> -        delta_interval = 0;
> -      }
> -      first_watchdog->delta_interval = delta_interval;
> -    }
> -    ts->Interval_watchdogs.last_snapshot = snapshot;
> -    _ISR_Enable( level );
> +  if ( watchdogs->system_watchdog_delta > delta ) {
> +    watchdogs->system_watchdog_delta -= delta;
> +  } else {
> +    watchdogs->system_watchdog_delta = 0;
> +  }
>
> -    _Watchdog_Insert( &ts->Interval_watchdogs.Header, &timer->Ticker );
> +  if ( !_Watchdog_Is_empty( &watchdogs->Header ) ) {
> +    Watchdog_Control *first = _Watchdog_First( &watchdogs->Header );
>
> -    if ( !ts->active ) {
> -      _Timer_server_Reset_interval_system_watchdog( ts );
> -    }
> -  } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
> -    /*
> -     *  We have to advance the last known seconds value of the server and update
> -     *  the watchdog chain accordingly.
> -     */
> -    _ISR_Disable( level );
> -    snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch();
> -    last_snapshot = ts->TOD_watchdogs.last_snapshot;
> -    if ( !_Watchdog_Is_empty( &ts->TOD_watchdogs.Header ) ) {
> -      first_watchdog = _Watchdog_First( &ts->TOD_watchdogs.Header );
> -      delta_interval = first_watchdog->delta_interval;
> -      if ( snapshot > last_snapshot ) {
> -        /*
> -         *  We advanced in time.
> -         */
> -        delta = snapshot - last_snapshot;
> -        if (delta_interval > delta) {
> -          delta_interval -= delta;
> -        } else {
> -          delta_interval = 0;
> -        }
> -      } else {
> -        /*
> -         *  Someone put us in the past.
> -         */
> -        delta = last_snapshot - snapshot;
> -        delta_interval += delta;
> -      }
> -      first_watchdog->delta_interval = delta_interval;
> +    if ( first->delta_interval > delta ) {
> +      first->delta_interval -= delta;
> +    } else {
> +      first->delta_interval = 0;
>      }
> -    ts->TOD_watchdogs.last_snapshot = snapshot;
> -    _ISR_Enable( level );
> +  }
>
> -    _Watchdog_Insert( &ts->TOD_watchdogs.Header, &timer->Ticker );
> +  _Watchdog_Insert_locked(
> +    &watchdogs->Header,
> +    &timer->Ticker,
> +    &lock_context
> +  );
>
> -    if ( !ts->active ) {
> -      _Timer_server_Reset_tod_system_watchdog( ts );
> -    }
> -  }
> +  ++watchdogs->generation;
>
> -  _Thread_Enable_dispatch();
> -}
> +  _Watchdog_Release( &watchdogs->Header, &lock_context );
>
> -static void _Timer_server_Cancel_method(
> -  Timer_server_Control *ts,
> -  Timer_Control *timer
> -)
> -{
> -  if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
> -    _Watchdog_Remove( &ts->Interval_watchdogs.Header, &timer->Ticker );
> -  } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
> -    _Watchdog_Remove( &ts->TOD_watchdogs.Header, &timer->Ticker );
> -  }
> +  _Timer_server_Update_system_watchdog( watchdogs, system_header );
>  }
>
>  static void _Timer_server_Schedule_operation_method(
> @@ -227,143 +155,71 @@ static void _Timer_server_Schedule_operation_method(
>    Timer_Control *timer
>  )
>  {
> -  if ( ts->insert_chain == NULL ) {
> -    _Timer_server_Insert_timer_and_make_snapshot( ts, timer );
> -  } else {
> -    /*
> -     *  We interrupted a critical section of the timer server.  The timer
> -     *  server is not preemptible, so we must be in interrupt context here.  No
> -     *  thread dispatch will happen until the timer server finishes its
> -     *  critical section.  We have to use the protected chain methods because
> -     *  we may be interrupted by a higher priority interrupt.
> -     */
> -    _Chain_Append( ts->insert_chain, &timer->Object.Node );
> +  if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
> +    _Timer_server_Insert_timer(
> +      &ts->Interval_watchdogs,
> +      timer,
> +      &_Watchdog_Ticks_header,
> +      _Timer_server_Get_ticks
> +    );
> +  } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
> +    _Timer_server_Insert_timer(
> +      &ts->TOD_watchdogs,
> +      timer,
> +      &_Watchdog_Seconds_header,
> +      _Timer_server_Get_seconds
> +    );
>    }
>  }
>
> -static void _Timer_server_Process_interval_watchdogs(
> +static void _Timer_server_Update_current_snapshot(
>    Timer_server_Watchdogs *watchdogs,
> -  Chain_Control *fire_chain
> +  Watchdog_Interval (*get_ticks)( void )
>  )
>  {
> -  Watchdog_Interval snapshot = _Watchdog_Ticks_since_boot;
> +  ISR_lock_Context lock_context;
>
> -  /*
> -   *  We assume adequate unsigned arithmetic here.
> -   */
> -  Watchdog_Interval delta = snapshot - watchdogs->last_snapshot;
> -
> -  watchdogs->last_snapshot = snapshot;
> -
> -  _Watchdog_Adjust_to_chain( &watchdogs->Header, delta, fire_chain );
> +  _Watchdog_Acquire( &watchdogs->Header, &lock_context );
> +  watchdogs->current_snapshot = (*get_ticks)();
> +  watchdogs->system_watchdog_delta = 0;
> +  _Watchdog_Release( &watchdogs->Header, &lock_context );
>  }
>
> -static void _Timer_server_Process_tod_watchdogs(
> +static void _Timer_server_Tickle(
>    Timer_server_Watchdogs *watchdogs,
> -  Chain_Control *fire_chain
> +  Watchdog_Header *system_header,
> +  Watchdog_Interval (*get_ticks)( void ),
> +  bool ticks
>  )
>  {
> -  Watchdog_Interval snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch();
> -  Watchdog_Interval last_snapshot = watchdogs->last_snapshot;
> -  Watchdog_Interval delta;
> -
> -  /*
> -   *  Process the seconds chain.  Start by checking that the Time
> -   *  of Day (TOD) has not been set backwards.  If it has then
> -   *  we want to adjust the watchdogs->Header to indicate this.
> -   */
> -  if ( snapshot > last_snapshot ) {
> -    /*
> -     *  This path is for normal forward movement and cases where the
> -     *  TOD has been set forward.
> -     */
> -    delta = snapshot - last_snapshot;
> -    _Watchdog_Adjust_to_chain( &watchdogs->Header, delta, fire_chain );
> -
> -  } else if ( snapshot < last_snapshot ) {
> -     /*
> -      *  The current TOD is before the last TOD which indicates that
> -      *  TOD has been set backwards.
> -      */
> -     delta = last_snapshot - snapshot;
> -     _Watchdog_Adjust_backward( &watchdogs->Header, delta );
> -  }
> -
> -  watchdogs->last_snapshot = snapshot;
> -}
> -
> -static void _Timer_server_Process_insertions( Timer_server_Control *ts )
> -{
> -  while ( true ) {
> -    Timer_Control *timer = (Timer_Control *) _Chain_Get( ts->insert_chain );
> +  ISR_lock_Context lock_context;
> +  Watchdog_Interval now;
> +  Watchdog_Interval last;
>
> -    if ( timer == NULL ) {
> -      break;
> -    }
> -
> -    _Timer_server_Insert_timer( ts, timer );
> -  }
> -}
> -
> -static void _Timer_server_Get_watchdogs_that_fire_now(
> -  Timer_server_Control *ts,
> -  Chain_Control *insert_chain,
> -  Chain_Control *fire_chain
> -)
> -{
> -  /*
> -   *  Afterwards all timer inserts are directed to this chain and the interval
> -   *  and TOD chains will be no more modified by other parties.
> -   */
> -  ts->insert_chain = insert_chain;
> +  _Watchdog_Acquire( &watchdogs->Header, &lock_context );
>
> -  while ( true ) {
> -    ISR_Level level;
> +  now = watchdogs->current_snapshot;
> +  last = watchdogs->last_snapshot;
> +  watchdogs->last_snapshot = now;
>
> -    /*
> -     *  Remove all the watchdogs that need to fire so we can invoke them.
> -     */
> -    _Timer_server_Process_interval_watchdogs(
> -      &ts->Interval_watchdogs,
> -      fire_chain
> +  if ( ticks || now >= last ) {
> +    _Watchdog_Adjust_forward_locked(
> +      &watchdogs->Header,
> +      now - last,
> +      &lock_context
> +    );
> +  } else {
> +    _Watchdog_Adjust_backward_locked(
> +      &watchdogs->Header,
> +      last - now
>      );
> -    _Timer_server_Process_tod_watchdogs( &ts->TOD_watchdogs, fire_chain );
> -
> -    /*
> -     *  The insertions have to take place here, because they reference the
> -     *  current time.  The previous process methods take a snapshot of the
> -     *  current time.  In case someone inserts a watchdog with an initial value
> -     *  of zero it will be processed in the next iteration of the timer server
> -     *  body loop.
> -     */
> -    _Timer_server_Process_insertions( ts );
> -
> -    _ISR_Disable( level );
> -    if ( _Chain_Is_empty( insert_chain ) ) {
> -      ts->insert_chain = NULL;
> -      _ISR_Enable( level );
> -
> -      break;
> -    } else {
> -      _ISR_Enable( level );
> -    }
>    }
> -}
>
> -/* FIXME: This locking approach for SMP is improvable! */
> +  ++watchdogs->generation;
>
> -static void _Timer_server_SMP_lock_aquire( void )
> -{
> -#if defined( RTEMS_SMP )
> -  _Thread_Disable_dispatch();
> -#endif
> -}
> +  _Watchdog_Release( &watchdogs->Header, &lock_context );
>
> -static void _Timer_server_SMP_lock_release( void )
> -{
> -#if defined( RTEMS_SMP )
> -  _Thread_Enable_dispatch();
> -#endif
> +  _Timer_server_Update_system_watchdog( watchdogs, system_header );
>  }
>
>  /**
> @@ -380,81 +236,73 @@ static rtems_task _Timer_server_Body(
>  )
>  {
>    Timer_server_Control *ts = (Timer_server_Control *) arg;
> -  Chain_Control insert_chain;
> -  Chain_Control fire_chain;
>
> -  _Chain_Initialize_empty( &insert_chain );
> -  _Chain_Initialize_empty( &fire_chain );
> +  while ( true ) {
> +    rtems_event_set events;
>
> -  _Timer_server_SMP_lock_aquire();
> +    _Timer_server_Tickle(
> +      &ts->Interval_watchdogs,
> +      &_Watchdog_Ticks_header,
> +      _Timer_server_Get_ticks,
> +      true
> +    );
>
> -  while ( true ) {
> -    _Timer_server_Get_watchdogs_that_fire_now( ts, &insert_chain, &fire_chain );
> -
> -    if ( !_Chain_Is_empty( &fire_chain ) ) {
> -      /*
> -       *  Fire the watchdogs.
> -       */
> -      while ( true ) {
> -        Watchdog_Control *watchdog;
> -        ISR_Level level;
> -
> -        /*
> -         *  It is essential that interrupts are disable here since an interrupt
> -         *  service routine may remove a watchdog from the chain.
> -         */
> -        _ISR_Disable( level );
> -        watchdog = (Watchdog_Control *) _Chain_Get_unprotected( &fire_chain );
> -        if ( watchdog != NULL ) {
> -          watchdog->state = WATCHDOG_INACTIVE;
> -          _ISR_Enable( level );
> -        } else {
> -          _ISR_Enable( level );
> -
> -          break;
> -        }
> +    _Timer_server_Tickle(
> +      &ts->TOD_watchdogs,
> +      &_Watchdog_Seconds_header,
> +      _Timer_server_Get_seconds,
> +      false
> +    );
>
> -        _Timer_server_SMP_lock_release();
> +    (void) rtems_event_system_receive(
> +      RTEMS_EVENT_SYSTEM_TIMER_SERVER,
> +      RTEMS_EVENT_ALL | RTEMS_WAIT,
> +      RTEMS_NO_TIMEOUT,
> +      &events
> +    );
> +  }
> +}
>
> -        /*
> -         *  The timer server may block here and wait for resources or time.
> -         *  The system watchdogs are inactive and will remain inactive since
> -         *  the active flag of the timer server is true.
> -         */
> -        (*watchdog->routine)( watchdog->id, watchdog->user_data );
> +static void _Timer_server_Wakeup(
> +  Objects_Id  id,
> +  void       *arg
> +)
> +{
> +  Timer_server_Control *ts = arg;
>
> -        _Timer_server_SMP_lock_aquire();
> -      }
> -    } else {
> -      ts->active = false;
> +  _Timer_server_Update_current_snapshot(
> +    &ts->Interval_watchdogs,
> +    _Timer_server_Get_ticks
> +  );
>
> -      /*
> -       *  Block until there is something to do.
> -       */
> -#if !defined( RTEMS_SMP )
> -      _Thread_Disable_dispatch();
> -#endif
> -        _Thread_Set_state( ts->thread, STATES_DELAYING );
> -        _Timer_server_Reset_interval_system_watchdog( ts );
> -        _Timer_server_Reset_tod_system_watchdog( ts );
> -#if !defined( RTEMS_SMP )
> -      _Thread_Enable_dispatch();
> -#endif
> +  _Timer_server_Update_current_snapshot(
> +    &ts->TOD_watchdogs,
> +    _Timer_server_Get_seconds
> +  );
>
> -      _Timer_server_SMP_lock_release();
> -      _Timer_server_SMP_lock_aquire();
> +  (void) rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TIMER_SERVER );
> +}
>
> -      ts->active = true;
> +static void _Timer_server_Initialize_watchdogs(
> +  Timer_server_Control *ts,
> +  rtems_id id,
> +  Timer_server_Watchdogs *watchdogs,
> +  Watchdog_Interval (*get_ticks)( void )
> +)
> +{
> +  Watchdog_Interval now;
>
> -      /*
> -       *  Maybe an interrupt did reset the system timers, so we have to stop
> -       *  them here.  Since we are active now, there will be no more resets
> -       *  until we are inactive again.
> -       */
> -      _Timer_server_Stop_interval_system_watchdog( ts );
> -      _Timer_server_Stop_tod_system_watchdog( ts );
> -    }
> -  }
> +  now = (*get_ticks)();
> +  watchdogs->last_snapshot = now;
> +  watchdogs->current_snapshot = now;
> +
> +  _Watchdog_Header_initialize( &watchdogs->Header );
> +  _Watchdog_Initialize(
> +    &watchdogs->System_watchdog,
> +    _Timer_server_Wakeup,
> +    id,
> +    ts
> +  );
>  }
>
>  /**
> @@ -542,36 +390,18 @@ rtems_status_code rtems_timer_initiate_server(
>     *  Timer Server so we do not have to have a critical section.
>     */
>
> -  /*
> -   *  We work with the TCB pointer, not the ID, so we need to convert
> -   *  to a TCB pointer from here out.
> -   */
> -  ts->thread = (Thread_Control *)_Objects_Get_local_object(
> -    &_RTEMS_tasks_Information,
> -    _Objects_Get_index(id)
> +  _Timer_server_Initialize_watchdogs(
> +    ts,
> +    id,
> +    &ts->Interval_watchdogs,
> +    _Timer_server_Get_ticks
>    );
>
> -  /*
> -   *  Initialize the timer lists that the server will manage.
> -   */
> -  _Watchdog_Header_initialize( &ts->Interval_watchdogs.Header );
> -  _Watchdog_Header_initialize( &ts->TOD_watchdogs.Header );
> -
> -  /*
> -   *  Initialize the timers that will be used to control when the
> -   *  Timer Server wakes up and services the task-based timers.
> -   */
> -  _Watchdog_Initialize(
> -    &ts->Interval_watchdogs.System_watchdog,
> -    _Thread_Delay_ended,
> -    0,
> -    ts->thread
> -  );
> -  _Watchdog_Initialize(
> -    &ts->TOD_watchdogs.System_watchdog,
> -    _Thread_Delay_ended,
> -    0,
> -    ts->thread
> +  _Timer_server_Initialize_watchdogs(
> +    ts,
> +    id,
> +    &ts->TOD_watchdogs,
> +    _Timer_server_Get_seconds
>    );
>
>    /*
> @@ -581,12 +411,6 @@ rtems_status_code rtems_timer_initiate_server(
>    ts->cancel = _Timer_server_Cancel_method;
>    ts->schedule_operation = _Timer_server_Schedule_operation_method;
>
> -  ts->Interval_watchdogs.last_snapshot = _Watchdog_Ticks_since_boot;
> -  ts->TOD_watchdogs.last_snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch();
> -
> -  ts->insert_chain = NULL;
> -  ts->active = false;
> -
>    /*
>     * The default timer server is now available.
>     */
> diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
> index f0cd676..e84d4e5 100644
> --- a/cpukit/score/Makefile.am
> +++ b/cpukit/score/Makefile.am
> @@ -324,7 +324,7 @@ libscore_a_SOURCES += src/coretod.c src/coretodset.c src/coretodget.c \
>
>  ## WATCHDOG_C_FILES
>  libscore_a_SOURCES += src/watchdog.c src/watchdogadjust.c \
> -    src/watchdogadjusttochain.c src/watchdoginsert.c src/watchdogremove.c \
> +    src/watchdoginsert.c src/watchdogremove.c \
>      src/watchdogtickle.c
>  libscore_a_SOURCES += src/watchdogtickssinceboot.c
>
> diff --git a/cpukit/score/include/rtems/score/watchdogimpl.h b/cpukit/score/include/rtems/score/watchdogimpl.h
> index 304392b..84c5a6d 100644
> --- a/cpukit/score/include/rtems/score/watchdogimpl.h
> +++ b/cpukit/score/include/rtems/score/watchdogimpl.h
> @@ -175,6 +175,22 @@ void _Watchdog_Adjust_backward(
>  );
>
>  /**
> + * @brief Adjusts the watchdogs in backward direction in a locked context.
> + *
> + * The caller must be the owner of the watchdog lock and will be the owner
> + * after the call.
> + *
> + * @param[in] header The watchdog header.
> + * @param[in] units The units of ticks to adjust.
> + *
> + * @see _Watchdog_Adjust_forward().
> + */
> +void _Watchdog_Adjust_backward_locked(
> +  Watchdog_Header   *header,
> +  Watchdog_Interval  units
> +);
> +
> +/**
>   *  @brief Adjusts the header watchdog chain in the forward direction for units
>   *  ticks.
>   *
> @@ -189,24 +205,22 @@ void _Watchdog_Adjust_forward(
>  );
>
>  /**
> - *  @brief Adjusts the @a header watchdog chain in the forward
> - *  @a direction for @a units_arg ticks.
> + * @brief Adjusts the watchdogs in forward direction in a locked context.
>   *
> - *  This routine adjusts the @a header watchdog chain in the forward
> - *  @a direction for @a units_arg ticks.
> + * The caller must be the owner of the watchdog lock and will be the owner
> + * after the call.  This function may release and acquire the watchdog lock
> + * internally.
>   *
> - *  @param[in] header is the watchdog chain to adjust
> - *  @param[in] units_arg is the number of units to adjust @a header
> - *  @param[in] to_fire is a pointer to an initialized Chain_Control to which
> - *             all watchdog instances that are to be fired will be placed.
> + * @param[in] header The watchdog header.
> + * @param[in] units The units of ticks to adjust.
> + * @param[in] lock_context The lock context.
>   *
> - *  @note This always adjusts forward.
> + * @see _Watchdog_Adjust_forward().
>   */
> -void _Watchdog_Adjust_to_chain(
> +void _Watchdog_Adjust_forward_locked(
>    Watchdog_Header   *header,
> -  Watchdog_Interval  units_arg,
> -  Chain_Control     *to_fire
> -
> +  Watchdog_Interval  units,
> +  ISR_lock_Context  *lock_context
>  );
>
>  /**
> @@ -226,6 +240,25 @@ void _Watchdog_Insert (
>  );
>
>  /**
> + * @brief Inserts the watchdog in a locked context.
> + *
> + * The caller must be the owner of the watchdog lock and will be the owner
> + * after the call.  This function may release and acquire the watchdog lock
> + * internally.
> + *
> + * @param[in] header The watchdog header.
> + * @param[in] the_watchdog The watchdog.
> + * @param[in] lock_context The lock context.
> + *
> + * @see _Watchdog_Insert().
> + */
> +void _Watchdog_Insert_locked(
> +  Watchdog_Header  *header,
> +  Watchdog_Control *the_watchdog,
> +  ISR_lock_Context *lock_context
> +);
> +
> +/**
>   *  @brief This routine is invoked at appropriate intervals to update
>   *  the @a header watchdog chain.
>   *
> diff --git a/cpukit/score/src/watchdogadjust.c b/cpukit/score/src/watchdogadjust.c
> index 04fc1a5..32b5f79 100644
> --- a/cpukit/score/src/watchdogadjust.c
> +++ b/cpukit/score/src/watchdogadjust.c
> @@ -19,26 +19,18 @@
>  #endif
>
>  #include <rtems/score/watchdogimpl.h>
> -#include <rtems/score/chainimpl.h>
> -#include <rtems/score/isrlevel.h>
>
> -void _Watchdog_Adjust_backward(
> +void _Watchdog_Adjust_backward_locked(
>    Watchdog_Header   *header,
>    Watchdog_Interval  units
>  )
>  {
> -  ISR_lock_Context lock_context;
> -
> -  _Watchdog_Acquire( header, &lock_context );
> -
>    if ( !_Watchdog_Is_empty( header ) ) {
>       _Watchdog_First( header )->delta_interval += units;
>    }
> -
> -  _Watchdog_Release( header, &lock_context );
>  }
>
> -void _Watchdog_Adjust_forward(
> +void _Watchdog_Adjust_backward(
>    Watchdog_Header   *header,
>    Watchdog_Interval  units
>  )
> @@ -46,7 +38,16 @@ void _Watchdog_Adjust_forward(
>    ISR_lock_Context lock_context;
>
>    _Watchdog_Acquire( header, &lock_context );
> +  _Watchdog_Adjust_backward_locked( header, units );
> +  _Watchdog_Release( header, &lock_context );
> +}
>
> +void _Watchdog_Adjust_forward_locked(
> +  Watchdog_Header   *header,
> +  Watchdog_Interval  units,
> +  ISR_lock_Context  *lock_context
> +)
> +{
>    while ( !_Watchdog_Is_empty( header ) && units > 0 ) {
>      Watchdog_Control *first = _Watchdog_First( header );
>
> @@ -57,13 +58,23 @@ void _Watchdog_Adjust_forward(
>        units -= first->delta_interval;
>        first->delta_interval = 1;
>
> -      _Watchdog_Release( header, &lock_context );
> +      _Watchdog_Release( header, lock_context );
>
>        _Watchdog_Tickle( header );
>
> -      _Watchdog_Acquire( header, &lock_context );
> +      _Watchdog_Acquire( header, lock_context );
>      }
>    }
> +}
>
> +void _Watchdog_Adjust_forward(
> +  Watchdog_Header   *header,
> +  Watchdog_Interval  units
> +)
> +{
> +  ISR_lock_Context lock_context;
> +
> +  _Watchdog_Acquire( header, &lock_context );
> +  _Watchdog_Adjust_forward_locked( header, units, &lock_context );
>    _Watchdog_Release( header, &lock_context );
>  }
> diff --git a/cpukit/score/src/watchdogadjusttochain.c b/cpukit/score/src/watchdogadjusttochain.c
> deleted file mode 100644
> index b3063e4..0000000
> --- a/cpukit/score/src/watchdogadjusttochain.c
> +++ /dev/null
> @@ -1,75 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Watchdog Adjust to Chain
> - *  @ingroup ScoreWatchdog
> - */
> -
> -/*
> - *  COPYRIGHT (c) 1989-2009.
> - *  On-Line Applications Research Corporation (OAR).
> - *
> - *  The license and distribution terms for this file may be
> - *  found in the file LICENSE in this distribution or at
> - *  http://www.rtems.org/license/LICENSE.
> - */
> -
> -#if HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <rtems/score/watchdogimpl.h>
> -#include <rtems/score/isrlevel.h>
> -
> -void _Watchdog_Adjust_to_chain(
> -  Watchdog_Header   *header,
> -  Watchdog_Interval  units_arg,
> -  Chain_Control     *to_fire
> -
> -)
> -{
> -  Watchdog_Interval  units = units_arg;
> -  ISR_lock_Context   lock_context;
> -  Watchdog_Control  *first;
> -
> -  _Watchdog_Acquire( header, &lock_context );
> -
> -  while ( 1 ) {
> -    if ( _Watchdog_Is_empty( header ) ) {
> -      break;
> -    }
> -    first = _Watchdog_First( header );
> -
> -    /*
> -     *  If it is longer than "units" until the first element on the chain
> -     *  fires, then bump it and quit.
> -     */
> -    if ( units < first->delta_interval ) {
> -      first->delta_interval -= units;
> -      break;
> -    }
> -
> -    /*
> -     *  The first set happens in less than units, so take all of them
> -     *  off the chain and adjust units to reflect this.
> -     */
> -    units -= first->delta_interval;
> -    first->delta_interval = 0;
> -
> -    while ( 1 ) {
> -      _Chain_Extract_unprotected( &first->Node );
> -      _Chain_Append_unprotected( to_fire, &first->Node );
> -
> -      _Watchdog_Flash( header, &lock_context );
> -
> -      if ( _Watchdog_Is_empty( header ) )
> -        break;
> -      first = _Watchdog_First( header );
> -      if ( first->delta_interval != 0 )
> -        break;
> -    }
> -  }
> -
> -  _Watchdog_Release( header, &lock_context );
> -}
> -
> diff --git a/cpukit/score/src/watchdoginsert.c b/cpukit/score/src/watchdoginsert.c
> index 6d2df82..6b81c7b 100644
> --- a/cpukit/score/src/watchdoginsert.c
> +++ b/cpukit/score/src/watchdoginsert.c
> @@ -47,15 +47,12 @@ static void _Watchdog_Insert_fixup(
>    }
>  }
>
> -void _Watchdog_Insert(
> +void _Watchdog_Insert_locked(
>    Watchdog_Header  *header,
> -  Watchdog_Control *the_watchdog
> +  Watchdog_Control *the_watchdog,
> +  ISR_lock_Context *lock_context
>  )
>  {
> -  ISR_lock_Context lock_context;
> -
> -  _Watchdog_Acquire( header, &lock_context );
> -
>    if ( the_watchdog->state == WATCHDOG_INACTIVE ) {
>      Watchdog_Iterator  iterator;
>      Chain_Node        *current;
> @@ -86,7 +83,7 @@ void _Watchdog_Insert(
>        iterator.delta_interval = delta - delta_next;
>        iterator.current = next;
>
> -      _Watchdog_Flash( header, &lock_context );
> +      _Watchdog_Flash( header, lock_context );
>
>        if ( the_watchdog->state != WATCHDOG_BEING_INSERTED ) {
>          goto abort_insert;
> @@ -105,6 +102,16 @@ abort_insert:
>
>      _Chain_Extract_unprotected( &iterator.Node );
>    }
> +}
>
> +void _Watchdog_Insert(
> +  Watchdog_Header  *header,
> +  Watchdog_Control *the_watchdog
> +)
> +{
> +  ISR_lock_Context lock_context;
> +
> +  _Watchdog_Acquire( header, &lock_context );
> +  _Watchdog_Insert_locked( header, the_watchdog, &lock_context );
>    _Watchdog_Release( header, &lock_context );
>  }
> diff --git a/testsuites/sptests/spintrcritical17/init.c b/testsuites/sptests/spintrcritical17/init.c
> index 9dde48a..238493e 100644
> --- a/testsuites/sptests/spintrcritical17/init.c
> +++ b/testsuites/sptests/spintrcritical17/init.c
> @@ -1,10 +1,11 @@
>  /*
> - * Copyright (c) 2009
> - * embedded brains GmbH
> - * Obere Lagerstr. 30
> - * D-82178 Puchheim
> - * Germany
> - * <rtems at embedded-brains.de>
> + * Copyright (c) 2009-2014 embedded brains GmbH.
> + *
> + *  embedded brains GmbH
> + *  Dornierstr. 4
> + *  82178 Puchheim
> + *  Germany
> + *  <rtems at embedded-brains.de>
>   *
>   * The license and distribution terms for this file may be
>   * found in the file LICENSE in this distribution or at
> @@ -22,141 +23,91 @@
>
>  const char rtems_test_name[] = "SPINTRCRITICAL 17";
>
> -/* forward declarations to avoid warnings */
> -rtems_task Init(rtems_task_argument argument);
> -
> -#define TIMER_COUNT 4
> -
> -#define TIMER_TRIGGER 0
> -#define TIMER_RESET 1
> -#define TIMER_NEVER_INTERVAL 2
> -#define TIMER_NEVER_TOD 3
> -
> -static rtems_id timer [TIMER_COUNT];
> +typedef struct {
> +  rtems_id timer1;
> +  rtems_id timer2;
> +  bool done;
> +} test_context;
>
> -static rtems_time_of_day tod;
> -
> -static volatile bool case_hit;
> -
> -static void never_callback(rtems_id timer, void *arg)
> -{
> -  rtems_test_assert(false);
> -}
> +static test_context ctx_instance;
>
> -static void reset_tod_timer(void)
> +static void never(rtems_id timer_id, void *arg)
>  {
> -  rtems_status_code sc = RTEMS_SUCCESSFUL;
> -
> -  sc = rtems_timer_server_fire_when(
> -    timer [TIMER_NEVER_TOD],
> -    &tod,
> -    never_callback,
> -    NULL
> -  );
> -  directive_failed_with_level(sc, "rtems_timer_server_fire_after", -1);
> +  rtems_test_assert(0);
>  }
>
> -static void reset_callback(rtems_id timer_id, void *arg)
> +static void fire(rtems_id timer_id, void *arg)
>  {
> -  rtems_status_code sc = RTEMS_SUCCESSFUL;
> -
> -  sc = rtems_timer_reset(timer [TIMER_RESET]);
> -  directive_failed_with_level(sc, "rtems_timer_reset", -1);
> -
> -  sc = rtems_timer_reset(timer [TIMER_NEVER_INTERVAL]);
> -  directive_failed_with_level(sc, "rtems_timer_reset", -1);
> -
> -  reset_tod_timer();
> -
> -  if (!case_hit) {
> -    case_hit = _Timer_server->insert_chain != NULL;
> +  /* The arg is NULL */
> +  test_context *ctx = &ctx_instance;
> +  rtems_status_code sc;
> +
> +  if (!ctx->done) {
> +    ctx->done =
> +      _Timer_server->Interval_watchdogs.system_watchdog_helper != NULL;
> +
> +    if (ctx->done) {
> +      sc = rtems_timer_server_fire_after(ctx->timer2, 100, never, NULL);
> +      rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +    }
>    }
>  }
>
> -static void trigger_callback(rtems_id timer_id, void *arg)
> +static bool test_body(void *arg)
>  {
> -  rtems_status_code sc = RTEMS_SUCCESSFUL;
> +  test_context *ctx = arg;
> +  rtems_status_code sc;
>
> -  if (case_hit) {
> -    TEST_END();
> +  sc = rtems_timer_reset(ctx->timer1);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
>
> -    rtems_test_exit(0);
> -  } else if (interrupt_critical_section_test_support_delay()) {
> -    puts("test case not hit, give up");
> -
> -    rtems_test_exit(0);
> -  }
> -
> -  sc = rtems_timer_reset(timer [TIMER_TRIGGER]);
> -  directive_failed(sc, "rtems_timer_reset");
> +  return ctx->done;
>  }
>
> -rtems_task Init( rtems_task_argument ignored )
> +static void Init(rtems_task_argument ignored)
>  {
> -  rtems_status_code sc = RTEMS_SUCCESSFUL;
> -  size_t i = 0;
> +  test_context *ctx = &ctx_instance;
> +  rtems_status_code sc;
>
>    TEST_BEGIN();
>
> -  build_time(&tod, 4, 12, 2009, 9, 34, 11, 0);
> -  sc = rtems_clock_set(&tod);
> -  directive_failed(sc, "rtems_clock_set");
> -
> -  ++tod.year;
> +  sc = rtems_timer_create(
> +    rtems_build_name('T', 'I', 'M', '1'),
> +    &ctx->timer1
> +  );
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
>
> -  for (i = 0; i < TIMER_COUNT; ++i) {
> -    sc = rtems_timer_create(
> -      rtems_build_name('T', 'I', 'M', '0' + i),
> -      &timer [i]
> -    );
> -    directive_failed(sc, "rtems_timer_create");
> -  }
> +  sc = rtems_timer_create(
> +    rtems_build_name('T', 'I', 'M', '2'),
> +    &ctx->timer2
> +  );
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
>
>    sc = rtems_timer_initiate_server(
>      RTEMS_MINIMUM_PRIORITY,
>      RTEMS_MINIMUM_STACK_SIZE,
>      RTEMS_DEFAULT_ATTRIBUTES
>    );
> -  directive_failed(sc, "rtems_timer_initiate_server");
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
>
> -  sc = rtems_timer_server_fire_after(
> -    timer [TIMER_NEVER_INTERVAL],
> -    2,
> -    never_callback,
> -    NULL
> -  );
> -  directive_failed(sc, "rtems_timer_server_fire_after");
> -
> -  reset_tod_timer();
> -
> -  sc = rtems_timer_fire_after(
> -    timer [TIMER_RESET],
> -    1,
> -    reset_callback,
> -    NULL
> -  );
> -  directive_failed(sc, "rtems_timer_fire_after");
> -
> -  sc = rtems_timer_server_fire_after(
> -    timer [TIMER_TRIGGER],
> -    1,
> -    trigger_callback,
> -    NULL
> -  );
> -  directive_failed(sc, "rtems_timer_server_fire_after");
> +  sc = rtems_timer_server_fire_after(ctx->timer1, 1000, never, NULL);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
>
> -  interrupt_critical_section_test_support_initialize(NULL);
> +  interrupt_critical_section_test(test_body, ctx, fire);
> +  rtems_test_assert(ctx->done);
>
> -  rtems_task_delete(RTEMS_SELF);
> +  TEST_END();
> +  rtems_test_exit(0);
>  }
>
>  #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
>  #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
>
> -#define CONFIGURE_MICROSECONDS_PER_TICK 2000
> +#define CONFIGURE_MICROSECONDS_PER_TICK 1000
>
>  #define CONFIGURE_MAXIMUM_TASKS 2
> -#define CONFIGURE_MAXIMUM_TIMERS 4
> +#define CONFIGURE_MAXIMUM_TIMERS 3
> +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
>
>  #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
>
> diff --git a/testsuites/sptests/spintrcritical17/spintrcritical17.doc b/testsuites/sptests/spintrcritical17/spintrcritical17.doc
> index 3be8e60..809a966 100644
> --- a/testsuites/sptests/spintrcritical17/spintrcritical17.doc
> +++ b/testsuites/sptests/spintrcritical17/spintrcritical17.doc
> @@ -1,4 +1,4 @@
> -#  Copyright (c) 2009 embedded brains GmbH.
> +#  Copyright (c) 2009-2015 embedded brains GmbH.
>  #
>  #  The license and distribution terms for this file may be
>  #  found in the file LICENSE in this distribution or at
> @@ -11,9 +11,7 @@ test set name:  spintrcritical17
>
>  directives:
>
> -  _Timer_server_Get_watchdogs_that_fire_now
> -  _Timer_server_Schedule_operation_method
> -  _Timer_server_Process_insertions
> +  _Timer_server_Update_system_watchdog
>
>  concepts:
>
> --
> 1.8.4.5
>
>
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel



More information about the devel mailing list