[PATCH 8/8] score: Replace watchdog handler implementation

Joel Sherrill joel at rtems.org
Thu Mar 3 15:23:24 UTC 2016


This looks OK but is such a large patch, it needs more eyes.

Gedare and Chris... please.

On Thu, Mar 3, 2016 at 8:47 AM, Sebastian Huber <
sebastian.huber at embedded-brains.de> wrote:

> Use a red-black tree instead of delta chains.
>
> Close #2344.
> Update #2554.
> Update #2555.
> Close #2606.
> ---
>  cpukit/posix/Makefile.am                           |   3 +-
>  cpukit/posix/include/rtems/posix/pthreadimpl.h     |   5 +-
>  cpukit/posix/include/rtems/posix/threadsup.h       |   2 +
>  cpukit/posix/include/rtems/posix/timerimpl.h       |  54 +-
>  cpukit/posix/src/alarm.c                           |  96 ++--
>  cpukit/posix/src/nanosleep.c                       |   5 +-
>  cpukit/posix/src/pthread.c                         |  31 +-
>  cpukit/posix/src/pthreadcreate.c                   |   6 +-
>  cpukit/posix/src/pthreadsetschedparam.c            |  14 +-
>  cpukit/posix/src/timercreate.c                     |   3 +-
>  cpukit/posix/src/timerdelete.c                     |  12 +-
>  cpukit/posix/src/timergetoverrun.c                 |   7 +-
>  cpukit/posix/src/timergettime.c                    |  29 +-
>  cpukit/posix/src/timerinserthelper.c               |  66 ---
>  cpukit/posix/src/timersettime.c                    | 152 ++++--
>  cpukit/posix/src/timertsr.c                        |  89 ----
>  cpukit/posix/src/ualarm.c                          | 155 +++---
>  cpukit/rtems/include/rtems/rtems/ratemonimpl.h     |  24 +-
>  cpukit/rtems/include/rtems/rtems/timer.h           |  59 ++-
>  cpukit/rtems/include/rtems/rtems/timerimpl.h       | 216 ++++----
>  cpukit/rtems/src/eventseize.c                      |  11 +-
>  cpukit/rtems/src/eventsurrender.c                  |   2 +-
>  cpukit/rtems/src/ratemoncancel.c                   |   5 +-
>  cpukit/rtems/src/ratemoncreate.c                   |   3 +-
>  cpukit/rtems/src/ratemondelete.c                   |   5 +-
>  cpukit/rtems/src/ratemonperiod.c                   |  38 +-
>  cpukit/rtems/src/ratemontimeout.c                  |  50 +-
>  cpukit/rtems/src/taskwakeafter.c                   |   9 +-
>  cpukit/rtems/src/taskwakewhen.c                    |  18 +-
>  cpukit/rtems/src/timercancel.c                     |  31 +-
>  cpukit/rtems/src/timercreate.c                     | 179 ++++++-
>  cpukit/rtems/src/timerdelete.c                     |  14 +-
>  cpukit/rtems/src/timerfireafter.c                  |  64 +--
>  cpukit/rtems/src/timerfirewhen.c                   |  50 +-
>  cpukit/rtems/src/timergetinfo.c                    |  13 +-
>  cpukit/rtems/src/timerreset.c                      |  41 +-
>  cpukit/rtems/src/timerserver.c                     | 394 ++++----------
>  cpukit/rtems/src/timerserverfireafter.c            |  68 +--
>  cpukit/rtems/src/timerserverfirewhen.c             |  70 +--
>  cpukit/sapi/src/exinit.c                           |   3 -
>  cpukit/score/Makefile.am                           |   5 +-
>  cpukit/score/include/rtems/score/mrsp.h            |   7 +-
>  cpukit/score/include/rtems/score/mrspimpl.h        |  32 +-
>  cpukit/score/include/rtems/score/percpu.h          |  53 +-
>  cpukit/score/include/rtems/score/schedulerimpl.h   |  16 +-
>  cpukit/score/include/rtems/score/thread.h          |  13 +-
>  cpukit/score/include/rtems/score/threadimpl.h      |  61 ++-
>  cpukit/score/include/rtems/score/todimpl.h         |  17 -
>  cpukit/score/include/rtems/score/watchdog.h        |  89 ++--
>  cpukit/score/include/rtems/score/watchdogimpl.h    | 590
> +++++++++------------
>  cpukit/score/src/condition.c                       |   2 +-
>  cpukit/score/src/coretodset.c                      |  28 +-
>  cpukit/score/src/coretodtickle.c                   |  36 --
>  cpukit/score/src/kern_tc.c                         |   3 +-
>  cpukit/score/src/smp.c                             |   1 +
>  cpukit/score/src/threadinitialize.c                |   4 +
>  cpukit/score/src/threadqenqueue.c                  |  10 +-
>  cpukit/score/src/threadrestart.c                   |  12 +-
>  cpukit/score/src/threadtimeout.c                   |   4 +-
>  cpukit/score/src/watchdog.c                        |  36 --
>  cpukit/score/src/watchdogadjust.c                  |  80 ---
>  cpukit/score/src/watchdoginsert.c                  | 132 ++---
>  cpukit/score/src/watchdogremove.c                  | 172 +-----
>  cpukit/score/src/watchdogtick.c                    |  78 ++-
>  testsuites/smptests/Makefile.am                    |   1 +
>  testsuites/smptests/configure.ac                   |   1 +
>  testsuites/smptests/smpclock01/Makefile.am         |  20 +
>  testsuites/smptests/smpclock01/init.c              | 206 +++++++
>  testsuites/smptests/smpclock01/smpclock01.doc      |  11 +
>  testsuites/smptests/smpclock01/smpclock01.scn      |   2 +
>  .../smptests/smpwakeafter01/smpwakeafter01.scn     | 224 ++++++--
>  testsuites/sptests/Makefile.am                     |   3 +-
>  testsuites/sptests/configure.ac                    |   2 +-
>  testsuites/sptests/sp31/task1.c                    |  22 -
>  testsuites/sptests/spintrcritical08/init.c         |  26 +-
>  testsuites/sptests/spintrcritical09/init.c         |  27 +-
>  testsuites/sptests/spintrcritical10/init.c         |   6 +-
>  testsuites/sptests/spintrcritical16/init.c         |   2 +-
>  testsuites/sptests/spintrcritical17/Makefile.am    |  25 -
>  testsuites/sptests/spintrcritical17/init.c         | 118 -----
>  .../sptests/spintrcritical17/spintrcritical17.doc  |  18 -
>  .../sptests/spintrcritical17/spintrcritical17.scn  |   2 -
>  testsuites/sptests/spintrcritical20/init.c         |   2 +-
>  testsuites/sptests/spsize/size.c                   |   2 -
>  testsuites/sptests/sptimecounter01/init.c          |   3 -
>  testsuites/sptests/sptimerserver01/Makefile.am     |  19 +
>  testsuites/sptests/sptimerserver01/init.c          | 129 +++++
>  .../sptests/sptimerserver01/sptimerserver01.doc    |  12 +
>  .../sptests/sptimerserver01/sptimerserver01.scn    |   2 +
>  testsuites/sptests/spwatchdog/init.c               | 381 ++++++-------
>  testsuites/tmtests/tmtimer01/tmtimer01.scn         |  90 ++--
>  91 files changed, 2340 insertions(+), 2593 deletions(-)
>  delete mode 100644 cpukit/posix/src/timerinserthelper.c
>  delete mode 100644 cpukit/posix/src/timertsr.c
>  delete mode 100644 cpukit/score/src/coretodtickle.c
>  delete mode 100644 cpukit/score/src/watchdog.c
>  delete mode 100644 cpukit/score/src/watchdogadjust.c
>  create mode 100644 testsuites/smptests/smpclock01/Makefile.am
>  create mode 100644 testsuites/smptests/smpclock01/init.c
>  create mode 100644 testsuites/smptests/smpclock01/smpclock01.doc
>  create mode 100644 testsuites/smptests/smpclock01/smpclock01.scn
>  delete mode 100644 testsuites/sptests/spintrcritical17/Makefile.am
>  delete mode 100644 testsuites/sptests/spintrcritical17/init.c
>  delete mode 100644
> testsuites/sptests/spintrcritical17/spintrcritical17.doc
>  delete mode 100644
> testsuites/sptests/spintrcritical17/spintrcritical17.scn
>  create mode 100644 testsuites/sptests/sptimerserver01/Makefile.am
>  create mode 100644 testsuites/sptests/sptimerserver01/init.c
>  create mode 100644 testsuites/sptests/sptimerserver01/sptimerserver01.doc
>  create mode 100644 testsuites/sptests/sptimerserver01/sptimerserver01.scn
>
> diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am
> index 40bc153..62a2a5a 100644
> --- a/cpukit/posix/Makefile.am
> +++ b/cpukit/posix/Makefile.am
> @@ -196,8 +196,7 @@ libposix_a_SOURCES += src/adjtime.c
> src/clockgetcpuclockid.c
>
>  ## TIMER_C_FILES
>  libposix_a_SOURCES += src/ptimer.c src/timercreate.c src/timerdelete.c \
> -    src/timergetoverrun.c src/timergettime.c src/timersettime.c \
> -    src/timertsr.c src/timerinserthelper.c
> +    src/timergetoverrun.c src/timergettime.c src/timersettime.c
>
>  ## ITIMER_C_FILES
>  libposix_a_SOURCES += src/getitimer.c src/setitimer.c
> diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h
> b/cpukit/posix/include/rtems/posix/pthreadimpl.h
> index 870b5f9..16b0163 100644
> --- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
> +++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
> @@ -114,10 +114,7 @@ void _POSIX_Threads_Sporadic_budget_callout(
>   * @param[in] argument is a pointer to the Thread_Control structure
>   *            for the thread being replenished.
>   */
> -void _POSIX_Threads_Sporadic_budget_TSR(
> -  Objects_Id      id,
> -  void           *argument
> -);
> +void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog );
>
>  /**
>   * @brief Translate sched_param into SuperCore terms.
> diff --git a/cpukit/posix/include/rtems/posix/threadsup.h
> b/cpukit/posix/include/rtems/posix/threadsup.h
> index 55db35d..7cd2354 100644
> --- a/cpukit/posix/include/rtems/posix/threadsup.h
> +++ b/cpukit/posix/include/rtems/posix/threadsup.h
> @@ -42,6 +42,8 @@ extern "C" {
>   * each thread in a system with POSIX configured.
>   */
>  typedef struct {
> +  /** Back pointer to thread of this POSIX API control. */
> +  Thread_Control         *thread;
>    /** This is the POSIX threads attribute set. */
>    pthread_attr_t          Attributes;
>    /** This indicates whether the thread is attached or detached. */
> diff --git a/cpukit/posix/include/rtems/posix/timerimpl.h
> b/cpukit/posix/include/rtems/posix/timerimpl.h
> index 8b5b42e..8c151c1 100644
> --- a/cpukit/posix/include/rtems/posix/timerimpl.h
> +++ b/cpukit/posix/include/rtems/posix/timerimpl.h
> @@ -21,6 +21,7 @@
>
>  #include <rtems/posix/timer.h>
>  #include <rtems/score/objectimpl.h>
> +#include <rtems/score/watchdogimpl.h>
>
>  #ifdef __cplusplus
>  extern "C" {
> @@ -51,24 +52,6 @@ extern "C" {
>  #endif
>
>  /**
> - *  @brief POSIX Timer Manager Timer Service Routine Helper
> - *
> - *  This is the operation that is run when a timer expires.
> - */
> -void _POSIX_Timer_TSR(Objects_Id timer, void *data);
> -
> -/**
> - *  @brief POSIX Timer Watchdog Insertion Helper
> - */
> -bool _POSIX_Timer_Insert_helper(
> -  Watchdog_Control               *timer,
> -  Watchdog_Interval               ticks,
> -  Objects_Id                      id,
> -  Watchdog_Service_routine_entry  TSR,
> -  void                           *arg
> -);
> -
> -/**
>   *  The following defines the information control block used to manage
>   *  this class of objects.
>   */
> @@ -98,6 +81,8 @@ RTEMS_INLINE_ROUTINE void _POSIX_Timer_Free (
>    _Objects_Free( &_POSIX_Timer_Information, &the_timer->Object );
>  }
>
> +void _POSIX_Timer_TSR( Watchdog_Control *the_watchdog );
> +
>  /**
>   *  @brief POSIX Timer Get
>   *
> @@ -109,11 +94,38 @@ RTEMS_INLINE_ROUTINE void _POSIX_Timer_Free (
>   */
>  RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Get (
>    timer_t            id,
> -  Objects_Locations *location
> +  Objects_Locations *location,
> +  ISR_lock_Context  *lock_context
> +)
> +{
> +  return (POSIX_Timer_Control *) _Objects_Get_isr_disable(
> +    &_POSIX_Timer_Information,
> +    (Objects_Id) id,
> +    location,
> +    lock_context
> +  );
> +}
> +
> +RTEMS_INLINE_ROUTINE Per_CPU_Control *_POSIX_Timer_Acquire_critical(
> +  POSIX_Timer_Control *ptimer,
> +  ISR_lock_Context    *lock_context
> +)
> +{
> +  Per_CPU_Control *cpu;
> +
> +  cpu = _Watchdog_Get_CPU( &ptimer->Timer );
> +  _Watchdog_Per_CPU_acquire( cpu, lock_context );
> +
> +  return cpu;
> +}
> +
> +RTEMS_INLINE_ROUTINE void _POSIX_Timer_Release(
> +  Per_CPU_Control  *cpu,
> +  ISR_lock_Context *lock_context
>  )
>  {
> -  return (POSIX_Timer_Control *)
> -    _Objects_Get( &_POSIX_Timer_Information, (Objects_Id) id, location );
> +  _Watchdog_Per_CPU_release( cpu, lock_context );
> +  _ISR_lock_ISR_enable( lock_context );
>  }
>
>  #ifdef __cplusplus
> diff --git a/cpukit/posix/src/alarm.c b/cpukit/posix/src/alarm.c
> index e85622f..196bc16 100644
> --- a/cpukit/posix/src/alarm.c
> +++ b/cpukit/posix/src/alarm.c
> @@ -22,29 +22,18 @@
>  #endif
>
>  #include <unistd.h>
> +#include <signal.h>
>
> -#include <rtems/posix/pthreadimpl.h>
> -#include <rtems/posix/psignalimpl.h>
> -#include <rtems/score/threaddispatch.h>
>  #include <rtems/score/todimpl.h>
>  #include <rtems/score/watchdogimpl.h>
>
> -/*
> - *  _POSIX_signals_Alarm_TSR
> - */
> -static void _POSIX_signals_Alarm_TSR(
> -  Objects_Id      id RTEMS_UNUSED,
> -  void           *argument RTEMS_UNUSED
> -)
> +ISR_LOCK_DEFINE( static, _POSIX_signals_Alarm_lock, "POSIX Alarm" )
> +
> +static void _POSIX_signals_Alarm_TSR( Watchdog_Control *the_watchdog )
>  {
> -  #if defined(RTEMS_DEBUG)
> -    int status;
> -    #define KILL_STATUS status =
> -  #else
> -    #define KILL_STATUS (void)
> -  #endif
> +  int status;
>
> -  KILL_STATUS kill( getpid(), SIGALRM );
> +  status = kill( getpid(), SIGALRM );
>
>    #if defined(RTEMS_DEBUG)
>      /*
> @@ -52,43 +41,62 @@ static void _POSIX_signals_Alarm_TSR(
>       *  cautious.
>       */
>      _Assert(status == 0);
> +  #else
> +    (void) status;
>    #endif
>  }
>
> -static Watchdog_Control _POSIX_signals_Alarm_timer = WATCHDOG_INITIALIZER(
> -  _POSIX_signals_Alarm_TSR,
> -  0,
> -  NULL
> +static Watchdog_Control _POSIX_signals_Alarm_watchdog =
> WATCHDOG_INITIALIZER(
> +  _POSIX_signals_Alarm_TSR
>  );
>
>  unsigned int alarm(
>    unsigned int seconds
>  )
>  {
> -  unsigned int      remaining = 0;
> -  Watchdog_Control *the_timer;
> -  Watchdog_States   state;
> -
> -  the_timer = &_POSIX_signals_Alarm_timer;
> -
> -  _Thread_Disable_dispatch();
> -
> -  state = _Watchdog_Remove_seconds( the_timer );
> -  if ( state == WATCHDOG_ACTIVE ) {
> -    /*
> -     *  The stop_time and start_time fields are snapshots of ticks since
> -     *  boot.  Since alarm() is dealing in seconds, we must account for
> -     *  this.
> -     */
> -
> -    remaining = the_timer->initial -
> -      ((the_timer->stop_time - the_timer->start_time) /
> TOD_TICKS_PER_SECOND);
> +  unsigned int      remaining;
> +  Watchdog_Control *the_watchdog;
> +  ISR_lock_Context  lock_context;
> +  ISR_lock_Context  lock_context2;
> +  Per_CPU_Control  *cpu;
> +  uint64_t          now;
> +  uint32_t          ticks_per_second;
> +  uint32_t          ticks;
> +
> +  the_watchdog = &_POSIX_signals_Alarm_watchdog;
> +  ticks_per_second = TOD_TICKS_PER_SECOND;
> +  ticks = seconds * ticks_per_second;
> +
> +  _ISR_lock_ISR_disable_and_acquire(
> +    &_POSIX_signals_Alarm_lock,
> +    &lock_context
> +  );
> +
> +  cpu = _Watchdog_Get_CPU( the_watchdog );
> +  _Watchdog_Per_CPU_acquire( cpu, &lock_context2 );
> +  now = cpu->Watchdog.ticks;
> +
> +  remaining = (unsigned long) _Watchdog_Cancel(
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +    the_watchdog,
> +    now
> +  );
> +
> +  if ( ticks != 0 ) {
> +    cpu = _Per_CPU_Get();
> +    _Watchdog_Set_CPU( the_watchdog, cpu );
> +    _Watchdog_Insert(
> +      &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +      the_watchdog,
> +      now + ticks
> +    );
>    }
>
> -  if ( seconds )
> -    _Watchdog_Insert_seconds( the_timer, seconds );
> -
> -  _Thread_Enable_dispatch();
> +  _Watchdog_Per_CPU_release( cpu, &lock_context2 );
> +  _ISR_lock_Release_and_ISR_enable(
> +    &_POSIX_signals_Alarm_lock,
> +    &lock_context
> +  );
>
> -  return remaining;
> +  return ( remaining + ticks_per_second - 1 ) / ticks_per_second;
>  }
> diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c
> index 46697ae..21bdb98 100644
> --- a/cpukit/posix/src/nanosleep.c
> +++ b/cpukit/posix/src/nanosleep.c
> @@ -46,6 +46,7 @@ int nanosleep(
>    Per_CPU_Control *cpu_self;
>
>    Watchdog_Interval  ticks;
> +  Watchdog_Interval  start;
>    Watchdog_Interval  elapsed;
>
>
> @@ -81,6 +82,8 @@ int nanosleep(
>      return 0;
>    }
>
> +  start = _Watchdog_Ticks_since_boot;
> +
>    /*
>     *  Block for the desired amount of time
>     */
> @@ -96,7 +99,7 @@ int nanosleep(
>     * Calculate the time that passed while we were sleeping and how
>     * much remains from what we requested.
>     */
> -  elapsed = executing->Timer.stop_time - executing->Timer.start_time;
> +  elapsed = _Watchdog_Ticks_since_boot - start;
>    if ( elapsed >= ticks )
>      ticks = 0;
>    else
> diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
> index ac5fbe4..001ae79 100644
> --- a/cpukit/posix/src/pthread.c
> +++ b/cpukit/posix/src/pthread.c
> @@ -104,18 +104,15 @@ static bool
> _POSIX_Threads_Sporadic_budget_TSR_filter(
>  /*
>   *  _POSIX_Threads_Sporadic_budget_TSR
>   */
> -void _POSIX_Threads_Sporadic_budget_TSR(
> -  Objects_Id      id RTEMS_UNUSED,
> -  void           *argument
> -)
> +void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
>  {
>    uint32_t            ticks;
> -  Thread_Control     *the_thread;
>    POSIX_API_Control  *api;
> +  Thread_Control     *the_thread;
> +  ISR_Level           level;
>
> -  the_thread = argument;
> -
> -  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
> +  api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic_timer );
> +  the_thread = api->thread;
>
>    /* ticks is guaranteed to be at least one */
>    ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget );
> @@ -133,7 +130,15 @@ void _POSIX_Threads_Sporadic_budget_TSR(
>    /* ticks is guaranteed to be at least one */
>    ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period );
>
> -  _Watchdog_Insert_ticks( &api->Sporadic_timer, ticks );
> +  _Thread_Disable_dispatch();
> +  _ISR_Disable( level );
> +  _Watchdog_Per_CPU_insert_relative(
> +    &api->Sporadic_timer,
> +    _Per_CPU_Get(),
> +    ticks
> +  );
> +  _ISR_Enable( level );
> +  _Thread_Unnest_dispatch();
>  }
>
>  static bool _POSIX_Threads_Sporadic_budget_callout_filter(
> @@ -198,6 +203,7 @@ static bool _POSIX_Threads_Create_extension(
>    api = created->API_Extensions[ THREAD_API_POSIX ];
>
>    /* XXX check all fields are touched */
> +  api->thread = created;
>    _POSIX_Threads_Initialize_attributes( &api->Attributes );
>    api->detachstate = _POSIX_Threads_Default_attributes.detachstate;
>    api->schedpolicy = _POSIX_Threads_Default_attributes.schedpolicy;
> @@ -229,11 +235,10 @@ static bool _POSIX_Threads_Create_extension(
>
>    _Thread_queue_Initialize( &api->Join_List, THREAD_QUEUE_DISCIPLINE_FIFO
> );
>
> +  _Watchdog_Preinitialize( &api->Sporadic_timer, _Per_CPU_Get_by_index( 0
> ) );
>    _Watchdog_Initialize(
>      &api->Sporadic_timer,
> -    _POSIX_Threads_Sporadic_budget_TSR,
> -    created->Object.id,
> -    created
> +    _POSIX_Threads_Sporadic_budget_TSR
>    );
>
>    return true;
> @@ -260,7 +265,7 @@ static void _POSIX_Threads_Terminate_extension(
>        *(void **)the_thread->Wait.return_argument = value_ptr;
>
>    if ( api->schedpolicy == SCHED_SPORADIC )
> -    _Watchdog_Remove_ticks( &api->Sporadic_timer );
> +    _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
>
>    _Thread_queue_Destroy( &api->Join_List );
>
> diff --git a/cpukit/posix/src/pthreadcreate.c
> b/cpukit/posix/src/pthreadcreate.c
> index 3185ab6..fc07b1f 100644
> --- a/cpukit/posix/src/pthreadcreate.c
> +++ b/cpukit/posix/src/pthreadcreate.c
> @@ -74,6 +74,7 @@ int pthread_create(
>    struct sched_param                  schedparam;
>    Objects_Name                        name;
>    int                                 rc;
> +  ISR_Level                           level;
>
>    if ( !start_routine )
>      return EFAULT;
> @@ -246,10 +247,13 @@ int pthread_create(
>    #endif
>
>    if ( schedpolicy == SCHED_SPORADIC ) {
> -    _Watchdog_Insert_ticks(
> +    _ISR_Disable( level );
> +    _Watchdog_Per_CPU_insert_relative(
>        &api->Sporadic_timer,
> +      _Per_CPU_Get(),
>        _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period )
>      );
> +    _ISR_Enable( level );
>    }
>
>    _Thread_Enable_dispatch();
> diff --git a/cpukit/posix/src/pthreadsetschedparam.c
> b/cpukit/posix/src/pthreadsetschedparam.c
> index c3be366..c9560f5 100644
> --- a/cpukit/posix/src/pthreadsetschedparam.c
> +++ b/cpukit/posix/src/pthreadsetschedparam.c
> @@ -44,6 +44,7 @@ int pthread_setschedparam(
>    Objects_Locations                    location;
>    int                                  rc;
>    Priority_Control                     unused;
> +  ISR_Level                            level;
>
>    /*
>     *  Check all the parameters
> @@ -69,8 +70,11 @@ int pthread_setschedparam(
>      case OBJECTS_LOCAL:
>        api = the_thread->API_Extensions[ THREAD_API_POSIX ];
>
> -      if ( api->schedpolicy == SCHED_SPORADIC )
> -        _Watchdog_Remove_ticks( &api->Sporadic_timer );
> +      if ( api->schedpolicy == SCHED_SPORADIC ) {
> +        _ISR_Disable( level );
> +        _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
> +        _ISR_Enable( level );
> +      }
>
>        api->schedpolicy = policy;
>        api->schedparam  = *param;
> @@ -97,8 +101,10 @@ int pthread_setschedparam(
>
>          case SCHED_SPORADIC:
>            api->ss_high_priority = api->schedparam.sched_priority;
> -          _Watchdog_Remove_ticks( &api->Sporadic_timer );
> -          _POSIX_Threads_Sporadic_budget_TSR( 0, the_thread );
> +          _ISR_Disable( level );
> +          _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
> +          _ISR_Enable( level );
> +          _POSIX_Threads_Sporadic_budget_TSR( &api->Sporadic_timer );
>            break;
>        }
>
> diff --git a/cpukit/posix/src/timercreate.c
> b/cpukit/posix/src/timercreate.c
> index 697f1ce..5123071 100644
> --- a/cpukit/posix/src/timercreate.c
> +++ b/cpukit/posix/src/timercreate.c
> @@ -91,7 +91,8 @@ int timer_create(
>    ptimer->timer_data.it_interval.tv_sec  = 0;
>    ptimer->timer_data.it_interval.tv_nsec = 0;
>
> -  _Watchdog_Preinitialize( &ptimer->Timer );
> +  _Watchdog_Preinitialize( &ptimer->Timer, _Per_CPU_Get_snapshot() );
> +  _Watchdog_Initialize( &ptimer->Timer, _POSIX_Timer_TSR );
>    _Objects_Open_u32(&_POSIX_Timer_Information, &ptimer->Object, 0);
>
>    *timerid  = ptimer->Object.id;
> diff --git a/cpukit/posix/src/timerdelete.c
> b/cpukit/posix/src/timerdelete.c
> index 8438b0d..c39de8e 100644
> --- a/cpukit/posix/src/timerdelete.c
> +++ b/cpukit/posix/src/timerdelete.c
> @@ -45,16 +45,22 @@ int timer_delete(
>    */
>    POSIX_Timer_Control *ptimer;
>    Objects_Locations    location;
> +  ISR_lock_Context     lock_context;
> +  Per_CPU_Control     *cpu;
>
>    _Objects_Allocator_lock();
> -  ptimer = _POSIX_Timer_Get( timerid, &location );
> +  ptimer = _POSIX_Timer_Get( timerid, &location, &lock_context );
>    switch ( location ) {
>
>      case OBJECTS_LOCAL:
>        _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object );
> +      cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
>        ptimer->state = POSIX_TIMER_STATE_FREE;
> -      _Watchdog_Remove_ticks( &ptimer->Timer );
> -      _Objects_Put( &ptimer->Object );
> +      _Watchdog_Remove(
> +        &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +        &ptimer->Timer
> +      );
> +      _POSIX_Timer_Release( cpu, &lock_context );
>        _POSIX_Timer_Free( ptimer );
>        _Objects_Allocator_unlock();
>
> diff --git a/cpukit/posix/src/timergetoverrun.c
> b/cpukit/posix/src/timergetoverrun.c
> index dd7669e..0a28fa7 100644
> --- a/cpukit/posix/src/timergetoverrun.c
> +++ b/cpukit/posix/src/timergetoverrun.c
> @@ -33,14 +33,17 @@ int timer_getoverrun(
>    int                  overrun;
>    POSIX_Timer_Control *ptimer;
>    Objects_Locations    location;
> +  ISR_lock_Context     lock_context;
> +  Per_CPU_Control     *cpu;
>
> -  ptimer = _POSIX_Timer_Get( timerid, &location );
> +  ptimer = _POSIX_Timer_Get( timerid, &location, &lock_context );
>    switch ( location ) {
>
>      case OBJECTS_LOCAL:
> +      cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
>        overrun = ptimer->overrun;
>        ptimer->overrun = 0;
> -      _Objects_Put( &ptimer->Object );
> +      _POSIX_Timer_Release( cpu, &lock_context );
>        return overrun;
>
>  #if defined(RTEMS_MULTIPROCESSING)
> diff --git a/cpukit/posix/src/timergettime.c
> b/cpukit/posix/src/timergettime.c
> index f065cc9..7f0015b 100644
> --- a/cpukit/posix/src/timergettime.c
> +++ b/cpukit/posix/src/timergettime.c
> @@ -42,31 +42,32 @@ int timer_gettime(
>  {
>    POSIX_Timer_Control *ptimer;
>    Objects_Locations    location;
> -  struct timespec      current_time;
> -  Watchdog_Interval    left;
> +  ISR_lock_Context     lock_context;
> +  Per_CPU_Control     *cpu;
> +  uint64_t             now;
> +  uint32_t             remaining;
>
>    if ( !value )
>      rtems_set_errno_and_return_minus_one( EINVAL );
>
> -  /* Reads the current time */
> -  _TOD_Get_as_timespec( &current_time );
> -
> -  ptimer = _POSIX_Timer_Get( timerid, &location );
> +  ptimer = _POSIX_Timer_Get( timerid, &location, &lock_context );
>    switch ( location ) {
>
>      case OBJECTS_LOCAL:
>
> -      /* Calculates the time left before the timer finishes */
> -
> -      left =
> -        (ptimer->Timer.start_time + ptimer->Timer.initial) - /* expire */
> -        _Watchdog_Ticks_since_boot;                          /* now */
> +      cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
> +      now = cpu->Watchdog.ticks;
>
> -      _Timespec_From_ticks( left, &value->it_value );
> +      if ( now < ptimer->Timer.expire ) {
> +        remaining = (uint32_t) ( ptimer->Timer.expire - now );
> +      } else {
> +        remaining = 0;
> +      }
>
> -      value->it_interval  = ptimer->timer_data.it_interval;
> +      _Timespec_From_ticks( remaining, &value->it_value );
> +      value->it_interval = ptimer->timer_data.it_interval;
>
> -      _Objects_Put( &ptimer->Object );
> +      _POSIX_Timer_Release( cpu, &lock_context );
>        return 0;
>
>  #if defined(RTEMS_MULTIPROCESSING)
> diff --git a/cpukit/posix/src/timerinserthelper.c
> b/cpukit/posix/src/timerinserthelper.c
> deleted file mode 100644
> index b1f3373..0000000
> --- a/cpukit/posix/src/timerinserthelper.c
> +++ /dev/null
> @@ -1,66 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Helper Routine for POSIX TIMERS
> - * @ingroup POSIXAPI
> - */
> -
> -/*
> - *  Helper routine for POSIX timers
> - *
> - *  COPYRIGHT (c) 1989-2007.
> - *  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 <time.h>
> -
> -#include <rtems/system.h>
> -#include <rtems/seterr.h>
> -#include <rtems/score/isr.h>
> -#include <rtems/score/watchdogimpl.h>
> -#include <rtems/posix/timerimpl.h>
> -#include <rtems/posix/ptimer.h>
> -
> -bool _POSIX_Timer_Insert_helper(
> -  Watchdog_Control               *timer,
> -  Watchdog_Interval               ticks,
> -  Objects_Id                      id,
> -  Watchdog_Service_routine_entry  TSR,
> -  void                           *arg
> -)
> -{
> -  ISR_lock_Context  lock_context;
> -  Watchdog_Header  *header;
> -
> -  _Watchdog_Remove_ticks( timer );
> -
> -  header = &_Watchdog_Ticks_header;
> -  _Watchdog_Acquire( header, &lock_context );
> -
> -    /*
> -     *  Check to see if the watchdog has just been inserted by a
> -     *  higher priority interrupt.  If so, abandon this insert.
> -     */
> -    if ( timer->state != WATCHDOG_INACTIVE ) {
> -      _Watchdog_Release( header, &lock_context );
> -      return false;
> -    }
> -
> -    /*
> -     *  OK.  Now we now the timer was not rescheduled by an interrupt
> -     *  so we can atomically initialize it as in use.
> -     */
> -    _Watchdog_Initialize( timer, TSR, id, arg );
> -    timer->initial = ticks;
> -    _Watchdog_Insert_locked( header, timer, &lock_context );
> -  _Watchdog_Release( header, &lock_context );
> -  return true;
> -}
> diff --git a/cpukit/posix/src/timersettime.c
> b/cpukit/posix/src/timersettime.c
> index fe54ff9..ac5c258 100644
> --- a/cpukit/posix/src/timersettime.c
> +++ b/cpukit/posix/src/timersettime.c
> @@ -29,6 +29,76 @@
>  #include <rtems/score/watchdogimpl.h>
>  #include <rtems/seterr.h>
>
> +static void _POSIX_Timer_Insert(
> +  POSIX_Timer_Control *ptimer,
> +  Per_CPU_Control     *cpu,
> +  Watchdog_Interval    ticks
> +)
> +{
> +  ptimer->ticks = ticks;
> +
> +  /* The state really did not change but just to be safe */
> +  ptimer->state = POSIX_TIMER_STATE_CREATE_RUN;
> +
> +  /* Store the time when the timer was started again */
> +  _TOD_Get_as_timespec( &ptimer->time );
> +
> +  _Watchdog_Insert(
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +    &ptimer->Timer,
> +    cpu->Watchdog.ticks + ticks
> +  );
> +}
> +
> +/*
> + *  This is the operation that is run when a timer expires
> + */
> +void _POSIX_Timer_TSR( Watchdog_Control *the_watchdog )
> +{
> +  POSIX_Timer_Control *ptimer;
> +  ISR_lock_Context     lock_context;
> +  Per_CPU_Control     *cpu;
> +
> +  ptimer = RTEMS_CONTAINER_OF( the_watchdog, POSIX_Timer_Control, Timer );
> +  _ISR_lock_ISR_disable( &lock_context );
> +  cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
> +
> +  /* Increment the number of expirations. */
> +  ptimer->overrun = ptimer->overrun + 1;
> +
> +  /* The timer must be reprogrammed */
> +  if ( ( ptimer->timer_data.it_interval.tv_sec  != 0 ) ||
> +       ( ptimer->timer_data.it_interval.tv_nsec != 0 ) ) {
> +    _POSIX_Timer_Insert( ptimer, cpu, ptimer->ticks );
> +  } else {
> +   /* Indicates that the timer is stopped */
> +   ptimer->state = POSIX_TIMER_STATE_CREATE_STOP;
> +  }
> +
> +  _POSIX_Timer_Release( cpu, &lock_context );
> +
> +  /*
> +   * The sending of the signal to the process running the handling
> function
> +   * specified for that signal is simulated
> +   */
> +
> +  if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) {
> +    _Assert( FALSE );
> +    /*
> +     * TODO: What if an error happens at run-time? This should never
> +     *       occur because the timer should be canceled if the thread
> +     *       is deleted. This method is being invoked from the Clock
> +     *       Tick ISR so even if we decide to take action on an error,
> +     *       we don't have many options. We shouldn't shut the system
> down.
> +     */
> +  }
> +
> +  /* After the signal handler returns, the count of expirations of the
> +   * timer must be set to 0.
> +   */
> +  ptimer->overrun = 0;
> +}
> +
>  int timer_settime(
>    timer_t                  timerid,
>    int                      flags,
> @@ -38,7 +108,8 @@ int timer_settime(
>  {
>    POSIX_Timer_Control *ptimer;
>    Objects_Locations    location;
> -  bool                 activated;
> +  ISR_lock_Context     lock_context;
> +  Per_CPU_Control     *cpu;
>    uint32_t             initial_period;
>    struct itimerspec    normalize;
>
> @@ -77,56 +148,47 @@ int timer_settime(
>     * or start it again
>     */
>
> -  ptimer = _POSIX_Timer_Get( timerid, &location );
> +  ptimer = _POSIX_Timer_Get( timerid, &location, &lock_context );
>    switch ( location ) {
>
>      case OBJECTS_LOCAL:
> +      cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
> +
> +      /* Stop the timer */
> +      _Watchdog_Remove(
> +        &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +        &ptimer->Timer
> +      );
> +
>        /* First, it verifies if the timer must be stopped */
>        if ( normalize.it_value.tv_sec == 0 && normalize.it_value.tv_nsec
> == 0 ) {
> -         /* Stop the timer */
> -         _Watchdog_Remove_ticks( &ptimer->Timer );
> -         /* The old data of the timer are returned */
> -         if ( ovalue )
> -           *ovalue = ptimer->timer_data;
> -         /* The new data are set */
> -         ptimer->timer_data = normalize;
> -         /* Indicates that the timer is created and stopped */
> -         ptimer->state = POSIX_TIMER_STATE_CREATE_STOP;
> -         /* Returns with success */
> -        _Objects_Put( &ptimer->Object );
> +        /* The old data of the timer are returned */
> +        if ( ovalue )
> +          *ovalue = ptimer->timer_data;
> +        /* The new data are set */
> +        ptimer->timer_data = normalize;
> +        /* Indicates that the timer is created and stopped */
> +        ptimer->state = POSIX_TIMER_STATE_CREATE_STOP;
> +        /* Returns with success */
> +        _POSIX_Timer_Release( cpu, &lock_context );
>          return 0;
> -       }
> -
> -       /* Convert from seconds and nanoseconds to ticks */
> -       ptimer->ticks  = _Timespec_To_ticks( &value->it_interval );
> -       initial_period = _Timespec_To_ticks( &normalize.it_value );
> -
> -
> -       activated = _POSIX_Timer_Insert_helper(
> -         &ptimer->Timer,
> -         initial_period,
> -         ptimer->Object.id,
> -         _POSIX_Timer_TSR,
> -         ptimer
> -       );
> -       if ( !activated ) {
> -         _Objects_Put( &ptimer->Object );
> -         return 0;
> -       }
> -
> -       /*
> -        * The timer has been started and is running.  So we return the
> -        * old ones in "ovalue"
> -        */
> -       if ( ovalue )
> -         *ovalue = ptimer->timer_data;
> -       ptimer->timer_data = normalize;
> -
> -       /* Indicate that the time is running */
> -       ptimer->state = POSIX_TIMER_STATE_CREATE_RUN;
> -       _TOD_Get_as_timespec( &ptimer->time );
> -      _Objects_Put( &ptimer->Object );
> -       return 0;
> +      }
> +
> +      /* Convert from seconds and nanoseconds to ticks */
> +      ptimer->ticks  = _Timespec_To_ticks( &value->it_interval );
> +      initial_period = _Timespec_To_ticks( &normalize.it_value );
> +
> +      _POSIX_Timer_Insert( ptimer, cpu, initial_period );
> +
> +      /*
> +       * The timer has been started and is running.  So we return the
> +       * old ones in "ovalue"
> +       */
> +      if ( ovalue )
> +        *ovalue = ptimer->timer_data;
> +      ptimer->timer_data = normalize;
> +      _POSIX_Timer_Release( cpu, &lock_context );
> +      return 0;
>
>  #if defined(RTEMS_MULTIPROCESSING)
>      case OBJECTS_REMOTE:
> diff --git a/cpukit/posix/src/timertsr.c b/cpukit/posix/src/timertsr.c
> deleted file mode 100644
> index 092bf16..0000000
> --- a/cpukit/posix/src/timertsr.c
> +++ /dev/null
> @@ -1,89 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Operation that is run when a timer expires
> - * @ingroup POSIX_INTERNAL_TIMERS Timers
> - */
> -
> -/*
> - * _POSIX_Timer_TSR
> - *
> - *  COPYRIGHT (c) 1989-2007.
> - *  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 <time.h>
> -#include <pthread.h>
> -#include <signal.h>
> -
> -#include <rtems/posix/ptimer.h>
> -#include <rtems/posix/timerimpl.h>
> -#include <rtems/score/todimpl.h>
> -
> -/*
> - *  This is the operation that is run when a timer expires
> - */
> -void _POSIX_Timer_TSR(
> -  Objects_Id timer RTEMS_UNUSED,
> -  void *data)
> -{
> -  POSIX_Timer_Control *ptimer;
> -  bool                 activated;
> -
> -  ptimer = (POSIX_Timer_Control *)data;
> -
> -  /* Increment the number of expirations. */
> -  ptimer->overrun = ptimer->overrun + 1;
> -
> -  /* The timer must be reprogrammed */
> -  if ( ( ptimer->timer_data.it_interval.tv_sec  != 0 ) ||
> -       ( ptimer->timer_data.it_interval.tv_nsec != 0 ) ) {
> -    activated = _POSIX_Timer_Insert_helper(
> -      &ptimer->Timer,
> -      ptimer->ticks,
> -      ptimer->Object.id,
> -      _POSIX_Timer_TSR,
> -      ptimer
> -    );
> -    if ( !activated )
> -      return;
> -
> -    /* Store the time when the timer was started again */
> -    _TOD_Get_as_timespec( &ptimer->time );
> -
> -    /* The state really did not change but just to be safe */
> -    ptimer->state = POSIX_TIMER_STATE_CREATE_RUN;
> -  } else {
> -   /* Indicates that the timer is stopped */
> -   ptimer->state = POSIX_TIMER_STATE_CREATE_STOP;
> -  }
> -
> -  /*
> -   * The sending of the signal to the process running the handling
> function
> -   * specified for that signal is simulated
> -   */
> -
> -  if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) {
> -    _Assert( FALSE );
> -    /*
> -     * TODO: What if an error happens at run-time? This should never
> -     *       occur because the timer should be canceled if the thread
> -     *       is deleted. This method is being invoked from the Clock
> -     *       Tick ISR so even if we decide to take action on an error,
> -     *       we don't have many options. We shouldn't shut the system
> down.
> -     */
> -  }
> -
> -  /* After the signal handler returns, the count of expirations of the
> -   * timer must be set to 0.
> -   */
> -  ptimer->overrun = 0;
> -}
> diff --git a/cpukit/posix/src/ualarm.c b/cpukit/posix/src/ualarm.c
> index 9607d3f..27cd2eb 100644
> --- a/cpukit/posix/src/ualarm.c
> +++ b/cpukit/posix/src/ualarm.c
> @@ -21,39 +21,62 @@
>  #include <signal.h>
>  #include <unistd.h>
>
> -#include <rtems/posix/pthreadimpl.h>
> -#include <rtems/posix/psignalimpl.h>
> -#include <rtems/score/threaddispatch.h>
>  #include <rtems/score/todimpl.h>
>  #include <rtems/score/watchdogimpl.h>
> +#include <rtems/config.h>
>
> -static void _POSIX_signals_Ualarm_TSR( Objects_Id id, void *argument );
> +ISR_LOCK_DEFINE( static, _POSIX_signals_Ualarm_lock, "POSIX Ualarm" )
>
> -static Watchdog_Control _POSIX_signals_Ualarm_timer =
> WATCHDOG_INITIALIZER(
> -  _POSIX_signals_Ualarm_TSR,
> -  0,
> -  NULL
> -);
> -
> -/*
> - *  _POSIX_signals_Ualarm_TSR
> - */
> +static uint32_t _POSIX_signals_Ualarm_interval;
>
> -static void _POSIX_signals_Ualarm_TSR(
> -  Objects_Id      id RTEMS_UNUSED,
> -  void           *argument RTEMS_UNUSED
> -)
> +static void _POSIX_signals_Ualarm_TSR( Watchdog_Control *the_watchdog )
>  {
> -  /*
> -   * Send a SIGALRM but if there is a problem, ignore it.
> -   * It's OK, there isn't a way this should fail.
> -   */
> -  (void) kill( getpid(), SIGALRM );
> +  int              status;
> +  ISR_lock_Context lock_context;
> +
> +  status = kill( getpid(), SIGALRM );
> +
> +  #if defined(RTEMS_DEBUG)
> +    /*
> +     *  There is no reason to think this might fail but we should be
> +     *  cautious.
> +     */
> +    _Assert(status == 0);
> +  #else
> +    (void) status;
> +  #endif
> +
> +  _ISR_lock_ISR_disable_and_acquire(
> +    &_POSIX_signals_Ualarm_lock,
> +    &lock_context
> +  );
>
>    /*
>     * If the reset interval is non-zero, reschedule ourselves.
>     */
> -  _Watchdog_Reset_ticks( &_POSIX_signals_Ualarm_timer );
> +  if ( _POSIX_signals_Ualarm_interval != 0 ) {
> +    _Watchdog_Per_CPU_insert_relative(
> +      the_watchdog,
> +      _Per_CPU_Get(),
> +      _POSIX_signals_Ualarm_interval
> +    );
> +  }
> +
> +  _ISR_lock_Release_and_ISR_enable(
> +    &_POSIX_signals_Ualarm_lock,
> +    &lock_context
> +  );
> +}
> +
> +static Watchdog_Control _POSIX_signals_Ualarm_watchdog =
> WATCHDOG_INITIALIZER(
> +  _POSIX_signals_Ualarm_TSR
> +);
> +
> +static uint32_t _POSIX_signals_Ualarm_us_to_ticks( useconds_t us )
> +{
> +  uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
> +
> +  return ( us + us_per_tick - 1 ) / us_per_tick;
>  }
>
>  useconds_t ualarm(
> @@ -61,51 +84,53 @@ useconds_t ualarm(
>    useconds_t interval
>  )
>  {
> -  useconds_t        remaining = 0;
> -  Watchdog_Control *the_timer;
> -  Watchdog_Interval ticks;
> -  Watchdog_States   state;
> -  struct timespec   tp;
> -
> -  the_timer = &_POSIX_signals_Ualarm_timer;
> -
> -  _Thread_Disable_dispatch();
> -
> -  state = _Watchdog_Remove_ticks( the_timer );
> -  if ( state == WATCHDOG_ACTIVE ) {
> -    /*
> -     *  The stop_time and start_time fields are snapshots of ticks since
> -     *  boot.  Since alarm() is dealing in seconds, we must account for
> -     *  this.
> -     */
> -
> -    ticks = the_timer->initial;
> -    ticks -= (the_timer->stop_time - the_timer->start_time);
> -    /* remaining is now in ticks */
> -
> -    _Timespec_From_ticks( ticks, &tp );
> -    remaining  = tp.tv_sec * TOD_MICROSECONDS_PER_SECOND;
> -    remaining += tp.tv_nsec / 1000;
> +  useconds_t        remaining;
> +  Watchdog_Control *the_watchdog;
> +  ISR_lock_Context  lock_context;
> +  ISR_lock_Context  lock_context2;
> +  Per_CPU_Control  *cpu;
> +  uint64_t          now;
> +  uint32_t          ticks_initial;
> +  uint32_t          ticks_interval;
> +
> +  the_watchdog = &_POSIX_signals_Ualarm_watchdog;
> +  ticks_initial = _POSIX_signals_Ualarm_us_to_ticks( useconds );
> +  ticks_interval = _POSIX_signals_Ualarm_us_to_ticks( interval );
> +
> +  _ISR_lock_ISR_disable_and_acquire(
> +    &_POSIX_signals_Ualarm_lock,
> +    &lock_context
> +  );
> +
> +  cpu = _Watchdog_Get_CPU( the_watchdog );
> +  _Watchdog_Per_CPU_acquire( cpu, &lock_context2 );
> +  now = cpu->Watchdog.ticks;
> +
> +  remaining = (useconds_t) _Watchdog_Cancel(
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +    the_watchdog,
> +    now
> +  );
> +
> +  if ( ticks_initial != 0 ) {
> +    _POSIX_signals_Ualarm_interval = ticks_interval;
> +
> +    cpu = _Per_CPU_Get();
> +    _Watchdog_Set_CPU( the_watchdog, cpu );
> +    _Watchdog_Insert(
> +      &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +      the_watchdog,
> +      now + ticks_initial
> +    );
>    }
>
> -  /*
> -   *  If useconds is non-zero, then the caller wants to schedule
> -   *  the alarm repeatedly at that interval.  If the interval is
> -   *  less than a single clock tick, then fudge it to a clock tick.
> -   */
> -  if ( useconds ) {
> -    Watchdog_Interval ticks;
> -
> -    tp.tv_sec = useconds / TOD_MICROSECONDS_PER_SECOND;
> -    tp.tv_nsec = (useconds % TOD_MICROSECONDS_PER_SECOND) * 1000;
> -    ticks = _Timespec_To_ticks( &tp );
> -    if ( ticks == 0 )
> -      ticks = 1;
> -
> -    _Watchdog_Insert_ticks( the_timer, _Timespec_To_ticks( &tp ) );
> -  }
> +  _Watchdog_Per_CPU_release( cpu, &lock_context2 );
> +  _ISR_lock_Release_and_ISR_enable(
> +    &_POSIX_signals_Ualarm_lock,
> +    &lock_context
> +  );
>
> -  _Thread_Enable_dispatch();
> +  remaining *= rtems_configuration_get_microseconds_per_tick();
>
>    return remaining;
>  }
> diff --git a/cpukit/rtems/include/rtems/rtems/ratemonimpl.h
> b/cpukit/rtems/include/rtems/rtems/ratemonimpl.h
> index 490912e..f184c44 100644
> --- a/cpukit/rtems/include/rtems/rtems/ratemonimpl.h
> +++ b/cpukit/rtems/include/rtems/rtems/ratemonimpl.h
> @@ -129,19 +129,13 @@ RTEMS_INLINE_ROUTINE bool _Rate_monotonic_Is_expired
> (
>  /**
>   * @brief Rate Monotonic Timeout
>   *
> - * This routine is invoked when the period represented
> - * by ID expires. If the thread which owns this period is blocked
> - * waiting for the period to expire, then it is readied and the
> - * period is restarted. If the owning thread is not waiting for the
> - * period to expire, then the period is placed in the EXPIRED
> - * state and not restarted.
> - *
> - * @param[in] id is the period id
> - */
> -void _Rate_monotonic_Timeout(
> -  rtems_id    id,
> -  void       *ignored
> -);
> + * This routine is invoked when the period represented by the watchdog
> expires.
> + * If the thread which owns this period is blocked waiting for the period
> to
> + * expire, then it is readied and the period is restarted. If the owning
> thread
> + * is not waiting for the period to expire, then the period is placed in
> the
> + * EXPIRED state and not restarted.
> + */
> +void _Rate_monotonic_Timeout( Watchdog_Control *watchdog );
>
>  /**
>   * @brief _Rate_monotonic_Get_status(
> @@ -165,7 +159,7 @@ bool _Rate_monotonic_Get_status(
>  );
>
>  /**
> - *  @brief Initiate Rate Monotonic Statistics
> + *  @brief Restart Rate Monotonic Period
>   *
>   *  This routine is invoked when a period is initiated via an explicit
>   *  call to rtems_rate_monotonic_period for the period's first iteration
> @@ -173,7 +167,7 @@ bool _Rate_monotonic_Get_status(
>   *
>   *  @param[in] the_period points to the period being operated upon.
>   */
> -void _Rate_monotonic_Initiate_statistics(
> +void _Rate_monotonic_Restart(
>    Rate_monotonic_Control *the_period
>  );
>
> diff --git a/cpukit/rtems/include/rtems/rtems/timer.h
> b/cpukit/rtems/include/rtems/rtems/timer.h
> index 7cc9051..032c495 100644
> --- a/cpukit/rtems/include/rtems/rtems/timer.h
> +++ b/cpukit/rtems/include/rtems/rtems/timer.h
> @@ -31,7 +31,7 @@
>   * COPYRIGHT (c) 1989-2011.
>   * On-Line Applications Research Corporation (OAR).
>   *
> - * Copyright (c) 2009 embedded brains GmbH.
> + * Copyright (c) 2009, 2016 embedded brains GmbH.
>   *
>   * The license and distribution terms for this file may be
>   * found in the file LICENSE in this distribution or at
> @@ -43,6 +43,7 @@
>
>  #include <rtems/rtems/attr.h>
>  #include <rtems/rtems/status.h>
> +#include <rtems/rtems/tasks.h>
>  #include <rtems/rtems/types.h>
>
>  #ifdef __cplusplus
> @@ -63,39 +64,49 @@ extern "C" {
>   */
>  /**@{*/
>
> +#define TIMER_CLASS_BIT_TIME_OF_DAY 0x1
> +
> +#define TIMER_CLASS_BIT_ON_TASK 0x2
> +
> +#define TIMER_CLASS_BIT_NOT_DORMANT 0x4
> +
>  /**
>   *  The following enumerated type details the classes to which a timer
>   *  may belong.
>   */
>  typedef enum {
>    /**
> +   * This value indicates the timer is currently not in use.
> +   */
> +  TIMER_DORMANT,
> +
> +  /**
>     * This value indicates the timer is currently in use as an interval
>     * timer which will fire in the clock tick ISR.
>     */
> -  TIMER_INTERVAL,
> +  TIMER_INTERVAL = TIMER_CLASS_BIT_NOT_DORMANT,
>
>    /**
>     * This value indicates the timer is currently in use as an interval
>     * timer which will fire in the timer server task.
>     */
> -  TIMER_INTERVAL_ON_TASK,
> +  TIMER_INTERVAL_ON_TASK =
> +    TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_ON_TASK,
>
>    /**
>     * This value indicates the timer is currently in use as an time of day
>     * timer which will fire in the clock tick ISR.
>     */
> -  TIMER_TIME_OF_DAY,
> +  TIMER_TIME_OF_DAY =
> +    TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY,
>
>    /**
>     * This value indicates the timer is currently in use as an time of day
>     * timer which will fire in the timer server task.
>     */
> -  TIMER_TIME_OF_DAY_ON_TASK,
> -
> -  /**
> -   * This value indicates the timer is currently not in use.
> -   */
> -  TIMER_DORMANT
> +  TIMER_TIME_OF_DAY_ON_TASK =
> +    TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY |
> +    TIMER_CLASS_BIT_ON_TASK
>  } Timer_Classes;
>
>  /**
> @@ -124,6 +135,16 @@ typedef struct {
>    Watchdog_Control Ticker;
>    /** This field indicates what type of timer this currently is. */
>    Timer_Classes    the_class;
> +  /** This field is the timer service routine. */
> +  rtems_timer_service_routine_entry routine;
> +  /** This field is the timer service routine user data. */
> +  void *user_data;
> +  /** This field is the timer interval in ticks or seconds. */
> +  Watchdog_Interval initial;
> +  /** This field is the timer start time point in ticks. */
> +  Watchdog_Interval start_time;
> +  /** This field is the timer stop time point in ticks. */
> +  Watchdog_Interval stop_time;
>  }   Timer_Control;
>
>  /**
> @@ -296,16 +317,22 @@ rtems_status_code rtems_timer_reset(
>  );
>
>  /**
> - *  @brief rtems_timer_initiate_server
> + *  @brief Initiates the timer server.
>   *
> - *  This routine implements the rtems_timer_initiate_server directive.
> - *  It creates and starts the server that executes task-based timers.
> + *  This directive creates and starts the server for task-based timers.
>   *  It must be invoked before any task-based timers can be initiated.
> + *
> + *  @param priority The timer server task priority.
> + *  @param stack_size The stack size in bytes for the timer server task.
> + *  @param attribute_set The timer server task attributes.
> + *
> + *  @return This method returns RTEMS_SUCCESSFUL if successful and an
> + *          error code otherwise.
>   */
>  rtems_status_code rtems_timer_initiate_server(
> -  uint32_t             priority,
> -  uint32_t             stack_size,
> -  rtems_attribute      attribute_set
> +  rtems_task_priority priority,
> +  size_t              stack_size,
> +  rtems_attribute     attribute_set
>  );
>
>  /**
> diff --git a/cpukit/rtems/include/rtems/rtems/timerimpl.h
> b/cpukit/rtems/include/rtems/rtems/timerimpl.h
> index 55be634..59ba09b 100644
> --- a/cpukit/rtems/include/rtems/rtems/timerimpl.h
> +++ b/cpukit/rtems/include/rtems/rtems/timerimpl.h
> @@ -10,6 +10,8 @@
>   * COPYRIGHT (c) 1989-2011.
>   * On-Line Applications Research Corporation (OAR).
>   *
> + * Copyright (c) 2016 embedded brains GmbH.
> + *
>   * 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.
> @@ -35,81 +37,13 @@ extern "C" {
>   * @{
>   */
>
> -typedef struct Timer_server_Control Timer_server_Control;
> +typedef struct Timer_server_Control {
> +  ISR_LOCK_MEMBER( Lock )
>
> -/**
> - * @brief Method used for task based timers.
> - */
> -typedef void (*Timer_server_Method)(
> -  Timer_server_Control *timer_server,
> -  Timer_Control        *timer
> -);
> +  Chain_Control Pending;
>
> -typedef struct {
> -  /**
> -   * @brief This watchdog that will be registered in the system tick
> mechanic
> -   * for timer server wake-up.
> -   */
> -  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 time snapshot of the timer server.
> -   *
> -   * The units may be ticks or seconds.
> -   */
> -  Watchdog_Interval last_snapshot;
> -
> -  /**
> -   * @brief Current time snapshot of the timer server.
> -   *
> -   * The units may be ticks or seconds.
> -   */
> -  Watchdog_Interval current_snapshot;
> -} Timer_server_Watchdogs;
> -
> -struct Timer_server_Control {
> -  /**
> -   * @brief The cancel method of the timer server.
> -   */
> -  Timer_server_Method cancel;
> -
> -  /**
> -   * @brief The schedule operation method of the timer server.
> -   */
> -  Timer_server_Method schedule_operation;
> -
> -  /**
> -   * @brief Interval watchdogs triggered by the timer server.
> -   */
> -  Timer_server_Watchdogs Interval_watchdogs;
> -
> -  /**
> -   * @brief TOD watchdogs triggered by the timer server.
> -   */
> -  Timer_server_Watchdogs TOD_watchdogs;
> -};
> +  Objects_Id server_id;
> +} Timer_server_Control;
>
>  /**
>   * @brief Pointer to default timer server control block.
> @@ -148,64 +82,124 @@ RTEMS_INLINE_ROUTINE void _Timer_Free (
>    _Objects_Free( &_Timer_Information, &the_timer->Object );
>  }
>
> -/**
> - *  @brief Timer_Get
> - *
> - *  This function maps timer IDs to timer control blocks.
> - *  If ID corresponds to a local timer, then it returns
> - *  the timer control pointer which maps to ID and location
> - *  is set to OBJECTS_LOCAL.  Otherwise, location is set
> - *  to OBJECTS_ERROR and the returned value is undefined.
> - */
> -RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Get (
> +RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Get(
>    Objects_Id         id,
> -  Objects_Locations *location
> +  Objects_Locations *location,
> +  ISR_lock_Context  *lock_context
>  )
>  {
> -  return (Timer_Control *)
> -    _Objects_Get( &_Timer_Information, id, location );
> +  return (Timer_Control *) _Objects_Get_isr_disable(
> +    &_Timer_Information,
> +    id,
> +    location,
> +    lock_context
> +  );
>  }
>
> -/**
> - *  @brief Timer_Is_interval_class
> - *
> - *  This function returns TRUE if the class is that of an INTERVAL
> - *  timer, and FALSE otherwise.
> - */
> -RTEMS_INLINE_ROUTINE bool _Timer_Is_interval_class (
> +RTEMS_INLINE_ROUTINE Per_CPU_Control *_Timer_Acquire_critical(
> +  Timer_Control    *the_timer,
> +  ISR_lock_Context *lock_context
> +)
> +{
> +  Per_CPU_Control *cpu;
> +
> +  cpu = _Watchdog_Get_CPU( &the_timer->Ticker );
> +  _Watchdog_Per_CPU_acquire( cpu, lock_context );
> +
> +  return cpu;
> +}
> +
> +RTEMS_INLINE_ROUTINE void _Timer_Release(
> +  Per_CPU_Control  *cpu,
> +  ISR_lock_Context *lock_context
> +)
> +{
> +  _Watchdog_Per_CPU_release( cpu, lock_context );
> +  _ISR_lock_ISR_enable( lock_context );
> +}
> +
> +RTEMS_INLINE_ROUTINE bool _Timer_Is_interval_class(
>    Timer_Classes the_class
>  )
>  {
> -  return (the_class == TIMER_INTERVAL) || (the_class ==
> TIMER_INTERVAL_ON_TASK);
> +  Timer_Classes mask =
> +    TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY;
> +
> +  return ( the_class & mask ) == TIMER_CLASS_BIT_NOT_DORMANT;
>  }
>
> -/**
> - *  @brief Timer_Is_time_of_day_class
> - *
> - *  This function returns TRUE if the class is that of an INTERVAL
> - *  timer, and FALSE otherwise.
> - */
> -RTEMS_INLINE_ROUTINE bool _Timer_Is_timer_of_day_class (
> +RTEMS_INLINE_ROUTINE bool _Timer_Is_on_task_class(
>    Timer_Classes the_class
>  )
>  {
> -  return ( the_class == TIMER_TIME_OF_DAY );
> +  Timer_Classes mask =
> +    TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_ON_TASK;
> +
> +  return ( the_class & mask ) == mask;
>  }
>
> -/**
> - *  @brief Timer_Is_dormant_class
> - *
> - *  This function returns TRUE if the class is that of a DORMANT
> - *  timer, and FALSE otherwise.
> - */
> -RTEMS_INLINE_ROUTINE bool _Timer_Is_dormant_class (
> +RTEMS_INLINE_ROUTINE Per_CPU_Watchdog_index _Timer_Watchdog_header_index(
>    Timer_Classes the_class
>  )
>  {
> -  return ( the_class == TIMER_DORMANT );
> +  return ( the_class & TIMER_CLASS_BIT_TIME_OF_DAY );
> +}
> +
> +RTEMS_INLINE_ROUTINE Watchdog_Interval _Timer_Get_CPU_ticks(
> +  const Per_CPU_Control *cpu
> +)
> +{
> +  return (Watchdog_Interval) cpu->Watchdog.ticks;
>  }
>
> -void _Timer_Cancel( Timer_Control *the_timer );
> +rtems_status_code _Timer_Fire(
> +  rtems_id                           id,
> +  rtems_interval                     interval,
> +  rtems_timer_service_routine_entry  routine,
> +  void                              *user_data,
> +  Timer_Classes                      the_class,
> +  Watchdog_Service_routine_entry     adaptor
> +);
> +
> +rtems_status_code _Timer_Fire_after(
> +  rtems_id                           id,
> +  rtems_interval                     ticks,
> +  rtems_timer_service_routine_entry  routine,
> +  void                              *user_data,
> +  Timer_Classes                      the_class,
> +  Watchdog_Service_routine_entry     adaptor
> +);
> +
> +rtems_status_code _Timer_Fire_when(
> +  rtems_id                           id,
> +  const rtems_time_of_day           *wall_time,
> +  rtems_timer_service_routine_entry  routine,
> +  void                              *user_data,
> +  Timer_Classes                      the_class,
> +  Watchdog_Service_routine_entry     adaptor
> +);
> +
> +void _Timer_Cancel( Per_CPU_Control *cpu, Timer_Control *the_timer );
> +
> +void _Timer_Routine_adaptor( Watchdog_Control *the_watchdog );
> +
> +void _Timer_server_Routine_adaptor( Watchdog_Control *the_watchdog );
> +
> +RTEMS_INLINE_ROUTINE void _Timer_server_Acquire_critical(
> +  Timer_server_Control *timer_server,
> +  ISR_lock_Context     *lock_context
> +)
> +{
> +  _ISR_lock_Acquire( &timer_server->Lock, lock_context );
> +}
> +
> +RTEMS_INLINE_ROUTINE void _Timer_server_Release_critical(
> +  Timer_server_Control *timer_server,
> +  ISR_lock_Context     *lock_context
> +)
> +{
> +  _ISR_lock_Release( &timer_server->Lock, lock_context );
> +}
>
>  /**@}*/
>
> diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c
> index 3dc554f..0be6bd6 100644
> --- a/cpukit/rtems/src/eventseize.c
> +++ b/cpukit/rtems/src/eventseize.c
> @@ -90,13 +90,12 @@ void _Event_Seize(
>
>    if ( ticks ) {
>      _Thread_Wait_set_timeout_code( executing, RTEMS_TIMEOUT );
> -    _Watchdog_Initialize(
> -      &executing->Timer,
> +    _Thread_Timer_insert_relative(
> +      executing,
> +      cpu_self,
>        _Thread_Timeout,
> -      0,
> -      executing
> +      ticks
>      );
> -    _Watchdog_Insert_ticks( &executing->Timer, ticks );
>    }
>
>    _Thread_Set_state( executing, block_state );
> @@ -113,7 +112,7 @@ void _Event_Seize(
>      wait_class | THREAD_WAIT_STATE_BLOCKED
>    );
>    if ( !success ) {
> -    _Watchdog_Remove_ticks( &executing->Timer );
> +    _Thread_Timer_remove( executing );
>      _Thread_Unblock( executing );
>    }
>
> diff --git a/cpukit/rtems/src/eventsurrender.c
> b/cpukit/rtems/src/eventsurrender.c
> index 5726cc8..7c4fe2e 100644
> --- a/cpukit/rtems/src/eventsurrender.c
> +++ b/cpukit/rtems/src/eventsurrender.c
> @@ -121,7 +121,7 @@ void _Event_Surrender(
>      cpu_self = _Thread_Dispatch_disable_critical( lock_context );
>      _Thread_Lock_release_default( the_thread, lock_context );
>
> -    _Watchdog_Remove_ticks( &the_thread->Timer );
> +    _Thread_Timer_remove( the_thread );
>      _Thread_Unblock( the_thread );
>
>      _Thread_Dispatch_enable( cpu_self );
> diff --git a/cpukit/rtems/src/ratemoncancel.c
> b/cpukit/rtems/src/ratemoncancel.c
> index 67b230f..2e4d532 100644
> --- a/cpukit/rtems/src/ratemoncancel.c
> +++ b/cpukit/rtems/src/ratemoncancel.c
> @@ -29,6 +29,7 @@ rtems_status_code rtems_rate_monotonic_cancel(
>  {
>    Rate_monotonic_Control *the_period;
>    Objects_Locations       location;
> +  ISR_Level               level;
>
>    the_period = _Rate_monotonic_Get( id, &location );
>    switch ( location ) {
> @@ -38,7 +39,9 @@ rtems_status_code rtems_rate_monotonic_cancel(
>          _Objects_Put( &the_period->Object );
>          return RTEMS_NOT_OWNER_OF_RESOURCE;
>        }
> -      _Watchdog_Remove_ticks( &the_period->Timer );
> +      _ISR_Disable( level );
> +      _Watchdog_Per_CPU_remove_relative( &the_period->Timer );
> +      _ISR_Enable( level );
>        the_period->state = RATE_MONOTONIC_INACTIVE;
>        _Scheduler_Release_job( the_period->owner, 0 );
>        _Objects_Put( &the_period->Object );
> diff --git a/cpukit/rtems/src/ratemoncreate.c
> b/cpukit/rtems/src/ratemoncreate.c
> index 1ac4a36..1a5c9b2 100644
> --- a/cpukit/rtems/src/ratemoncreate.c
> +++ b/cpukit/rtems/src/ratemoncreate.c
> @@ -65,7 +65,8 @@ rtems_status_code rtems_rate_monotonic_create(
>    the_period->owner = _Thread_Get_executing();
>    the_period->state = RATE_MONOTONIC_INACTIVE;
>
> -  _Watchdog_Preinitialize( &the_period->Timer );
> +  _Watchdog_Preinitialize( &the_period->Timer, _Per_CPU_Get_by_index( 0 )
> );
> +  _Watchdog_Initialize( &the_period->Timer, _Rate_monotonic_Timeout );
>
>    _Rate_monotonic_Reset_statistics( the_period );
>
> diff --git a/cpukit/rtems/src/ratemondelete.c
> b/cpukit/rtems/src/ratemondelete.c
> index 77cf3fe..09b9ab6 100644
> --- a/cpukit/rtems/src/ratemondelete.c
> +++ b/cpukit/rtems/src/ratemondelete.c
> @@ -29,6 +29,7 @@ rtems_status_code rtems_rate_monotonic_delete(
>  {
>    Rate_monotonic_Control *the_period;
>    Objects_Locations       location;
> +  ISR_Level               level;
>
>    _Objects_Allocator_lock();
>    the_period = _Rate_monotonic_Get( id, &location );
> @@ -37,7 +38,9 @@ rtems_status_code rtems_rate_monotonic_delete(
>      case OBJECTS_LOCAL:
>        _Scheduler_Release_job( the_period->owner, 0 );
>        _Objects_Close( &_Rate_monotonic_Information, &the_period->Object );
> -      _Watchdog_Remove_ticks( &the_period->Timer );
> +      _ISR_Disable( level );
> +      _Watchdog_Per_CPU_remove_relative( &the_period->Timer );
> +      _ISR_Enable( level );
>        the_period->state = RATE_MONOTONIC_INACTIVE;
>        _Objects_Put( &the_period->Object );
>        _Rate_monotonic_Free( the_period );
> diff --git a/cpukit/rtems/src/ratemonperiod.c
> b/cpukit/rtems/src/ratemonperiod.c
> index 6afe101..58be148 100644
> --- a/cpukit/rtems/src/ratemonperiod.c
> +++ b/cpukit/rtems/src/ratemonperiod.c
> @@ -77,12 +77,11 @@ bool _Rate_monotonic_Get_status(
>    return true;
>  }
>
> -void _Rate_monotonic_Initiate_statistics(
> -  Rate_monotonic_Control *the_period
> -)
> +void _Rate_monotonic_Restart( Rate_monotonic_Control *the_period )
>  {
>    Thread_Control    *owning_thread = the_period->owner;
>    Timestamp_Control  uptime;
> +  ISR_Level          level;
>
>    _TOD_Get_uptime( &uptime );
>
> @@ -113,7 +112,15 @@ void _Rate_monotonic_Initiate_statistics(
>      _Timestamp_Add_to( &the_period->cpu_usage_period_initiated, &ran );
>    }
>
> -  _Scheduler_Release_job( the_period->owner, the_period->next_length );
> +  _Scheduler_Release_job( owning_thread, the_period->next_length );
> +
> +  _ISR_Disable( level );
> +  _Watchdog_Per_CPU_insert_relative(
> +    &the_period->Timer,
> +    _Per_CPU_Get(),
> +    the_period->next_length
> +  );
> +  _ISR_Enable( level );
>  }
>
>  static void _Rate_monotonic_Update_statistics(
> @@ -238,22 +245,9 @@ rtems_status_code rtems_rate_monotonic_period(
>        if ( the_period->state == RATE_MONOTONIC_INACTIVE ) {
>          _ISR_Enable( level );
>
> -        the_period->next_length = length;
> -
> -        /*
> -         *  Baseline statistics information for the beginning of a period.
> -         */
> -        _Rate_monotonic_Initiate_statistics( the_period );
> -
>          the_period->state = RATE_MONOTONIC_ACTIVE;
> -        _Watchdog_Initialize(
> -          &the_period->Timer,
> -          _Rate_monotonic_Timeout,
> -          id,
> -          NULL
> -        );
> -
> -        _Watchdog_Insert_ticks( &the_period->Timer, length );
> +        the_period->next_length = length;
> +        _Rate_monotonic_Restart( the_period );
>          _Objects_Put( &the_period->Object );
>          return RTEMS_SUCCESSFUL;
>        }
> @@ -308,7 +302,11 @@ rtems_status_code rtems_rate_monotonic_period(
>          the_period->state = RATE_MONOTONIC_ACTIVE;
>          the_period->next_length = length;
>
> -        _Watchdog_Insert_ticks( &the_period->Timer, length );
> +        _Watchdog_Per_CPU_insert_relative(
> +          &the_period->Timer,
> +          _Per_CPU_Get(),
> +          length
> +        );
>          _Scheduler_Release_job( the_period->owner,
> the_period->next_length );
>          _Objects_Put( &the_period->Object );
>          return RTEMS_TIMEOUT;
> diff --git a/cpukit/rtems/src/ratemontimeout.c
> b/cpukit/rtems/src/ratemontimeout.c
> index 08f9bd1..7c25595 100644
> --- a/cpukit/rtems/src/ratemontimeout.c
> +++ b/cpukit/rtems/src/ratemontimeout.c
> @@ -22,46 +22,30 @@
>  #include <rtems/score/threadimpl.h>
>  #include <rtems/score/watchdogimpl.h>
>
> -void _Rate_monotonic_Timeout(
> -  Objects_Id  id,
> -  void       *ignored
> -)
> +void _Rate_monotonic_Timeout( Watchdog_Control *watchdog )
>  {
>    Rate_monotonic_Control *the_period;
> -  Objects_Locations       location;
>    Thread_Control         *the_thread;
>
>    /*
>     *  When we get here, the Timer is already off the chain so we do not
>     *  have to worry about that -- hence no _Watchdog_Remove().
>     */
> -  the_period = _Rate_monotonic_Get( id, &location );
> -  switch ( location ) {
> -
> -    case OBJECTS_LOCAL:
> -      the_thread = the_period->owner;
> -      if ( _States_Is_waiting_for_period( the_thread->current_state ) &&
> -            the_thread->Wait.id == the_period->Object.id ) {
> -        _Thread_Unblock( the_thread );
> -
> -        _Rate_monotonic_Initiate_statistics( the_period );
> -
> -        _Watchdog_Insert_ticks( &the_period->Timer,
> the_period->next_length );
> -      } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING )
> {
> -        the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING;
> -
> -        _Rate_monotonic_Initiate_statistics( the_period );
> -
> -        _Watchdog_Insert_ticks( &the_period->Timer,
> the_period->next_length );
> -      } else
> -        the_period->state = RATE_MONOTONIC_EXPIRED;
> -      _Objects_Put_without_thread_dispatch( &the_period->Object );
> -      break;
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -    case OBJECTS_REMOTE:  /* impossible */
> -#endif
> -    case OBJECTS_ERROR:
> -      break;
> +  the_period = RTEMS_CONTAINER_OF( watchdog, Rate_monotonic_Control,
> Timer );
> +  the_thread = the_period->owner;
> +
> +  _Thread_Disable_dispatch();
> +
> +  if ( _States_Is_waiting_for_period( the_thread->current_state ) &&
> +        the_thread->Wait.id == the_period->Object.id ) {
> +    _Thread_Unblock( the_thread );
> +    _Rate_monotonic_Restart( the_period );
> +  } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) {
> +    the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING;
> +    _Rate_monotonic_Restart( the_period );
> +  } else {
> +    the_period->state = RATE_MONOTONIC_EXPIRED;
>    }
> +
> +  _Thread_Unnest_dispatch();
>  }
> diff --git a/cpukit/rtems/src/taskwakeafter.c
> b/cpukit/rtems/src/taskwakeafter.c
> index b7f328f..fa5f6f4 100644
> --- a/cpukit/rtems/src/taskwakeafter.c
> +++ b/cpukit/rtems/src/taskwakeafter.c
> @@ -41,13 +41,12 @@ rtems_status_code rtems_task_wake_after(
>      } else {
>        _Thread_Set_state( executing, STATES_DELAYING );
>        _Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED );
> -      _Watchdog_Initialize(
> -        &executing->Timer,
> +      _Thread_Timer_insert_relative(
> +        executing,
> +        cpu_self,
>          _Thread_Timeout,
> -        0,
> -        executing
> +        ticks
>        );
> -      _Watchdog_Insert_ticks( &executing->Timer, ticks );
>      }
>    _Thread_Dispatch_enable( cpu_self );
>    return RTEMS_SUCCESSFUL;
> diff --git a/cpukit/rtems/src/taskwakewhen.c
> b/cpukit/rtems/src/taskwakewhen.c
> index cf0b303..5d6d45a 100644
> --- a/cpukit/rtems/src/taskwakewhen.c
> +++ b/cpukit/rtems/src/taskwakewhen.c
> @@ -28,9 +28,9 @@ rtems_status_code rtems_task_wake_when(
>    rtems_time_of_day *time_buffer
>  )
>  {
> -  Watchdog_Interval   seconds;
> -  Thread_Control     *executing;
> -  Per_CPU_Control    *cpu_self;
> +  uint32_t         seconds;
> +  Thread_Control  *executing;
> +  Per_CPU_Control *cpu_self;
>
>    if ( !_TOD_Is_set() )
>      return RTEMS_NOT_DEFINED;
> @@ -52,15 +52,11 @@ rtems_status_code rtems_task_wake_when(
>      executing = _Thread_Executing;
>      _Thread_Set_state( executing, STATES_WAITING_FOR_TIME );
>      _Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED );
> -    _Watchdog_Initialize(
> -      &executing->Timer,
> +    _Thread_Timer_insert_absolute(
> +      executing,
> +      cpu_self,
>        _Thread_Timeout,
> -      0,
> -      executing
> -    );
> -    _Watchdog_Insert_seconds(
> -      &executing->Timer,
> -      seconds - _TOD_Seconds_since_epoch()
> +      _Watchdog_Ticks_from_seconds( seconds )
>      );
>    _Thread_Dispatch_enable( cpu_self );
>    return RTEMS_SUCCESSFUL;
> diff --git a/cpukit/rtems/src/timercancel.c
> b/cpukit/rtems/src/timercancel.c
> index 1e737a2..5d4343e 100644
> --- a/cpukit/rtems/src/timercancel.c
> +++ b/cpukit/rtems/src/timercancel.c
> @@ -14,39 +14,24 @@
>  #include "config.h"
>  #endif
>
> -#include <rtems/system.h>
> -#include <rtems/rtems/status.h>
> -#include <rtems/rtems/support.h>
> -#include <rtems/score/thread.h>
>  #include <rtems/rtems/timerimpl.h>
> -#include <rtems/score/watchdogimpl.h>
> -
> -/*
> - *  rtems_timer_cancel
> - *
> - *  This directive allows a thread to cancel a timer.
> - *
> - *  Input parameters:
> - *    id - timer id
> - *
> - *  Output parameters:
> - *    RTEMS_SUCCESSFUL - if successful
> - *    error code       - if unsuccessful
> - */
>
>  rtems_status_code rtems_timer_cancel(
>    rtems_id id
>  )
>  {
> -  Timer_Control   *the_timer;
> -  Objects_Locations       location;
> +  Timer_Control     *the_timer;
> +  Objects_Locations  location;
> +  ISR_lock_Context   lock_context;
> +  Per_CPU_Control   *cpu;
>
> -  the_timer = _Timer_Get( id, &location );
> +  the_timer = _Timer_Get( id, &location, &lock_context );
>    switch ( location ) {
>
>      case OBJECTS_LOCAL:
> -      _Timer_Cancel( the_timer );
> -      _Objects_Put( &the_timer->Object );
> +      cpu = _Timer_Acquire_critical( the_timer, &lock_context );
> +      _Timer_Cancel( cpu, the_timer );
> +      _Timer_Release( cpu, &lock_context );
>        return RTEMS_SUCCESSFUL;
>
>  #if defined(RTEMS_MULTIPROCESSING)
> diff --git a/cpukit/rtems/src/timercreate.c
> b/cpukit/rtems/src/timercreate.c
> index 5c718b9..80c1356 100644
> --- a/cpukit/rtems/src/timercreate.c
> +++ b/cpukit/rtems/src/timercreate.c
> @@ -18,40 +18,173 @@
>  #include "config.h"
>  #endif
>
> -#include <rtems/system.h>
> +#include <rtems/rtems/timerimpl.h>
> +#include <rtems/rtems/clock.h>
>  #include <rtems/rtems/status.h>
>  #include <rtems/rtems/support.h>
>  #include <rtems/score/assert.h>
> +#include <rtems/score/chainimpl.h>
>  #include <rtems/score/thread.h>
> -#include <rtems/rtems/timerimpl.h>
> +#include <rtems/score/todimpl.h>
>  #include <rtems/score/watchdogimpl.h>
>
> -void _Timer_Cancel( Timer_Control *the_timer )
> +RTEMS_STATIC_ASSERT(
> +  PER_CPU_WATCHDOG_ABSOLUTE == TIMER_CLASS_BIT_TIME_OF_DAY,
> +  TIMER_CLASS_BIT_TIME_OF_DAY
> +);
> +
> +void _Timer_Routine_adaptor( Watchdog_Control *the_watchdog )
>  {
> -  Timer_server_Control *timer_server;
> -  ISR_Level level;
> +  Timer_Control   *the_timer;
> +  Per_CPU_Control *cpu;
>
> -  /* The timer class must not change during the cancel operation */
> -  _ISR_Disable( level );
> +  the_timer = RTEMS_CONTAINER_OF( the_watchdog, Timer_Control, Ticker );
> +  cpu = _Watchdog_Get_CPU( &the_timer->Ticker );
> +  the_timer->stop_time = _Timer_Get_CPU_ticks( cpu );
>
> -  switch ( the_timer->the_class ) {
> -    case TIMER_INTERVAL:
> -      _Watchdog_Remove_ticks( &the_timer->Ticker );
> -      break;
> -    case TIMER_TIME_OF_DAY:
> -      _Watchdog_Remove_seconds( &the_timer->Ticker );
> -      break;
> -    case TIMER_INTERVAL_ON_TASK:
> -    case TIMER_TIME_OF_DAY_ON_TASK:
> -      timer_server = _Timer_server;
> -      (*timer_server->cancel)( timer_server, the_timer );
> -      break;
> -    default:
> -      _Assert( the_timer->the_class == TIMER_DORMANT );
> +  ( *the_timer->routine )( the_timer->Object.id, the_timer->user_data );
> +}
> +
> +rtems_status_code _Timer_Fire(
> +  rtems_id                           id,
> +  rtems_interval                     interval,
> +  rtems_timer_service_routine_entry  routine,
> +  void                              *user_data,
> +  Timer_Classes                      the_class,
> +  Watchdog_Service_routine_entry     adaptor
> +)
> +{
> +  Timer_Control        *the_timer;
> +  Objects_Locations     location;
> +  ISR_lock_Context      lock_context;
> +  Per_CPU_Control      *cpu;
> +
> +  the_timer = _Timer_Get( id, &location, &lock_context );
> +  switch ( location ) {
> +
> +    case OBJECTS_LOCAL:
> +      cpu = _Timer_Acquire_critical( the_timer, &lock_context );
> +      _Timer_Cancel( cpu, the_timer );
> +      _Watchdog_Initialize( &the_timer->Ticker, adaptor );
> +      the_timer->the_class = the_class;
> +      the_timer->routine = routine;
> +      the_timer->user_data = user_data;
> +      the_timer->initial = interval;
> +      the_timer->start_time = _Timer_Get_CPU_ticks( cpu );
> +
> +      if ( _Timer_Is_interval_class( the_class ) ) {
> +        _Watchdog_Insert(
> +          &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +          &the_timer->Ticker,
> +          cpu->Watchdog.ticks + interval
> +        );
> +      } else {
> +        _Watchdog_Insert(
> +          &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_ABSOLUTE ],
> +          &the_timer->Ticker,
> +          _Watchdog_Ticks_from_seconds( interval )
> +        );
> +      }
> +
> +      _Timer_Release( cpu, &lock_context );
> +      return RTEMS_SUCCESSFUL;
> +
> +#if defined(RTEMS_MULTIPROCESSING)
> +    case OBJECTS_REMOTE:            /* should never return this */
> +#endif
> +    case OBJECTS_ERROR:
>        break;
>    }
>
> -  _ISR_Enable( level );
> +  return RTEMS_INVALID_ID;
> +}
> +
> +rtems_status_code _Timer_Fire_after(
> +  rtems_id                           id,
> +  rtems_interval                     ticks,
> +  rtems_timer_service_routine_entry  routine,
> +  void                              *user_data,
> +  Timer_Classes                      the_class,
> +  Watchdog_Service_routine_entry     adaptor
> +)
> +{
> +  if ( ticks == 0 )
> +    return RTEMS_INVALID_NUMBER;
> +
> +  if ( !routine )
> +    return RTEMS_INVALID_ADDRESS;
> +
> +  return _Timer_Fire(
> +    id,
> +    ticks,
> +    routine,
> +    user_data,
> +    the_class,
> +    adaptor
> +  );
> +}
> +
> +rtems_status_code _Timer_Fire_when(
> +  rtems_id                           id,
> +  const rtems_time_of_day           *wall_time,
> +  rtems_timer_service_routine_entry  routine,
> +  void                              *user_data,
> +  Timer_Classes                      the_class,
> +  Watchdog_Service_routine_entry     adaptor
> +)
> +{
> +  rtems_interval seconds;
> +
> +  if ( !_TOD_Is_set() )
> +    return RTEMS_NOT_DEFINED;
> +
> +  if ( !routine )
> +    return RTEMS_INVALID_ADDRESS;
> +
> +  if ( !_TOD_Validate( wall_time ) )
> +    return RTEMS_INVALID_CLOCK;
> +
> +  seconds = _TOD_To_seconds( wall_time );
> +  if ( seconds <= _TOD_Seconds_since_epoch() )
> +    return RTEMS_INVALID_CLOCK;
> +
> +  return _Timer_Fire(
> +    id,
> +    seconds,
> +    routine,
> +    user_data,
> +    the_class,
> +    adaptor
> +  );
> +}
> +
> +void _Timer_Cancel( Per_CPU_Control *cpu, Timer_Control *the_timer )
> +{
> +  Timer_Classes the_class;
> +
> +  the_class = the_timer->the_class;
> +
> +  if ( _Watchdog_Is_scheduled( &the_timer->Ticker ) ) {
> +    the_timer->stop_time = _Timer_Get_CPU_ticks( cpu );
> +    _Watchdog_Remove(
> +      &cpu->Watchdog.Header[ _Timer_Watchdog_header_index( the_class ) ],
> +      &the_timer->Ticker
> +    );
> +  } else if ( _Timer_Is_on_task_class( the_class ) ) {
> +    Timer_server_Control *timer_server;
> +    ISR_lock_Context      lock_context;
> +
> +    timer_server = _Timer_server;
> +    _Assert( timer_server != NULL );
> +    _Timer_server_Acquire_critical( timer_server, &lock_context );
> +
> +    if ( _Watchdog_Get_state( &the_timer->Ticker ) == WATCHDOG_PENDING ) {
> +      _Watchdog_Set_state( &the_timer->Ticker, WATCHDOG_INACTIVE );
> +      _Chain_Extract_unprotected( &the_timer->Ticker.Node.Chain );
> +    }
> +
> +    _Timer_server_Release_critical( timer_server, &lock_context );
> +  }
>  }
>
>  rtems_status_code rtems_timer_create(
> @@ -75,7 +208,7 @@ rtems_status_code rtems_timer_create(
>    }
>
>    the_timer->the_class = TIMER_DORMANT;
> -  _Watchdog_Preinitialize( &the_timer->Ticker );
> +  _Watchdog_Preinitialize( &the_timer->Ticker, _Per_CPU_Get_snapshot() );
>
>    _Objects_Open(
>      &_Timer_Information,
> diff --git a/cpukit/rtems/src/timerdelete.c
> b/cpukit/rtems/src/timerdelete.c
> index 0849ec5..9c41397 100644
> --- a/cpukit/rtems/src/timerdelete.c
> +++ b/cpukit/rtems/src/timerdelete.c
> @@ -18,12 +18,7 @@
>  #include "config.h"
>  #endif
>
> -#include <rtems/system.h>
> -#include <rtems/rtems/status.h>
> -#include <rtems/rtems/support.h>
> -#include <rtems/score/thread.h>
>  #include <rtems/rtems/timerimpl.h>
> -#include <rtems/score/watchdogimpl.h>
>
>  rtems_status_code rtems_timer_delete(
>    rtems_id id
> @@ -31,15 +26,18 @@ rtems_status_code rtems_timer_delete(
>  {
>    Timer_Control     *the_timer;
>    Objects_Locations  location;
> +  ISR_lock_Context   lock_context;
> +  Per_CPU_Control   *cpu;
>
>    _Objects_Allocator_lock();
> -  the_timer = _Timer_Get( id, &location );
> +  the_timer = _Timer_Get( id, &location, &lock_context );
>    switch ( location ) {
>
>      case OBJECTS_LOCAL:
>        _Objects_Close( &_Timer_Information, &the_timer->Object );
> -      _Timer_Cancel( the_timer );
> -      _Objects_Put( &the_timer->Object );
> +      cpu = _Timer_Acquire_critical( the_timer, &lock_context );
> +      _Timer_Cancel( cpu, the_timer );
> +      _Timer_Release( cpu, &lock_context );
>        _Timer_Free( the_timer );
>        _Objects_Allocator_unlock();
>        return RTEMS_SUCCESSFUL;
> diff --git a/cpukit/rtems/src/timerfireafter.c
> b/cpukit/rtems/src/timerfireafter.c
> index 84cf46b..82bd878 100644
> --- a/cpukit/rtems/src/timerfireafter.c
> +++ b/cpukit/rtems/src/timerfireafter.c
> @@ -18,12 +18,7 @@
>  #include "config.h"
>  #endif
>
> -#include <rtems/system.h>
> -#include <rtems/rtems/status.h>
> -#include <rtems/rtems/support.h>
> -#include <rtems/score/thread.h>
>  #include <rtems/rtems/timerimpl.h>
> -#include <rtems/score/watchdogimpl.h>
>
>  rtems_status_code rtems_timer_fire_after(
>    rtems_id                           id,
> @@ -32,55 +27,12 @@ rtems_status_code rtems_timer_fire_after(
>    void                              *user_data
>  )
>  {
> -  Timer_Control      *the_timer;
> -  Objects_Locations   location;
> -  ISR_Level           level;
> -
> -  if ( ticks == 0 )
> -    return RTEMS_INVALID_NUMBER;
> -
> -  if ( !routine )
> -    return RTEMS_INVALID_ADDRESS;
> -
> -  the_timer = _Timer_Get( id, &location );
> -  switch ( location ) {
> -
> -    case OBJECTS_LOCAL:
> -      _Timer_Cancel( the_timer );
> -
> -      _ISR_Disable( level );
> -
> -        /*
> -         *  Check to see if the watchdog has just been inserted by a
> -         *  higher priority interrupt.  If so, abandon this insert.
> -         */
> -
> -        if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) {
> -          _ISR_Enable( level );
> -          _Objects_Put( &the_timer->Object );
> -          return RTEMS_SUCCESSFUL;
> -        }
> -
> -        /*
> -         *  OK.  Now we now the timer was not rescheduled by an interrupt
> -         *  so we can atomically initialize it as in use.
> -         */
> -
> -        the_timer->the_class = TIMER_INTERVAL;
> -        _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data
> );
> -      _ISR_Enable( level );
> -
> -
> -      _Watchdog_Insert_ticks( &the_timer->Ticker, ticks );
> -      _Objects_Put( &the_timer->Object );
> -      return RTEMS_SUCCESSFUL;
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -    case OBJECTS_REMOTE:            /* should never return this */
> -#endif
> -    case OBJECTS_ERROR:
> -      break;
> -  }
> -
> -  return RTEMS_INVALID_ID;
> +  return _Timer_Fire_after(
> +    id,
> +    ticks,
> +    routine,
> +    user_data,
> +    TIMER_INTERVAL,
> +    _Timer_Routine_adaptor
> +  );
>  }
> diff --git a/cpukit/rtems/src/timerfirewhen.c
> b/cpukit/rtems/src/timerfirewhen.c
> index 1acbaf9..eddeb16 100644
> --- a/cpukit/rtems/src/timerfirewhen.c
> +++ b/cpukit/rtems/src/timerfirewhen.c
> @@ -19,9 +19,6 @@
>  #endif
>
>  #include <rtems/rtems/timerimpl.h>
> -#include <rtems/rtems/clock.h>
> -#include <rtems/score/todimpl.h>
> -#include <rtems/score/watchdogimpl.h>
>
>  rtems_status_code rtems_timer_fire_when(
>    rtems_id                            id,
> @@ -30,43 +27,12 @@ rtems_status_code rtems_timer_fire_when(
>    void                               *user_data
>  )
>  {
> -  Timer_Control       *the_timer;
> -  Objects_Locations    location;
> -  rtems_interval       seconds;
> -
> -  if ( !_TOD_Is_set() )
> -    return RTEMS_NOT_DEFINED;
> -
> -  if ( !_TOD_Validate( wall_time ) )
> -    return RTEMS_INVALID_CLOCK;
> -
> -  if ( !routine )
> -    return RTEMS_INVALID_ADDRESS;
> -
> -  seconds = _TOD_To_seconds( wall_time );
> -  if ( seconds <= _TOD_Seconds_since_epoch() )
> -    return RTEMS_INVALID_CLOCK;
> -
> -  the_timer = _Timer_Get( id, &location );
> -  switch ( location ) {
> -
> -    case OBJECTS_LOCAL:
> -      _Timer_Cancel( the_timer );
> -      the_timer->the_class = TIMER_TIME_OF_DAY;
> -      _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
> -      _Watchdog_Insert_seconds(
> -         &the_timer->Ticker,
> -         seconds - _TOD_Seconds_since_epoch()
> -       );
> -      _Objects_Put( &the_timer->Object );
> -      return RTEMS_SUCCESSFUL;
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -    case OBJECTS_REMOTE:            /* should never return this */
> -#endif
> -    case OBJECTS_ERROR:
> -      break;
> -  }
> -
> -  return RTEMS_INVALID_ID;
> +  return _Timer_Fire_when(
> +    id,
> +    wall_time,
> +    routine,
> +    user_data,
> +    TIMER_TIME_OF_DAY,
> +    _Timer_Routine_adaptor
> +  );
>  }
> diff --git a/cpukit/rtems/src/timergetinfo.c
> b/cpukit/rtems/src/timergetinfo.c
> index 17c32e6..a11861c 100644
> --- a/cpukit/rtems/src/timergetinfo.c
> +++ b/cpukit/rtems/src/timergetinfo.c
> @@ -32,19 +32,22 @@ rtems_status_code rtems_timer_get_information(
>  {
>    Timer_Control     *the_timer;
>    Objects_Locations  location;
> +  ISR_lock_Context   lock_context;
> +  Per_CPU_Control   *cpu;
>
>    if ( !the_info )
>      return RTEMS_INVALID_ADDRESS;
>
> -  the_timer = _Timer_Get( id, &location );
> +  the_timer = _Timer_Get( id, &location, &lock_context );
>    switch ( location ) {
>
>      case OBJECTS_LOCAL:
> +      cpu = _Timer_Acquire_critical( the_timer, &lock_context );
>        the_info->the_class  = the_timer->the_class;
> -      the_info->initial    = the_timer->Ticker.initial;
> -      the_info->start_time = the_timer->Ticker.start_time;
> -      the_info->stop_time  = the_timer->Ticker.stop_time;
> -      _Objects_Put( &the_timer->Object );
> +      the_info->initial    = the_timer->initial;
> +      the_info->start_time = the_timer->start_time;
> +      the_info->stop_time  = the_timer->stop_time;
> +      _Timer_Release( cpu, &lock_context );
>        return RTEMS_SUCCESSFUL;
>
>  #if defined(RTEMS_MULTIPROCESSING)
> diff --git a/cpukit/rtems/src/timerreset.c b/cpukit/rtems/src/timerreset.c
> index 7ab172e..72c912b 100644
> --- a/cpukit/rtems/src/timerreset.c
> +++ b/cpukit/rtems/src/timerreset.c
> @@ -44,40 +44,29 @@ rtems_status_code rtems_timer_reset(
>  {
>    Timer_Control     *the_timer;
>    Objects_Locations  location;
> -  rtems_status_code  status = RTEMS_SUCCESSFUL;
> +  ISR_lock_Context   lock_context;
> +  Per_CPU_Control   *cpu;
> +  rtems_status_code  status;
>
> -  the_timer = _Timer_Get( id, &location );
> +  the_timer = _Timer_Get( id, &location, &lock_context );
>    switch ( location ) {
>
>      case OBJECTS_LOCAL:
> -      if ( the_timer->the_class == TIMER_INTERVAL ) {
> -        _Watchdog_Reset_ticks( &the_timer->Ticker );
> -      } else if ( the_timer->the_class == TIMER_INTERVAL_ON_TASK ) {
> -        Timer_server_Control *timer_server = _Timer_server;
> +      cpu = _Timer_Acquire_critical( the_timer, &lock_context );
>
> -        /*
> -         *  There is no way for a timer to have this class unless
> -         *  it was scheduled as a server fire.  That requires that
> -         *  the Timer Server be initiated.  So this error cannot
> -         *  occur unless something is internally wrong.
> -         */
> -        #if defined(RTEMS_DEBUG)
> -          if ( !timer_server ) {
> -            _Objects_Put( &the_timer->Object );
> -            return RTEMS_INCORRECT_STATE;
> -          }
> -        #endif
> -        (*timer_server->cancel)( timer_server, the_timer );
> -        (*timer_server->schedule_operation)( timer_server, the_timer );
> +      if ( _Timer_Is_interval_class( the_timer->the_class ) ) {
> +        _Timer_Cancel( cpu, the_timer );
> +        _Watchdog_Insert(
> +          &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +          &the_timer->Ticker,
> +          cpu->Watchdog.ticks + the_timer->initial
> +        );
> +        status = RTEMS_SUCCESSFUL;
>        } else {
> -        /*
> -         *  Must be dormant or time of day timer (e.g. TIMER_DORMANT,
> -         *  TIMER_TIME_OF_DAY, or TIMER_TIME_OF_DAY_ON_TASK).  We
> -         *  can only reset active interval timers.
> -         */
>          status = RTEMS_NOT_DEFINED;
>        }
> -      _Objects_Put( &the_timer->Object );
> +
> +      _Timer_Release( cpu, &lock_context );
>        return status;
>
>  #if defined(RTEMS_MULTIPROCESSING)
> diff --git a/cpukit/rtems/src/timerserver.c
> b/cpukit/rtems/src/timerserver.c
> index 7d75780..cf06319 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-2015 embedded brains GmbH.
> + *  Copyright (c) 2009, 2016 embedded brains GmbH.
>   *
>   *  The license and distribution terms for this file may be
>   *  found in the file LICENSE in this distribution or at
> @@ -34,193 +34,48 @@
>
>  static Timer_server_Control _Timer_server_Default;
>
> -static void _Timer_server_Cancel_method(
> +static void _Timer_server_Acquire(
>    Timer_server_Control *ts,
> -  Timer_Control *timer
> +  ISR_lock_Context     *lock_context
>  )
>  {
> -  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 Watchdog_Interval _Timer_server_Get_ticks( void )
> -{
> -  return _Watchdog_Ticks_since_boot;
> +  _ISR_lock_ISR_disable_and_acquire( &ts->Lock, lock_context );
>  }
>
> -static Watchdog_Interval _Timer_server_Get_seconds( void )
> -{
> -  return _TOD_Seconds_since_epoch();
> -}
> -
> -static void _Timer_server_Update_system_watchdog(
> -  Timer_server_Watchdogs *watchdogs,
> -  Watchdog_Header *system_header
> -)
> -{
> -  ISR_lock_Context lock_context;
> -
> -  _Watchdog_Acquire( &watchdogs->Header, &lock_context );
> -
> -  if ( watchdogs->system_watchdog_helper == NULL ) {
> -    Thread_Control *executing;
> -    uint32_t my_generation;
> -
> -    executing = _Thread_Executing;
> -    watchdogs->system_watchdog_helper = executing;
> -
> -    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(
> -  Timer_server_Watchdogs *watchdogs,
> -  Timer_Control *timer,
> -  Watchdog_Header *system_header,
> -  Watchdog_Interval (*get_ticks)( void )
> -)
> -{
> -  ISR_lock_Context lock_context;
> -  Watchdog_Interval now;
> -  Watchdog_Interval delta;
> -
> -  _Watchdog_Acquire( &watchdogs->Header, &lock_context );
> -
> -  now = (*get_ticks)();
> -  delta = now - watchdogs->last_snapshot;
> -  watchdogs->last_snapshot = now;
> -  watchdogs->current_snapshot = now;
> -
> -  if ( watchdogs->system_watchdog_delta > delta ) {
> -    watchdogs->system_watchdog_delta -= delta;
> -  } else {
> -    watchdogs->system_watchdog_delta = 0;
> -  }
> -
> -  if ( !_Watchdog_Is_empty( &watchdogs->Header ) ) {
> -    Watchdog_Control *first = _Watchdog_First( &watchdogs->Header );
> -
> -    if ( first->delta_interval > delta ) {
> -      first->delta_interval -= delta;
> -    } else {
> -      first->delta_interval = 0;
> -    }
> -  }
> -
> -  _Watchdog_Insert_locked(
> -    &watchdogs->Header,
> -    &timer->Ticker,
> -    &lock_context
> -  );
> -
> -  ++watchdogs->generation;
> -
> -  _Watchdog_Release( &watchdogs->Header, &lock_context );
> -
> -  _Timer_server_Update_system_watchdog( watchdogs, system_header );
> -}
> -
> -static void _Timer_server_Schedule_operation_method(
> +static void _Timer_server_Release(
>    Timer_server_Control *ts,
> -  Timer_Control *timer
> +  ISR_lock_Context     *lock_context
>  )
>  {
> -  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
> -    );
> -  }
> +  _ISR_lock_Release_and_ISR_enable( &ts->Lock, lock_context );
>  }
>
> -static void _Timer_server_Update_current_snapshot(
> -  Timer_server_Watchdogs *watchdogs,
> -  Watchdog_Interval (*get_ticks)( void )
> -)
> +void _Timer_server_Routine_adaptor( Watchdog_Control *the_watchdog )
>  {
> -  ISR_lock_Context lock_context;
> +  Timer_Control        *the_timer;
> +  ISR_lock_Context      lock_context;
> +  Per_CPU_Control      *cpu;
> +  Timer_server_Control *ts;
> +  bool                  wakeup;
>
> -  _Watchdog_Acquire( &watchdogs->Header, &lock_context );
> -  watchdogs->current_snapshot = (*get_ticks)();
> -  watchdogs->system_watchdog_delta = 0;
> -  _Watchdog_Release( &watchdogs->Header, &lock_context );
> -}
> +  ts = _Timer_server;
> +  _Assert( ts != NULL );
> +  the_timer = RTEMS_CONTAINER_OF( the_watchdog, Timer_Control, Ticker );
>
> -static void _Timer_server_Tickle(
> -  Timer_server_Watchdogs *watchdogs,
> -  Watchdog_Header *system_header,
> -  Watchdog_Interval (*get_ticks)( void ),
> -  bool ticks
> -)
> -{
> -  ISR_lock_Context lock_context;
> -  Watchdog_Interval now;
> -  Watchdog_Interval last;
> +  _Timer_server_Acquire( ts, &lock_context );
>
> -  _Watchdog_Acquire( &watchdogs->Header, &lock_context );
> +  _Assert( _Watchdog_Get_state( &the_timer->Ticker ) == WATCHDOG_INACTIVE
> );
> +  _Watchdog_Set_state( &the_timer->Ticker, WATCHDOG_PENDING );
> +  cpu = _Watchdog_Get_CPU( &the_timer->Ticker );
> +  the_timer->stop_time = _Timer_Get_CPU_ticks( cpu );
> +  wakeup = _Chain_Is_empty( &ts->Pending );
> +  _Chain_Append_unprotected( &ts->Pending, &the_timer->Ticker.Node.Chain
> );
>
> -  now = watchdogs->current_snapshot;
> -  last = watchdogs->last_snapshot;
> -  watchdogs->last_snapshot = now;
> +  _Timer_server_Release( ts, &lock_context );
>
> -  if ( ticks || now >= last ) {
> -    _Watchdog_Adjust_forward_locked(
> -      &watchdogs->Header,
> -      now - last,
> -      &lock_context
> -    );
> -  } else {
> -    _Watchdog_Adjust_backward_locked(
> -      &watchdogs->Header,
> -      last - now
> -    );
> +  if ( wakeup ) {
> +    (void) rtems_event_system_send( ts->server_id,
> RTEMS_EVENT_SYSTEM_SERVER );
>    }
> -
> -  ++watchdogs->generation;
> -
> -  _Watchdog_Release( &watchdogs->Header, &lock_context );
> -
> -  _Timer_server_Update_system_watchdog( watchdogs, system_header );
>  }
>
>  /**
> @@ -239,21 +94,38 @@ static rtems_task _Timer_server_Body(
>    Timer_server_Control *ts = (Timer_server_Control *) arg;
>
>    while ( true ) {
> -    rtems_event_set events;
> +    ISR_lock_Context  lock_context;
> +    rtems_event_set   events;
>
> -    _Timer_server_Tickle(
> -      &ts->Interval_watchdogs,
> -      &_Watchdog_Ticks_header,
> -      _Timer_server_Get_ticks,
> -      true
> -    );
> +    _Timer_server_Acquire( ts, &lock_context );
>
> -    _Timer_server_Tickle(
> -      &ts->TOD_watchdogs,
> -      &_Watchdog_Seconds_header,
> -      _Timer_server_Get_seconds,
> -      false
> -    );
> +    while ( true ) {
> +      Watchdog_Control                  *the_watchdog;
> +      Timer_Control                     *the_timer;
> +      rtems_timer_service_routine_entry  routine;
> +      Objects_Id                         id;
> +      void                              *user_data;
> +
> +      the_watchdog = (Watchdog_Control *) _Chain_Get_unprotected(
> &ts->Pending );
> +      if ( the_watchdog == NULL ) {
> +        break;
> +      }
> +
> +      _Assert( _Watchdog_Get_state( the_watchdog ) == WATCHDOG_PENDING );
> +      _Watchdog_Set_state( the_watchdog, WATCHDOG_INACTIVE );
> +      the_timer = RTEMS_CONTAINER_OF( the_watchdog, Timer_Control, Ticker
> );
> +      routine = the_timer->routine;
> +      id = the_timer->Object.id;
> +      user_data = the_timer->user_data;
> +
> +      _Timer_server_Release( ts, &lock_context );
> +
> +      ( *routine )( id, user_data );
> +
> +      _Timer_server_Acquire( ts, &lock_context );
> +    }
> +
> +    _Timer_server_Release( ts, &lock_context );
>
>      (void) rtems_event_system_receive(
>        RTEMS_EVENT_SYSTEM_SERVER,
> @@ -264,99 +136,35 @@ static rtems_task _Timer_server_Body(
>    }
>  }
>
> -static void _Timer_server_Wakeup(
> -  Objects_Id  id,
> -  void       *arg
> -)
> -{
> -  Timer_server_Control *ts = arg;
> -
> -  _Timer_server_Update_current_snapshot(
> -    &ts->Interval_watchdogs,
> -    _Timer_server_Get_ticks
> -  );
> -
> -  _Timer_server_Update_current_snapshot(
> -    &ts->TOD_watchdogs,
> -    _Timer_server_Get_seconds
> -  );
> -
> -  (void) rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_SERVER );
> -}
> -
> -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;
> -
> -  now = (*get_ticks)();
> -  watchdogs->last_snapshot = now;
> -  watchdogs->current_snapshot = now;
> -
> -  _Watchdog_Header_initialize( &watchdogs->Header );
> -  _Watchdog_Preinitialize( &watchdogs->System_watchdog );
> -  _Watchdog_Initialize(
> -    &watchdogs->System_watchdog,
> -    _Timer_server_Wakeup,
> -    id,
> -    ts
> -  );
> -}
> -
> -/**
> - *  @brief rtems_timer_initiate_server
> - *
> - *  This directive creates and starts the server for task-based timers.
> - *  It must be invoked before any task-based timers can be initiated.
> - *
> - *  @param[in] priority is the timer server priority
> - *  @param[in] stack_size is the stack size in bytes
> - *  @param[in] attribute_set is the timer server attributes
> - *
> - *  @return This method returns RTEMS_SUCCESSFUL if successful and an
> - *          error code otherwise.
> - */
> -rtems_status_code rtems_timer_initiate_server(
> -  uint32_t             priority,
> -  uint32_t             stack_size,
> -  rtems_attribute      attribute_set
> +static rtems_status_code _Timer_server_Initiate(
> +  rtems_task_priority priority,
> +  size_t              stack_size,
> +  rtems_attribute     attribute_set
>  )
>  {
> -  rtems_id              id;
>    rtems_status_code     status;
> -  rtems_task_priority   _priority;
> -  static bool           initialized = false;
> -  bool                  tmpInitialized;
> -  Timer_server_Control *ts = &_Timer_server_Default;
> +  rtems_id              id;
> +  Timer_server_Control *ts;
> +
> +  /*
> +   *  Just to make sure this is only called once.
> +   */
> +  if ( _Timer_server != NULL ) {
> +    return RTEMS_INCORRECT_STATE;
> +  }
>
>    /*
>     *  Make sure the requested priority is valid.  The if is
>     *  structured so we check it is invalid before looking for
>     *  a specific invalid value as the default.
>     */
> -  _priority = priority;
>    if ( !_RTEMS_tasks_Priority_is_valid( priority ) ) {
>      if ( priority != RTEMS_TIMER_SERVER_DEFAULT_PRIORITY )
>        return RTEMS_INVALID_PRIORITY;
> -    _priority = PRIORITY_PSEUDO_ISR;
> +    priority = PRIORITY_PSEUDO_ISR;
>    }
>
>    /*
> -   *  Just to make sure this is only called once.
> -   */
> -  _Once_Lock();
> -    tmpInitialized  = initialized;
> -    initialized = true;
> -  _Once_Unlock();
> -
> -  if ( tmpInitialized )
> -    return RTEMS_INCORRECT_STATE;
> -
> -  /*
>     *  Create the Timer Server with the name the name of "TIME".  The
> attribute
>     *  RTEMS_SYSTEM_TASK allows us to set a priority to 0 which will makes
> it
>     *  higher than any other task in the system.  It can be viewed as a low
> @@ -371,19 +179,18 @@ rtems_status_code rtems_timer_initiate_server(
>     *  GNAT run-time is violated.
>     */
>    status = rtems_task_create(
> -    _Objects_Build_name('T','I','M','E'),           /* "TIME" */
> -    _priority,            /* create with priority 1 since 0 is illegal */
> -    stack_size,           /* let user specify stack size */
> +    rtems_build_name('T','I','M','E'),
> +    priority,
> +    stack_size,
>      rtems_configuration_is_smp_enabled() ?
>        RTEMS_DEFAULT_MODES : /* no preempt is not supported for SMP */
>        RTEMS_NO_PREEMPT,   /* no preempt is like an interrupt */
>                            /* user may want floating point but we need */
>                            /*   system task specified for 0 priority */
>      attribute_set | RTEMS_SYSTEM_TASK,
> -    &id                   /* get the id back */
> +    &id
>    );
> -  if (status) {
> -    initialized = false;
> +  if (status != RTEMS_SUCCESSFUL) {
>      return status;
>    }
>
> @@ -392,26 +199,10 @@ rtems_status_code rtems_timer_initiate_server(
>     *  Timer Server so we do not have to have a critical section.
>     */
>
> -  _Timer_server_Initialize_watchdogs(
> -    ts,
> -    id,
> -    &ts->Interval_watchdogs,
> -    _Timer_server_Get_ticks
> -  );
> -
> -  _Timer_server_Initialize_watchdogs(
> -    ts,
> -    id,
> -    &ts->TOD_watchdogs,
> -    _Timer_server_Get_seconds
> -  );
> -
> -  /*
> -   *  Initialize the pointer to the timer server methods so applications
> that
> -   *  do not use the Timer Server do not have to pull it in.
> -   */
> -  ts->cancel = _Timer_server_Cancel_method;
> -  ts->schedule_operation = _Timer_server_Schedule_operation_method;
> +  ts = &_Timer_server_Default;
> +  _ISR_lock_Initialize( &ts->Lock, "Timer Server" );
> +  _Chain_Initialize_empty( &ts->Pending );
> +  ts->server_id = id;
>
>    /*
>     * The default timer server is now available.
> @@ -426,19 +217,22 @@ rtems_status_code rtems_timer_initiate_server(
>      _Timer_server_Body,
>      (rtems_task_argument) ts
>    );
> +  _Assert( status == RTEMS_SUCCESSFUL );
>
> -  #if defined(RTEMS_DEBUG)
> -    /*
> -     *  One would expect a call to rtems_task_delete() here to clean up
> -     *  but there is actually no way (in normal circumstances) that the
> -     *  start can fail.  The id and starting address are known to be
> -     *  be good.  If this service fails, something is weirdly wrong on the
> -     *  target such as a stray write in an ISR or incorrect memory layout.
> -     */
> -    if (status) {
> -      initialized = false;
> -    }
> -  #endif
> +  return status;
> +}
> +
> +rtems_status_code rtems_timer_initiate_server(
> +  rtems_task_priority priority,
> +  size_t              stack_size,
> +  rtems_attribute     attribute_set
> +)
> +{
> +  rtems_status_code status;
> +
> +  _Once_Lock();
> +  status = _Timer_server_Initiate( priority, stack_size, attribute_set );
> +  _Once_Unlock();
>
>    return status;
>  }
> diff --git a/cpukit/rtems/src/timerserverfireafter.c
> b/cpukit/rtems/src/timerserverfireafter.c
> index 0636782..ce1fd05 100644
> --- a/cpukit/rtems/src/timerserverfireafter.c
> +++ b/cpukit/rtems/src/timerserverfireafter.c
> @@ -18,12 +18,7 @@
>  #include "config.h"
>  #endif
>
> -#include <rtems/system.h>
> -#include <rtems/rtems/status.h>
> -#include <rtems/rtems/support.h>
> -#include <rtems/score/thread.h>
>  #include <rtems/rtems/timerimpl.h>
> -#include <rtems/score/watchdogimpl.h>
>
>  rtems_status_code rtems_timer_server_fire_after(
>    rtems_id                           id,
> @@ -32,60 +27,19 @@ rtems_status_code rtems_timer_server_fire_after(
>    void                              *user_data
>  )
>  {
> -  Timer_Control        *the_timer;
> -  Objects_Locations     location;
> -  ISR_Level             level;
> -  Timer_server_Control *timer_server = _Timer_server;
> +  Timer_server_Control *timer_server;
> +
> +  timer_server = _Timer_server;
>
>    if ( !timer_server )
>      return RTEMS_INCORRECT_STATE;
>
> -  if ( !routine )
> -    return RTEMS_INVALID_ADDRESS;
> -
> -  if ( ticks == 0 )
> -    return RTEMS_INVALID_NUMBER;
> -
> -  the_timer = _Timer_Get( id, &location );
> -  switch ( location ) {
> -
> -    case OBJECTS_LOCAL:
> -      _Timer_Cancel( the_timer );
> -
> -      _ISR_Disable( level );
> -
> -        /*
> -         *  Check to see if the watchdog has just been inserted by a
> -         *  higher priority interrupt.  If so, abandon this insert.
> -         */
> -
> -        if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) {
> -          _ISR_Enable( level );
> -          _Objects_Put( &the_timer->Object );
> -          return RTEMS_SUCCESSFUL;
> -        }
> -
> -        /*
> -         *  OK.  Now we now the timer was not rescheduled by an interrupt
> -         *  so we can atomically initialize it as in use.
> -         */
> -
> -        the_timer->the_class = TIMER_INTERVAL_ON_TASK;
> -        _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data
> );
> -        the_timer->Ticker.initial = ticks;
> -      _ISR_Enable( level );
> -
> -      (*timer_server->schedule_operation)( timer_server, the_timer );
> -
> -      _Objects_Put( &the_timer->Object );
> -      return RTEMS_SUCCESSFUL;
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -    case OBJECTS_REMOTE:            /* should never return this */
> -#endif
> -    case OBJECTS_ERROR:
> -      break;
> -  }
> -
> -  return RTEMS_INVALID_ID;
> +  return _Timer_Fire_after(
> +    id,
> +    ticks,
> +    routine,
> +    user_data,
> +    TIMER_INTERVAL_ON_TASK,
> +    _Timer_server_Routine_adaptor
> +  );
>  }
> diff --git a/cpukit/rtems/src/timerserverfirewhen.c
> b/cpukit/rtems/src/timerserverfirewhen.c
> index 0069af1..f96a470 100644
> --- a/cpukit/rtems/src/timerserverfirewhen.c
> +++ b/cpukit/rtems/src/timerserverfirewhen.c
> @@ -19,26 +19,6 @@
>  #endif
>
>  #include <rtems/rtems/timerimpl.h>
> -#include <rtems/rtems/clock.h>
> -#include <rtems/score/todimpl.h>
> -#include <rtems/score/watchdogimpl.h>
> -
> -/*
> - *  rtems_timer_server_fire_when
> - *
> - *  This directive allows a thread to start a timer which will by
> - *  executed by the Timer Server when it fires.
> - *
> - *  Input parameters:
> - *    id        - timer id
> - *    wall_time - time of day to fire timer
> - *    routine   - routine to schedule
> - *    user_data - passed as argument to routine when it is fired
> - *
> - *  Output parameters:
> - *    RTEMS_SUCCESSFUL - if successful
> - *    error code       - if unsuccessful
> - */
>
>  rtems_status_code rtems_timer_server_fire_when(
>    rtems_id                           id,
> @@ -47,47 +27,19 @@ rtems_status_code rtems_timer_server_fire_when(
>    void                              *user_data
>  )
>  {
> -  Timer_Control        *the_timer;
> -  Objects_Locations     location;
> -  rtems_interval        seconds;
> -  Timer_server_Control *timer_server = _Timer_server;
> +  Timer_server_Control *timer_server;
> +
> +  timer_server = _Timer_server;
>
>    if ( !timer_server )
>      return RTEMS_INCORRECT_STATE;
>
> -  if ( !_TOD_Is_set() )
> -    return RTEMS_NOT_DEFINED;
> -
> -  if ( !routine )
> -    return RTEMS_INVALID_ADDRESS;
> -
> -  if ( !_TOD_Validate( wall_time ) )
> -    return RTEMS_INVALID_CLOCK;
> -
> -  seconds = _TOD_To_seconds( wall_time );
> -  if ( seconds <= _TOD_Seconds_since_epoch() )
> -    return RTEMS_INVALID_CLOCK;
> -
> -  the_timer = _Timer_Get( id, &location );
> -  switch ( location ) {
> -
> -    case OBJECTS_LOCAL:
> -      _Timer_Cancel( the_timer );
> -      the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK;
> -      _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
> -      the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch();
> -
> -      (*timer_server->schedule_operation)( timer_server, the_timer );
> -
> -      _Objects_Put( &the_timer->Object );
> -      return RTEMS_SUCCESSFUL;
> -
> -#if defined(RTEMS_MULTIPROCESSING)
> -    case OBJECTS_REMOTE:            /* should never return this */
> -#endif
> -    case OBJECTS_ERROR:
> -      break;
> -  }
> -
> -  return RTEMS_INVALID_ID;
> +  return _Timer_Fire_when(
> +    id,
> +    wall_time,
> +    routine,
> +    user_data,
> +    TIMER_TIME_OF_DAY_ON_TASK,
> +    _Timer_server_Routine_adaptor
> +  );
>  }
> diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c
> index 7df2316..350c774 100644
> --- a/cpukit/sapi/src/exinit.c
> +++ b/cpukit/sapi/src/exinit.c
> @@ -38,7 +38,6 @@
>  #include <rtems/score/timecounter.h>
>  #include <rtems/score/threadimpl.h>
>  #include <rtems/score/todimpl.h>
> -#include <rtems/score/watchdogimpl.h>
>  #include <rtems/score/wkspace.h>
>
>  const char _Copyright_Notice[] =
> @@ -87,8 +86,6 @@ static void rtems_initialize_data_structures(void)
>    _API_Mutex_Allocate( &_RTEMS_Allocator_Mutex );
>    _API_Mutex_Allocate( &_Once_Mutex );
>
> -  _Watchdog_Handler_initialization();
> -
>    _Thread_Handler_initialization();
>
>    _Scheduler_Handler_initialization();
> diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
> index 3d3f1c1..ea440b3 100644
> --- a/cpukit/score/Makefile.am
> +++ b/cpukit/score/Makefile.am
> @@ -327,14 +327,13 @@ libscore_a_SOURCES += src/timespecaddto.c
> src/timespecfromticks.c \
>
>  ## TOD_C_FILES
>  libscore_a_SOURCES += src/coretod.c src/coretodset.c \
> -    src/coretodtickle.c \
>      src/coretodtickspersec.c \
>      src/coretodadjust.c
>  libscore_a_SOURCES += src/coretodabsolutetimeout.c
>
>  ## WATCHDOG_C_FILES
> -libscore_a_SOURCES += src/watchdog.c src/watchdogadjust.c \
> -    src/watchdoginsert.c src/watchdogremove.c
> +libscore_a_SOURCES += src/watchdoginsert.c
> +libscore_a_SOURCES += src/watchdogremove.c
>  libscore_a_SOURCES += src/watchdogtick.c
>  libscore_a_SOURCES += src/watchdogtickssinceboot.c
>
> diff --git a/cpukit/score/include/rtems/score/mrsp.h
> b/cpukit/score/include/rtems/score/mrsp.h
> index 08f96ac..cb3de67 100644
> --- a/cpukit/score/include/rtems/score/mrsp.h
> +++ b/cpukit/score/include/rtems/score/mrsp.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
> + * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
>   *
>   *  embedded brains GmbH
>   *  Dornierstr. 4
> @@ -128,6 +128,11 @@ typedef struct {
>     * MRSP_TIMEOUT.  State changes are protected by the MrsP control lock.
>     */
>    volatile MRSP_Status status;
> +
> +  /**
> +   * @brief Watchdog for timeouts.
> +   */
> +  Watchdog_Control Watchdog;
>  } MRSP_Rival;
>
>  /**
> diff --git a/cpukit/score/include/rtems/score/mrspimpl.h
> b/cpukit/score/include/rtems/score/mrspimpl.h
> index bc9ed4b..7638fb5 100644
> --- a/cpukit/score/include/rtems/score/mrspimpl.h
> +++ b/cpukit/score/include/rtems/score/mrspimpl.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2014-2015 embedded brains GmbH.  All rights reserved.
> + * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
>   *
>   *  embedded brains GmbH
>   *  Dornierstr. 4
> @@ -159,18 +159,13 @@ RTEMS_INLINE_ROUTINE void _MRSP_Set_ceiling_priority(
>    mrsp->ceiling_priorities[ scheduler_index ] = ceiling_priority;
>  }
>
> -RTEMS_INLINE_ROUTINE void _MRSP_Timeout(
> -  Objects_Id  id,
> -  void       *arg
> -)
> +RTEMS_INLINE_ROUTINE void _MRSP_Timeout( Watchdog_Control *watchdog )
>  {
> -  MRSP_Rival *rival = arg;
> +  MRSP_Rival *rival = RTEMS_CONTAINER_OF( watchdog, MRSP_Rival, Watchdog
> );
>    MRSP_Control *mrsp = rival->resource;
>    Thread_Control *thread = rival->thread;
>    ISR_lock_Context lock_context;
>
> -  (void) id;
> -
>    _ISR_lock_ISR_disable_and_acquire( &mrsp->Lock, &lock_context );
>
>    if ( rival->status == MRSP_WAIT_FOR_OWNERSHIP ) {
> @@ -209,6 +204,7 @@ RTEMS_INLINE_ROUTINE MRSP_Status
> _MRSP_Wait_for_ownership(
>    bool initial_life_protection;
>    Per_CPU_Control *cpu_self;
>    ISR_lock_Context giant_lock_context;
> +  ISR_Level level;
>
>    rival.thread = executing;
>    rival.resource = mrsp;
> @@ -236,13 +232,11 @@ RTEMS_INLINE_ROUTINE MRSP_Status
> _MRSP_Wait_for_ownership(
>    _Thread_Raise_priority( executing, ceiling_priority );
>
>    if ( timeout > 0 ) {
> -    _Watchdog_Initialize(
> -      &executing->Timer,
> -      _MRSP_Timeout,
> -      0,
> -      &rival
> -    );
> -    _Watchdog_Insert_ticks( &executing->Timer, timeout );
> +    _Watchdog_Preinitialize( &rival.Watchdog, cpu_self );
> +    _Watchdog_Initialize( &rival.Watchdog, _MRSP_Timeout );
> +    _ISR_Disable_without_giant( level );
> +    _Watchdog_Per_CPU_insert_relative( &rival.Watchdog, cpu_self, timeout
> );
> +    _ISR_Enable_without_giant( level );
>    }
>
>    initial_life_protection = _Thread_Set_life_protection( true );
> @@ -258,7 +252,13 @@ RTEMS_INLINE_ROUTINE MRSP_Status
> _MRSP_Wait_for_ownership(
>    _Thread_Set_life_protection( initial_life_protection );
>
>    if ( timeout > 0 ) {
> -    _Watchdog_Remove_ticks( &executing->Timer );
> +    _ISR_Disable_without_giant( level );
> +    _Watchdog_Per_CPU_remove(
> +      &rival.Watchdog,
> +      cpu_self,
> +      &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ]
> +    );
> +    _ISR_Enable_without_giant( level );
>
>      if ( status == MRSP_TIMEOUT ) {
>        _MRSP_Restore_priority( executing, initial_priority );
> diff --git a/cpukit/score/include/rtems/score/percpu.h
> b/cpukit/score/include/rtems/score/percpu.h
> index 39be1e3..2201788 100644
> --- a/cpukit/score/include/rtems/score/percpu.h
> +++ b/cpukit/score/include/rtems/score/percpu.h
> @@ -23,10 +23,11 @@
>    #include <rtems/asm.h>
>  #else
>    #include <rtems/score/assert.h>
> -  #include <rtems/score/isrlevel.h>
> +  #include <rtems/score/isrlock.h>
>    #include <rtems/score/smp.h>
>    #include <rtems/score/smplock.h>
>    #include <rtems/score/timestamp.h>
> +  #include <rtems/score/watchdog.h>
>  #endif
>
>  #ifdef __cplusplus
> @@ -41,7 +42,7 @@ extern "C" {
>     * processor.
>     */
>    #if defined( RTEMS_PROFILING )
> -    #define PER_CPU_CONTROL_SIZE_LOG2 8
> +    #define PER_CPU_CONTROL_SIZE_LOG2 9
>    #else
>      #define PER_CPU_CONTROL_SIZE_LOG2 7
>    #endif
> @@ -226,6 +227,32 @@ typedef struct {
>  } Per_CPU_Stats;
>
>  /**
> + * @brief Per-CPU watchdog header index.
> + */
> +typedef enum {
> +  /**
> +   * @brief Index for relative per-CPU watchdog header.
> +   *
> +   * The reference time point for this header is current ticks value
> +   * during insert.  Time is measured in clock ticks.
> +   */
> +  PER_CPU_WATCHDOG_RELATIVE,
> +
> +  /**
> +   * @brief Index for absolute per-CPU watchdog header.
> +   *
> +   * The reference time point for this header is the POSIX Epoch.  Time is
> +   * measured in nanoseconds since POSIX Epoch.
> +   */
> +  PER_CPU_WATCHDOG_ABSOLUTE,
> +
> +  /**
> +   * @brief Count of per-CPU watchdog headers.
> +   */
> +  PER_CPU_WATCHDOG_COUNT
> +} Per_CPU_Watchdog_index;
> +
> +/**
>   *  @brief Per CPU Core Structure
>   *
>   *  This structure is used to hold per core state information.
> @@ -309,6 +336,28 @@ typedef struct Per_CPU_Control {
>    /** This is the time of the last context switch on this CPU. */
>    Timestamp_Control time_of_last_context_switch;
>
> +  /**
> +   * @brief Watchdog state for this processor.
> +   */
> +  struct {
> +    /**
> +     * @brief Protects all watchdog operations on this processor.
> +     */
> +    ISR_LOCK_MEMBER( Lock )
> +
> +    /**
> +     * @brief Watchdog ticks on this processor used for relative
> watchdogs.
> +     */
> +    uint64_t ticks;
> +
> +    /**
> +     * @brief Header for watchdogs.
> +     *
> +     * @see Per_CPU_Watchdog_index.
> +     */
> +    Watchdog_Header Header[ PER_CPU_WATCHDOG_COUNT ];
> +  } Watchdog;
> +
>    #if defined( RTEMS_SMP )
>      /**
>       * @brief This lock protects some parts of the low-level thread
> dispatching.
> diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h
> b/cpukit/score/include/rtems/score/schedulerimpl.h
> index cadebfd..d50c36a 100644
> --- a/cpukit/score/include/rtems/score/schedulerimpl.h
> +++ b/cpukit/score/include/rtems/score/schedulerimpl.h
> @@ -452,19 +452,13 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Release_job(
>   * scheduler which support standard RTEMS features, this includes
>   * time-slicing management.
>   */
> -RTEMS_INLINE_ROUTINE void _Scheduler_Tick( void )
> +RTEMS_INLINE_ROUTINE void _Scheduler_Tick( const Per_CPU_Control *cpu )
>  {
> -  uint32_t cpu_count = _SMP_Get_processor_count();
> -  uint32_t cpu_index;
> +  const Scheduler_Control *scheduler = _Scheduler_Get_by_CPU( cpu );
> +  Thread_Control *executing = cpu->executing;
>
> -  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
> -    const Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
> -    const Scheduler_Control *scheduler = _Scheduler_Get_by_CPU( cpu );
> -    Thread_Control *executing = cpu->executing;
> -
> -    if ( scheduler != NULL && executing != NULL ) {
> -      ( *scheduler->Operations.tick )( scheduler, executing );
> -    }
> +  if ( scheduler != NULL && executing != NULL ) {
> +    ( *scheduler->Operations.tick )( scheduler, executing );
>    }
>  }
>
> diff --git a/cpukit/score/include/rtems/score/thread.h
> b/cpukit/score/include/rtems/score/thread.h
> index 73776b3..44b706d 100644
> --- a/cpukit/score/include/rtems/score/thread.h
> +++ b/cpukit/score/include/rtems/score/thread.h
> @@ -347,6 +347,15 @@ typedef struct {
>  }   Thread_Wait_information;
>
>  /**
> + * @brief Information required to manage a thread timer.
> + */
> +typedef struct {
> +  ISR_LOCK_MEMBER( Lock )
> +  Watchdog_Header *header;
> +  Watchdog_Control Watchdog;
> +} Thread_Timer_information;
> +
> +/**
>   *  The following defines the control block used to manage
>   *  each thread proxy.
>   *
> @@ -400,7 +409,7 @@ typedef struct {
>    /** This field is the blocking information for this proxy. */
>    Thread_Wait_information  Wait;
>    /** This field is the Watchdog used to manage proxy delays and
> timeouts. */
> -  Watchdog_Control         Timer;
> +  Thread_Timer_information Timer;
>  #if defined(RTEMS_MULTIPROCESSING)
>    /** This field is the received response packet in an MP system. */
>    MP_packet_Prefix        *receive_packet;
> @@ -728,7 +737,7 @@ struct _Thread_Control {
>    /** This field is the blocking information for this thread. */
>    Thread_Wait_information  Wait;
>    /** This field is the Watchdog used to manage thread delays and
> timeouts. */
> -  Watchdog_Control         Timer;
> +  Thread_Timer_information Timer;
>  #if defined(RTEMS_MULTIPROCESSING)
>    /** This field is the received response packet in an MP system. */
>    MP_packet_Prefix        *receive_packet;
> diff --git a/cpukit/score/include/rtems/score/threadimpl.h
> b/cpukit/score/include/rtems/score/threadimpl.h
> index 1377543..ec9851d 100644
> --- a/cpukit/score/include/rtems/score/threadimpl.h
> +++ b/cpukit/score/include/rtems/score/threadimpl.h
> @@ -33,6 +33,7 @@
>  #include <rtems/score/threadqimpl.h>
>  #include <rtems/score/todimpl.h>
>  #include <rtems/score/freechain.h>
> +#include <rtems/score/watchdogimpl.h>
>  #include <rtems/config.h>
>
>  #ifdef __cplusplus
> @@ -1472,10 +1473,64 @@ RTEMS_INLINE_ROUTINE void
> _Thread_Wait_set_timeout_code(
>  /**
>   * @brief General purpose thread wait timeout.
>   *
> - * @param[in] id Unused.
> - * @param[in] arg The thread.
> + * @param[in] watchdog The thread timer watchdog.
>   */
> -void _Thread_Timeout( Objects_Id id, void *arg );
> +void _Thread_Timeout( Watchdog_Control *watchdog );
> +
> +RTEMS_INLINE_ROUTINE void _Thread_Timer_insert_relative(
> +  Thread_Control                 *the_thread,
> +  Per_CPU_Control                *cpu,
> +  Watchdog_Service_routine_entry  routine,
> +  Watchdog_Interval               ticks
> +)
> +{
> +  ISR_lock_Context lock_context;
> +
> +  _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock,
> &lock_context );
> +
> +  the_thread->Timer.header = &cpu->Watchdog.Header[
> PER_CPU_WATCHDOG_RELATIVE ];
> +  the_thread->Timer.Watchdog.routine = routine;
> +  _Watchdog_Per_CPU_insert_relative( &the_thread->Timer.Watchdog, cpu,
> ticks );
> +
> +  _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock,
> &lock_context );
> +}
> +
> +RTEMS_INLINE_ROUTINE void _Thread_Timer_insert_absolute(
> +  Thread_Control                 *the_thread,
> +  Per_CPU_Control                *cpu,
> +  Watchdog_Service_routine_entry  routine,
> +  uint64_t                        expire
> +)
> +{
> +  ISR_lock_Context lock_context;
> +
> +  _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock,
> &lock_context );
> +
> +  the_thread->Timer.header = &cpu->Watchdog.Header[
> PER_CPU_WATCHDOG_ABSOLUTE ];
> +  the_thread->Timer.Watchdog.routine = routine;
> +  _Watchdog_Per_CPU_insert_absolute( &the_thread->Timer.Watchdog, cpu,
> expire );
> +
> +  _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock,
> &lock_context );
> +}
> +
> +RTEMS_INLINE_ROUTINE void _Thread_Timer_remove( Thread_Control
> *the_thread )
> +{
> +  ISR_lock_Context lock_context;
> +
> +  _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock,
> &lock_context );
> +
> +  _Watchdog_Per_CPU_remove(
> +    &the_thread->Timer.Watchdog,
> +#if defined(RTEMS_SMP)
> +    the_thread->Timer.Watchdog.cpu,
> +#else
> +    _Per_CPU_Get(),
> +#endif
> +    the_thread->Timer.header
> +  );
> +
> +  _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock,
> &lock_context );
> +}
>
>  RTEMS_INLINE_ROUTINE void _Thread_Debug_set_real_processor(
>    Thread_Control  *the_thread,
> diff --git a/cpukit/score/include/rtems/score/todimpl.h
> b/cpukit/score/include/rtems/score/todimpl.h
> index b61651c..b1f8a6d 100644
> --- a/cpukit/score/include/rtems/score/todimpl.h
> +++ b/cpukit/score/include/rtems/score/todimpl.h
> @@ -132,15 +132,6 @@ extern "C" {
>   */
>  typedef struct {
>    /**
> -   * @brief Time of day seconds trigger.
> -   *
> -   * This value specifies the nanoseconds since the last time of day
> second.
> -   * It is updated and evaluated in _TOD_Tickle_ticks().  It is set in
> -   * _TOD_Set_with_timestamp().
> -   */
> -  uint32_t seconds_trigger;
> -
> -  /**
>     *  @brief Indicates if the time of day is set.
>     *
>     *  This is true if the application has set the current
> @@ -273,14 +264,6 @@ static inline uint32_t _TOD_Seconds_since_epoch( void
> )
>  }
>
>  /**
> - *  @brief Increments time of day at each clock tick.
> - *
> - *  This routine increments the ticks field of the current time of
> - *  day at each clock tick.
> - */
> -void _TOD_Tickle_ticks( void );
> -
> -/**
>   *  @brief Gets number of ticks in a second.
>   *
>   *  This method returns the number of ticks in a second.
> diff --git a/cpukit/score/include/rtems/score/watchdog.h
> b/cpukit/score/include/rtems/score/watchdog.h
> index bad7269..b371f94 100644
> --- a/cpukit/score/include/rtems/score/watchdog.h
> +++ b/cpukit/score/include/rtems/score/watchdog.h
> @@ -20,7 +20,11 @@
>  #ifndef _RTEMS_SCORE_WATCHDOG_H
>  #define _RTEMS_SCORE_WATCHDOG_H
>
> -#include <rtems/score/object.h>
> +#include <rtems/score/basedefs.h>
> +#include <rtems/score/chain.h>
> +#include <rtems/score/rbtree.h>
> +
> +struct Per_CPU_Control;
>
>  #ifdef __cplusplus
>  extern "C" {
> @@ -39,6 +43,8 @@ extern "C" {
>   */
>  /**@{*/
>
> +typedef struct Watchdog_Control Watchdog_Control;
> +
>  /**
>   *  @brief Type is used to specify the length of intervals.
>   *
> @@ -58,10 +64,8 @@ typedef void Watchdog_Service_routine;
>   *
>   *  This type define a pointer to a watchdog service routine.
>   */
> -typedef Watchdog_Service_routine ( *Watchdog_Service_routine_entry )(
> -                 Objects_Id,
> -                 void *
> -             );
> +typedef Watchdog_Service_routine
> +  ( *Watchdog_Service_routine_entry )( Watchdog_Control * );
>
>  /**
>   *  @brief The constant for indefinite wait.
> @@ -72,22 +76,20 @@ typedef Watchdog_Service_routine (
> *Watchdog_Service_routine_entry )(
>  #define WATCHDOG_NO_TIMEOUT  0
>
>  /**
> - *  @brief Set of the states which a watchdog timer may be at any given
> time.
> - *
> - *  This enumerated type is the set of the states in which a
> - *  watchdog timer may be at any given time.
> + * @brief The watchdog header to manage scheduled watchdogs.
>   */
> +typedef struct {
> +  /**
> +   * @brief Red-black tree of scheduled watchdogs sorted by expiration
> time.
> +   */
> +  RBTree_Control Watchdogs;
>
> -typedef enum {
> -  /** This is the state when the watchdog is off all chains */
> -  WATCHDOG_INACTIVE,
> -  /** This is the state when the watchdog is off all chains, but we are
> -   *  currently searching for the insertion point.
> +  /**
> +   * @brief The scheduled watchdog with the earliest expiration time or
> NULL in
> +   * case no watchdog is scheduled.
>     */
> -  WATCHDOG_BEING_INSERTED,
> -  /** This is the state when the watchdog is on a chain, and allowed to
> fire. */
> -  WATCHDOG_ACTIVE
> -} Watchdog_States;
> +  RBTree_Node *first;
> +} Watchdog_Header;
>
>  /**
>   *  @brief The control block used to manage each watchdog timer.
> @@ -95,30 +97,35 @@ typedef enum {
>   *  The following record defines the control block used
>   *  to manage each watchdog timer.
>   */
> -typedef struct {
> -  /** This field is a Chain Node structure and allows this to be placed on
> -   *  chains for set management.
> -   */
> -  Chain_Node                      Node;
> -  /** This field is the state of the watchdog. */
> -  Watchdog_States                 state;
> -  /** This field is the initially requested interval. */
> -  Watchdog_Interval               initial;
> -  /** This field is the remaining portion of the interval. */
> -  Watchdog_Interval               delta_interval;
> -  /** This field is the number of system clock ticks when this was
> scheduled. */
> -  Watchdog_Interval               start_time;
> -  /** This field is the number of system clock ticks when this was
> suspended. */
> -  Watchdog_Interval               stop_time;
> -  /** This field is the function to invoke. */
> -  Watchdog_Service_routine_entry  routine;
> -  /** This field is the Id to pass as an argument to the routine. */
> -  Objects_Id                      id;
> -  /** This field is an untyped pointer to user data that is passed to the
> -   *  watchdog handler routine.
> +struct Watchdog_Control {
> +  /**
> +   * @brief Nodes for the watchdog.
>     */
> -  void                           *user_data;
> -}   Watchdog_Control;
> +  union {
> +    /**
> +     * @brief This field is a Red-Black Tree Node structure and allows
> this to
> +     * be placed on Red-Black Trees for set management.
> +     */
> +    RBTree_Node RBTree;
> +
> +    /**
> +     * @brief This field is a Chain Node structure and allows this to
> +     * be placed on Red-Black Trees for set management.
> +     */
> +    Chain_Node Chain;
> +  } Node;
> +
> +#if defined(RTEMS_SMP)
> +  /** @brief This field references the processor of this watchdog
> control. */
> +  struct Per_CPU_Control *cpu;
> +#endif
> +
> +  /** @brief This field is the function to invoke. */
> +  Watchdog_Service_routine_entry routine;
> +
> +  /** @brief This field is the expiration time point. */
> +  uint64_t expire;
> +};
>
>  /**
>   * @brief The watchdog ticks counter.
> diff --git a/cpukit/score/include/rtems/score/watchdogimpl.h
> b/cpukit/score/include/rtems/score/watchdogimpl.h
> index 49ac2a1..0f6947f 100644
> --- a/cpukit/score/include/rtems/score/watchdogimpl.h
> +++ b/cpukit/score/include/rtems/score/watchdogimpl.h
> @@ -21,9 +21,11 @@
>
>  #include <rtems/score/watchdog.h>
>  #include <rtems/score/assert.h>
> -#include <rtems/score/chainimpl.h>
>  #include <rtems/score/isrlock.h>
>  #include <rtems/score/percpu.h>
> +#include <rtems/score/rbtreeimpl.h>
> +
> +#include <sys/timespec.h>
>
>  #ifdef __cplusplus
>  extern "C" {
> @@ -35,241 +37,116 @@ extern "C" {
>   */
>
>  /**
> - * @brief Watchdog initializer for static initialization.
> - *
> - * @see _Watchdog_Initialize().
> - */
> -#define WATCHDOG_INITIALIZER( routine, id, user_data ) \
> -  { \
> -    { NULL, NULL }, \
> -    WATCHDOG_INACTIVE, \
> -    0, 0, 0, 0, \
> -    ( routine ), ( id ), ( user_data ) \
> -  }
> -
> -/**
> - * @brief Iterator item to synchronize concurrent insert, remove and
> tickle
> - * operations.
> + * @brief Watchdog states.
>   */
> -typedef struct {
> +typedef enum {
>    /**
> -   * @brief A node for a Watchdog_Header::Iterators chain.
> +   * @brief The watchdog is scheduled and a black node in the red-black
> tree.
>     */
> -  Chain_Node Node;
> +  WATCHDOG_SCHEDULED_BLACK,
>
>    /**
> -   * @brief The current delta interval of the new watchdog to insert.
> +   * @brief The watchdog is scheduled and a black node in the red-black
> tree.
>     */
> -  Watchdog_Interval delta_interval;
> +  WATCHDOG_SCHEDULED_RED,
>
>    /**
> -   * @brief The current watchdog of the chain on the way to insert the new
> -   * watchdog.
> +   * @brief The watchdog is inactive.
>     */
> -  Chain_Node *current;
> -} Watchdog_Iterator;
> -
> -/**
> - * @brief Watchdog header.
> - */
> -typedef struct {
> -  /**
> -   * @brief ISR lock to protect this watchdog chain.
> -   */
> -  ISR_LOCK_MEMBER( Lock )
> +  WATCHDOG_INACTIVE,
>
>    /**
> -   * @brief The chain of active or transient watchdogs.
> -   */
> -  Chain_Control Watchdogs;
> -
> -  /**
> -   * @brief Currently active iterators.
> +   * @brief The watchdog is on a chain of pending watchdogs.
>     *
> -   * The iterators are registered in _Watchdog_Insert() and updated in
> case the
> -   * watchdog chain changes.
> +   * This state is used by the timer server for example.
>     */
> -  Chain_Control Iterators;
> -} Watchdog_Header;
> +  WATCHDOG_PENDING
> +} Watchdog_State;
>
>  /**
> - *  @brief Watchdog chain which is managed at ticks.
> + * @brief Watchdog initializer for static initialization.
>   *
> - *  This is the watchdog chain which is managed at ticks.
> - */
> -extern Watchdog_Header _Watchdog_Ticks_header;
> -
> -/**
> - *  @brief Watchdog chain which is managed at second boundaries.
> + * The processor of this watchdog is set to processor with index zero.
>   *
> - *  This is the watchdog chain which is managed at second boundaries.
> + * @see _Watchdog_Preinitialize().
>   */
> -extern Watchdog_Header _Watchdog_Seconds_header;
> -
> -RTEMS_INLINE_ROUTINE void _Watchdog_Acquire(
> -  Watchdog_Header  *header,
> -  ISR_lock_Context *lock_context
> -)
> -{
> -  _ISR_lock_ISR_disable_and_acquire( &header->Lock, lock_context );
> -}
> +#if defined(RTEMS_SMP)
> +  #define WATCHDOG_INITIALIZER( routine ) \
> +    { \
> +      { { { NULL, NULL, NULL, WATCHDOG_INACTIVE } } }, \
> +      &_Per_CPU_Information[ 0 ].per_cpu, \
> +      ( routine ), \
> +      0 \
> +    }
> +#else
> +  #define WATCHDOG_INITIALIZER( routine ) \
> +    { \
> +      { { { NULL, NULL, NULL, WATCHDOG_INACTIVE } } }, \
> +      ( routine ), \
> +      0 \
> +    }
> +#endif
>
> -RTEMS_INLINE_ROUTINE void _Watchdog_Release(
> -  Watchdog_Header  *header,
> -  ISR_lock_Context *lock_context
> +RTEMS_INLINE_ROUTINE void _Watchdog_Header_initialize(
> +  Watchdog_Header *header
>  )
>  {
> -  _ISR_lock_Release_and_ISR_enable( &header->Lock, lock_context );
> +  _RBTree_Initialize_empty( &header->Watchdogs );
> +  header->first = NULL;
>  }
>
> -RTEMS_INLINE_ROUTINE void _Watchdog_Flash(
> -  Watchdog_Header  *header,
> -  ISR_lock_Context *lock_context
> +RTEMS_INLINE_ROUTINE void _Watchdog_Header_destroy(
> +  Watchdog_Header *header
>  )
>  {
> -  _ISR_lock_Flash( &header->Lock, lock_context );
> +  /* Do nothing */
> +  (void) header;
>  }
>
>  /**
> - *  @brief Initialize the watchdog handler.
> - *
> - *  This routine initializes the watchdog handler.  The watchdog
> - *  synchronization flag is initialized and the watchdog chains are
> - *  initialized and emptied.
> - */
> -void _Watchdog_Handler_initialization( void );
> -
> -/**
>   *  @brief Performs a watchdog tick.
>   *
>   *  @param cpu The processor for this watchdog tick.
>   */
> -void _Watchdog_Tick( Per_CPU_Control *cpu );
> -
> -/**
> - *  @brief Removes @a the_watchdog from the watchdog chain.
> - *
> - *  This routine removes @a the_watchdog from the watchdog chain on which
> - *  it resides and returns the state @a the_watchdog timer was in.
> - *
> - *  @param[in] header The watchdog chain.
> - *  @param[in] the_watchdog will be removed
> - *  @retval the state in which @a the_watchdog was in when removed
> - */
> -Watchdog_States _Watchdog_Remove (
> -  Watchdog_Header  *header,
> -  Watchdog_Control *the_watchdog
> -);
> -
> -/**
> - *  @brief Adjusts the header watchdog chain in the backward direction for
> - *  units ticks.
> - *
> - *  @param[in] header The watchdog chain.
> - *  @param[in] units The units of ticks to adjust.
> - */
> -void _Watchdog_Adjust_backward(
> -  Watchdog_Header   *header,
> -  Watchdog_Interval  units
> -);
> -
> -/**
> - * @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
> -);
> +void _Watchdog_Tick( struct Per_CPU_Control *cpu );
>
> -/**
> - *  @brief Adjusts the header watchdog chain in the forward direction for
> units
> - *  ticks.
> - *
> - *  This may lead to several _Watchdog_Tickle() invocations.
> - *
> - *  @param[in] header The watchdog chain.
> - *  @param[in] units The units of ticks to adjust.
> - */
> -void _Watchdog_Adjust_forward(
> -  Watchdog_Header   *header,
> -  Watchdog_Interval  units
> -);
> +RTEMS_INLINE_ROUTINE Watchdog_State _Watchdog_Get_state(
> +  const Watchdog_Control *the_watchdog
> +)
> +{
> +  return RB_COLOR( &the_watchdog->Node.RBTree, Node );
> +}
>
> -/**
> - * @brief Adjusts the watchdogs in forward direction 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] units The units of ticks to adjust.
> - * @param[in] lock_context The lock context.
> - *
> - * @see _Watchdog_Adjust_forward().
> - */
> -void _Watchdog_Adjust_forward_locked(
> -  Watchdog_Header   *header,
> -  Watchdog_Interval  units,
> -  ISR_lock_Context  *lock_context
> -);
> +RTEMS_INLINE_ROUTINE void _Watchdog_Set_state(
> +  Watchdog_Control *the_watchdog,
> +  Watchdog_State    state
> +)
> +{
> +  RB_COLOR( &the_watchdog->Node.RBTree, Node ) = state;
> +}
>
> -/**
> - *  @brief Inserts @a the_watchdog into the @a header watchdog chain
> - *  for a time of @a units.
> - *
> - *  This routine inserts @a the_watchdog into the @a header watchdog chain
> - *  for a time of @a units.
> - *  Update the delta interval counters.
> - *
> - *  @param[in] header is @a the_watchdog list to insert @a the_watchdog on
> - *  @param[in] the_watchdog is the watchdog to insert
> - */
> -void _Watchdog_Insert (
> -  Watchdog_Header  *header,
> -  Watchdog_Control *the_watchdog
> -);
> +RTEMS_INLINE_ROUTINE Per_CPU_Control *_Watchdog_Get_CPU(
> +  const Watchdog_Control *the_watchdog
> +)
> +{
> +#if defined(RTEMS_SMP)
> +  return the_watchdog->cpu;
> +#else
> +  return _Per_CPU_Get_by_index( 0 );
> +#endif
> +}
>
> -/**
> - * @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,
> +RTEMS_INLINE_ROUTINE void _Watchdog_Set_CPU(
>    Watchdog_Control *the_watchdog,
> -  ISR_lock_Context *lock_context
> -);
> -
> -/**
> - *  @brief This routine is invoked at appropriate intervals to update
> - *  the @a header watchdog chain.
> - *
> - *  This routine is invoked at appropriate intervals to update
> - *  the @a header watchdog chain.
> - *  This routine decrements the delta counter in response to a tick.
> - *
> - *  @param[in] header is the watchdog chain to tickle
> - */
> -void _Watchdog_Tickle (
> -  Watchdog_Header *header
> -);
> +  Per_CPU_Control  *cpu
> +)
> +{
> +#if defined(RTEMS_SMP)
> +  the_watchdog->cpu = cpu;
> +#else
> +  (void) cpu;
> +#endif
> +}
>
>  /**
>   * @brief Pre-initializes a watchdog.
> @@ -280,228 +157,261 @@ void _Watchdog_Tickle (
>   * @param[in] the_watchdog The uninitialized watchdog.
>   */
>  RTEMS_INLINE_ROUTINE void _Watchdog_Preinitialize(
> -  Watchdog_Control *the_watchdog
> +  Watchdog_Control *the_watchdog,
> +  Per_CPU_Control  *cpu
>  )
>  {
> -  the_watchdog->state = WATCHDOG_INACTIVE;
> +  _Watchdog_Set_CPU( the_watchdog, cpu );
> +  _Watchdog_Set_state( the_watchdog, WATCHDOG_INACTIVE );
> +
>  #if defined(RTEMS_DEBUG)
>    the_watchdog->routine = NULL;
> -  the_watchdog->id = 0;
> -  the_watchdog->user_data = NULL;
> +  the_watchdog->expire = 0;
>  #endif
>  }
>
>  /**
> - * This routine initializes the specified watchdog.  The watchdog is
> - * made inactive, the watchdog id and handler routine are set to the
> - * specified values.
> + * @brief Initializes a watchdog with a new service routine.
> + *
> + * The watchdog must be inactive.
>   */
> -
>  RTEMS_INLINE_ROUTINE void _Watchdog_Initialize(
>    Watchdog_Control               *the_watchdog,
> -  Watchdog_Service_routine_entry  routine,
> -  Objects_Id                      id,
> -  void                           *user_data
> +  Watchdog_Service_routine_entry  routine
>  )
>  {
> -  _Assert( the_watchdog->state == WATCHDOG_INACTIVE );
> -  the_watchdog->routine   = routine;
> -  the_watchdog->id        = id;
> -  the_watchdog->user_data = user_data;
> +  _Assert( _Watchdog_Get_state( the_watchdog ) == WATCHDOG_INACTIVE );
> +  the_watchdog->routine = routine;
>  }
>
> -/**
> - * This routine returns true if the watchdog timer is in the ACTIVE
> - * state, and false otherwise.
> - */
> -
> -RTEMS_INLINE_ROUTINE bool _Watchdog_Is_active(
> -  Watchdog_Control *the_watchdog
> -)
> -{
> -
> -  return ( the_watchdog->state == WATCHDOG_ACTIVE );
> +void _Watchdog_Do_tickle(
> +  Watchdog_Header  *header,
> +  uint64_t          now,
> +#if defined(RTEMS_SMP)
> +  ISR_lock_Control *lock,
> +#endif
> +  ISR_lock_Context *lock_context
> +);
>
> -}
> +#if defined(RTEMS_SMP)
> +  #define _Watchdog_Tickle( header, now, lock, lock_context ) \
> +    _Watchdog_Do_tickle( header, now, lock, lock_context )
> +#else
> +  #define _Watchdog_Tickle( header, now, lock, lock_context ) \
> +    _Watchdog_Do_tickle( header, now, lock_context )
> +#endif
>
>  /**
> - * This routine activates THE_WATCHDOG timer which is already
> - * on a watchdog chain.
> + * @brief Inserts a watchdog into the set of scheduled watchdogs
> according to
> + * the specified expiration time.
> + *
> + * The watchdog must be inactive.
>   */
> +void _Watchdog_Insert(
> +  Watchdog_Header  *header,
> +  Watchdog_Control *the_watchdog,
> +  uint64_t          expire
> +);
>
> -RTEMS_INLINE_ROUTINE void _Watchdog_Activate(
> +/**
> + * @brief In case the watchdog is scheduled, then it is removed from the
> set of
> + * scheduled watchdogs.
> + *
> + * The watchdog must be initialized before this call.
> + */
> +void _Watchdog_Remove(
> +  Watchdog_Header  *header,
>    Watchdog_Control *the_watchdog
> -)
> -{
> -
> -  the_watchdog->state = WATCHDOG_ACTIVE;
> -
> -}
> +);
>
>  /**
> - * This routine is invoked at each clock tick to update the ticks
> - * watchdog chain.
> + * @brief In case the watchdog is scheduled, then it is removed from the
> set of
> + * scheduled watchdogs.
> + *
> + * The watchdog must be initialized before this call.
> + *
> + * @retval 0 The now time is greater than or equal to the expiration time
> of
> + * the watchdog.
> + * @retval other The difference of the now and expiration time.
>   */
> -
> -RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_ticks( void )
> +RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Cancel(
> +  Watchdog_Header  *header,
> +  Watchdog_Control *the_watchdog,
> +  uint64_t          now
> +)
>  {
> +  uint64_t expire;
> +  uint64_t remaining;
>
> -  _Watchdog_Tickle( &_Watchdog_Ticks_header );
> -
> -}
> -
> -/**
> - * This routine is invoked at each clock tick to update the seconds
> - * watchdog chain.
> - */
> +  expire = the_watchdog->expire;
>
> -RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_seconds( void )
> -{
> +  if ( now < expire ) {
> +    remaining = expire - now;
> +  } else {
> +    remaining = 0;
> +  }
>
> -  _Watchdog_Tickle( &_Watchdog_Seconds_header );
> +  _Watchdog_Remove( header, the_watchdog );
>
> +  return remaining;
>  }
>
> -/**
> - * This routine inserts THE_WATCHDOG into the ticks watchdog chain
> - * for a time of UNITS ticks.  The INSERT_MODE indicates whether
> - * THE_WATCHDOG is to be activated automatically or later, explicitly
> - * by the caller.
> - */
> -
> -RTEMS_INLINE_ROUTINE void _Watchdog_Insert_ticks(
> -  Watchdog_Control      *the_watchdog,
> -  Watchdog_Interval      units
> +RTEMS_INLINE_ROUTINE bool _Watchdog_Is_scheduled(
> +  const Watchdog_Control *the_watchdog
>  )
>  {
> -
> -  the_watchdog->initial = units;
> -
> -  _Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
> -
> +  return _Watchdog_Get_state( the_watchdog ) < WATCHDOG_INACTIVE;
>  }
>
> -/**
> - * This routine inserts THE_WATCHDOG into the seconds watchdog chain
> - * for a time of UNITS seconds.  The INSERT_MODE indicates whether
> - * THE_WATCHDOG is to be activated automatically or later, explicitly
> - * by the caller.
> - */
> -
> -RTEMS_INLINE_ROUTINE void _Watchdog_Insert_seconds(
> -  Watchdog_Control      *the_watchdog,
> -  Watchdog_Interval      units
> +RTEMS_INLINE_ROUTINE void _Watchdog_Next_first(
> +  Watchdog_Header  *header,
> +  Watchdog_Control *the_watchdog
>  )
>  {
> +  RBTree_Node *node = _RBTree_Right( &the_watchdog->Node.RBTree );
>
> -  the_watchdog->initial = units;
> +  if ( node != NULL ) {
> +    RBTree_Node *left;
>
> -  _Watchdog_Insert( &_Watchdog_Seconds_header, the_watchdog );
> +    while ( ( left = _RBTree_Left( node ) ) != NULL ) {
> +      node = left;
> +    }
>
> +    header->first = node;
> +  } else {
> +    header->first = _RBTree_Parent( &the_watchdog->Node.RBTree );
> +  }
>  }
>
> -RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_ticks(
> -  Watchdog_Control *the_watchdog
> +RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_seconds(
> +  uint32_t seconds
>  )
>  {
> -  return _Watchdog_Remove( &_Watchdog_Ticks_header, the_watchdog );
> -}
> +  uint64_t ticks = seconds;
>
> -RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_seconds(
> -  Watchdog_Control *the_watchdog
> -)
> -{
> -  return _Watchdog_Remove( &_Watchdog_Seconds_header, the_watchdog );
> -}
> +  ticks <<= 30;
>
> -/**
> - * This routine resets THE_WATCHDOG timer to its state at INSERT
> - * time.  This routine is valid only on interval watchdog timers
> - * and is used to make an interval watchdog timer fire "every" so
> - * many ticks.
> - */
> +  return ticks;
> +}
>
> -RTEMS_INLINE_ROUTINE void _Watchdog_Reset_ticks(
> -  Watchdog_Control *the_watchdog
> +RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_timespec(
> +  const struct timespec *ts
>  )
>  {
> +  uint64_t ticks = (uint64_t) ts->tv_sec;
>
> -  _Watchdog_Remove_ticks( the_watchdog );
> +  _Assert( ticks < 0x400000000 );
> +  _Assert( ts->tv_nsec >= 0 );
> +  _Assert( ts->tv_nsec < 1000000000 );
>
> -  _Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
> +  ticks <<= 30;
> +  ticks |= ts->tv_nsec;
>
> +  return ticks;
>  }
>
> -/**
> - * This routine returns a pointer to the watchdog timer following
> - * THE_WATCHDOG on the watchdog chain.
> - */
> +#define _Watchdog_Per_CPU_acquire( cpu, lock_context ) \
> +  _ISR_lock_Acquire( &( cpu )->Watchdog.Lock, lock_context )
>
> -RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Next(
> -  Watchdog_Control *the_watchdog
> +#define _Watchdog_Per_CPU_release( cpu, lock_context ) \
> +  _ISR_lock_Release( &( cpu )->Watchdog.Lock, lock_context )
> +
> +RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_insert_relative(
> +  Watchdog_Control *the_watchdog,
> +  Per_CPU_Control  *cpu,
> +  uint32_t          ticks
>  )
>  {
> +  ISR_lock_Context lock_context;
>
> -  return ( (Watchdog_Control *) the_watchdog->Node.next );
> +  _Watchdog_Set_CPU( the_watchdog, cpu );
>
> +  _Watchdog_Per_CPU_acquire( cpu, &lock_context );
> +  _Watchdog_Insert(
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +    the_watchdog,
> +    cpu->Watchdog.ticks + ticks
> +  );
> +  _Watchdog_Per_CPU_release( cpu, &lock_context );
>  }
>
> -/**
> - * This routine returns a pointer to the watchdog timer preceding
> - * THE_WATCHDOG on the watchdog chain.
> - */
> -
> -RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Previous(
> -  Watchdog_Control *the_watchdog
> +RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_insert_absolute(
> +  Watchdog_Control *the_watchdog,
> +  Per_CPU_Control  *cpu,
> +  uint64_t          expire
>  )
>  {
> +  ISR_lock_Context lock_context;
>
> -  return ( (Watchdog_Control *) the_watchdog->Node.previous );
> +  _Watchdog_Set_CPU( the_watchdog, cpu );
>
> +  _Watchdog_Per_CPU_acquire( cpu, &lock_context );
> +  _Watchdog_Insert(
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_ABSOLUTE ],
> +    the_watchdog,
> +    expire
> +  );
> +  _Watchdog_Per_CPU_release( cpu, &lock_context );
>  }
>
> -/**
> - * This routine returns a pointer to the first watchdog timer
> - * on the watchdog chain HEADER.
> - */
> -
> -RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_First(
> -  Watchdog_Header *header
> +RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove(
> +  Watchdog_Control *the_watchdog,
> +  Per_CPU_Control  *cpu,
> +  Watchdog_Header  *header
>  )
>  {
> -
> -  return ( (Watchdog_Control *) _Chain_First( &header->Watchdogs ) );
> -
> +  ISR_lock_Context lock_context;
> +
> +  _Watchdog_Per_CPU_acquire( cpu, &lock_context );
> +  _Watchdog_Remove(
> +    header,
> +    the_watchdog
> +  );
> +  _Watchdog_Per_CPU_release( cpu, &lock_context );
>  }
>
> -/**
> - * This routine returns a pointer to the last watchdog timer
> - * on the watchdog chain HEADER.
> - */
> -
> -RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Last(
> -  Watchdog_Header *header
> +RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_relative(
> +  Watchdog_Control *the_watchdog
>  )
>  {
> -
> -  return ( (Watchdog_Control *) _Chain_Last( &header->Watchdogs ) );
> -
> +  Per_CPU_Control *cpu;
> +
> +  cpu = _Watchdog_Get_CPU( the_watchdog );
> +  _Watchdog_Per_CPU_remove(
> +    the_watchdog,
> +    cpu,
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ]
> +  );
>  }
>
> -RTEMS_INLINE_ROUTINE bool _Watchdog_Is_empty(
> -  const Watchdog_Header *header
> +RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_absolute(
> +  Watchdog_Control *the_watchdog
>  )
>  {
> -  return _Chain_Is_empty( &header->Watchdogs );
> +  Per_CPU_Control *cpu;
> +
> +  cpu = _Watchdog_Get_CPU( the_watchdog );
> +  _Watchdog_Per_CPU_remove(
> +    the_watchdog,
> +    cpu,
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_ABSOLUTE ]
> +  );
>  }
>
> -RTEMS_INLINE_ROUTINE void _Watchdog_Header_initialize(
> -  Watchdog_Header *header
> +RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_tickle_absolute(
> +  Per_CPU_Control *cpu,
> +  uint64_t         now
>  )
>  {
> -  _ISR_lock_Initialize( &header->Lock, "Watchdog" );
> -  _Chain_Initialize_empty( &header->Watchdogs );
> -  _Chain_Initialize_empty( &header->Iterators );
> +  ISR_lock_Context lock_context;
> +
> +  _ISR_lock_ISR_disable_and_acquire( &cpu->Watchdog.Lock, &lock_context );
> +  _Watchdog_Tickle(
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_ABSOLUTE ],
> +    now,
> +    &cpu->Watchdog.Lock,
> +    &lock_context
> +  );
>  }
>
>  /** @} */
> diff --git a/cpukit/score/src/condition.c b/cpukit/score/src/condition.c
> index 22c2a9b..4206819 100644
> --- a/cpukit/score/src/condition.c
> +++ b/cpukit/score/src/condition.c
> @@ -282,7 +282,7 @@ static int _Condition_Wake( struct _Condition_Control
> *_condition, int count )
>
>        next = _Chain_Next( node );
>        thread = THREAD_CHAIN_NODE_TO_THREAD( node );
> -      _Watchdog_Remove_ticks( &thread->Timer );
> +      _Thread_Timer_remove( thread );
>        _Thread_Unblock( thread );
>
>        node = next;
> diff --git a/cpukit/score/src/coretodset.c b/cpukit/score/src/coretodset.c
> index 3230179..b2efc07 100644
> --- a/cpukit/score/src/coretodset.c
> +++ b/cpukit/score/src/coretodset.c
> @@ -26,30 +26,26 @@ void _TOD_Set_with_timestamp(
>    const Timestamp_Control *tod_as_timestamp
>  )
>  {
> -  struct timespec ts;
> -  uint32_t nanoseconds;
> -  Watchdog_Interval seconds_next;
> -  Watchdog_Interval seconds_now;
> -  Watchdog_Header *header;
> +  struct timespec tod_as_timespec;
> +  uint64_t        tod_as_ticks;
> +  uint32_t        cpu_count;
> +  uint32_t        cpu_index;
>
> -  _Timestamp_To_timespec( tod_as_timestamp, &ts );
> -  nanoseconds = ts.tv_nsec;
> -  seconds_next = ts.tv_sec;
> +  _Timestamp_To_timespec( tod_as_timestamp, &tod_as_timespec );
>
>    _Thread_Disable_dispatch();
>
> -  seconds_now = _TOD_Seconds_since_epoch();
> +  _Timecounter_Set_clock( &tod_as_timespec );
>
> -  _Timecounter_Set_clock( &ts );
> +  tod_as_ticks = _Watchdog_Ticks_from_timespec( &tod_as_timespec );
> +  cpu_count = _SMP_Get_processor_count();
>
> -  header = &_Watchdog_Seconds_header;
> +  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
> +    Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
>
> -  if ( seconds_next < seconds_now )
> -    _Watchdog_Adjust_backward( header, seconds_now - seconds_next );
> -  else
> -    _Watchdog_Adjust_forward( header, seconds_next - seconds_now );
> +    _Watchdog_Per_CPU_tickle_absolute( cpu, tod_as_ticks );
> +  }
>
> -  _TOD.seconds_trigger = nanoseconds;
>    _TOD.is_set = true;
>
>    _Thread_Enable_dispatch();
> diff --git a/cpukit/score/src/coretodtickle.c
> b/cpukit/score/src/coretodtickle.c
> deleted file mode 100644
> index 3d7c71e..0000000
> --- a/cpukit/score/src/coretodtickle.c
> +++ /dev/null
> @@ -1,36 +0,0 @@
> -/**
> - * @file
> - *
> - * @brief Increments time of day at each clock tick
> - *
> - * @ingroup ScoreTOD
> - */
> -
> -/*  COPYRIGHT (c) 1989-2014.
> - *  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/todimpl.h>
> -#include <rtems/score/watchdogimpl.h>
> -#include <rtems/config.h>
> -
> -void _TOD_Tickle_ticks( void )
> -{
> -  /* Update the counter of ticks since boot */
> -  _Watchdog_Ticks_since_boot += 1;
> -
> -  _TOD.seconds_trigger += rtems_configuration_get_nanoseconds_per_tick();
> -  if ( _TOD.seconds_trigger >= 1000000000UL ) {
> -    _TOD.seconds_trigger -= 1000000000UL;
> -    _Watchdog_Tickle_seconds();
> -  }
> -}
> -
> diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c
> index e56c292..316a16f 100644
> --- a/cpukit/score/src/kern_tc.c
> +++ b/cpukit/score/src/kern_tc.c
> @@ -1971,6 +1971,7 @@ tc_ticktock(int cnt)
>                 return;
>         count = 0;
>  #else /* __rtems__ */
> +#include <rtems/score/smp.h>
>  void
>  _Timecounter_Tick(void)
>  {
> @@ -2021,7 +2022,7 @@ _Timecounter_Tick_simple(uint32_t delta, uint32_t
> offset,
>
>         _Timecounter_Release(lock_context);
>
> -       _Watchdog_Tick(_Per_CPU_Get());
> +       _Watchdog_Tick(_Per_CPU_Get_snapshot());
>  }
>  #endif /* __rtems__ */
>
> diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
> index 9d9507d..85256b0 100644
> --- a/cpukit/score/src/smp.c
> +++ b/cpukit/score/src/smp.c
> @@ -87,6 +87,7 @@ void _SMP_Handler_initialize( void )
>    for ( cpu_index = 0 ; cpu_index < cpu_max; ++cpu_index ) {
>      Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
>
> +    _ISR_lock_Initialize( &cpu->Watchdog.Lock, "Watchdog" );
>      _SMP_ticket_lock_Initialize( &cpu->Lock );
>      _SMP_lock_Stats_initialize( &cpu->Lock_stats, "Per-CPU" );
>    }
> diff --git a/cpukit/score/src/threadinitialize.c
> b/cpukit/score/src/threadinitialize.c
> index a49406f..0b5fd3a 100644
> --- a/cpukit/score/src/threadinitialize.c
> +++ b/cpukit/score/src/threadinitialize.c
> @@ -160,6 +160,10 @@ bool _Thread_Initialize(
>    the_thread->Start.budget_algorithm = budget_algorithm;
>    the_thread->Start.budget_callout   = budget_callout;
>
> +  _ISR_lock_Initialize( &the_thread->Timer.Lock, "Thread Timer" );
> +  the_thread->Timer.header = &cpu->Watchdog.Header[
> PER_CPU_WATCHDOG_RELATIVE ];
> +  _Watchdog_Preinitialize( &the_thread->Timer.Watchdog, cpu );
> +
>    switch ( budget_algorithm ) {
>      case THREAD_CPU_BUDGET_ALGORITHM_NONE:
>      case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE:
> diff --git a/cpukit/score/src/threadqenqueue.c
> b/cpukit/score/src/threadqenqueue.c
> index 960783c..07618fc 100644
> --- a/cpukit/score/src/threadqenqueue.c
> +++ b/cpukit/score/src/threadqenqueue.c
> @@ -35,7 +35,7 @@
>
>  static void _Thread_queue_Unblock( Thread_Control *the_thread )
>  {
> -  _Watchdog_Remove_ticks( &the_thread->Timer );
> +  _Thread_Timer_remove( the_thread );
>    _Thread_Unblock( the_thread );
>
>  #if defined(RTEMS_MULTIPROCESSING)
> @@ -84,8 +84,12 @@ void _Thread_queue_Enqueue_critical(
>     */
>    if ( timeout != WATCHDOG_NO_TIMEOUT ) {
>      _Thread_Wait_set_timeout_code( the_thread, timeout_code );
> -    _Watchdog_Initialize( &the_thread->Timer, _Thread_Timeout, 0,
> the_thread );
> -    _Watchdog_Insert_ticks( &the_thread->Timer, timeout );
> +    _Thread_Timer_insert_relative(
> +      the_thread,
> +      cpu_self,
> +      _Thread_Timeout,
> +      timeout
> +    );
>    }
>
>    success = _Thread_Wait_flags_try_change(
> diff --git a/cpukit/score/src/threadrestart.c
> b/cpukit/score/src/threadrestart.c
> index 03b1fba..d366f97 100644
> --- a/cpukit/score/src/threadrestart.c
> +++ b/cpukit/score/src/threadrestart.c
> @@ -84,7 +84,7 @@ static void _Thread_Make_zombie( Thread_Control
> *the_thread )
>
>    _Thread_Set_state( the_thread, STATES_ZOMBIE );
>    _Thread_queue_Extract_with_proxy( the_thread );
> -  _Watchdog_Remove_ticks( &the_thread->Timer );
> +  _Thread_Timer_remove( the_thread );
>
>    _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );
>    _Chain_Append_unprotected( &zombies->Chain, &the_thread->Object.Node );
> @@ -191,7 +191,9 @@ static void _Thread_Start_life_change_for_executing(
>    Thread_Control *executing
>  )
>  {
> -  _Assert( executing->Timer.state == WATCHDOG_INACTIVE );
> +  _Assert(
> +    _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE
> +  );
>    _Assert(
>      executing->current_state == STATES_READY
>        || executing->current_state == STATES_SUSPENDED
> @@ -246,7 +248,9 @@ void _Thread_Life_action_handler(
>        /* Someone deleted us in the mean-time */
>        _Thread_Start_life_change_for_executing( executing );
>      } else {
> -      _Assert( executing->Timer.state == WATCHDOG_INACTIVE );
> +      _Assert(
> +        _Watchdog_Get_state( &executing->Timer.Watchdog ) ==
> WATCHDOG_INACTIVE
> +      );
>        _Assert(
>          executing->current_state == STATES_READY
>            || executing->current_state == STATES_SUSPENDED
> @@ -274,7 +278,7 @@ static void _Thread_Start_life_change(
>
>    _Thread_Set_state( the_thread, STATES_RESTARTING );
>    _Thread_queue_Extract_with_proxy( the_thread );
> -  _Watchdog_Remove_ticks( &the_thread->Timer );
> +  _Thread_Timer_remove( the_thread );
>    _Thread_Change_priority(
>      the_thread,
>      priority,
> diff --git a/cpukit/score/src/threadtimeout.c
> b/cpukit/score/src/threadtimeout.c
> index 8ecaebd..59f6bd9 100644
> --- a/cpukit/score/src/threadtimeout.c
> +++ b/cpukit/score/src/threadtimeout.c
> @@ -33,7 +33,7 @@ static void _Thread_Do_timeout( Thread_Control
> *the_thread )
>    _Thread_Lock_restore_default( the_thread );
>  }
>
> -void _Thread_Timeout( Objects_Id id, void *arg )
> +void _Thread_Timeout( Watchdog_Control *watchdog )
>  {
>    Thread_Control    *the_thread;
>    void              *thread_lock;
> @@ -41,7 +41,7 @@ void _Thread_Timeout( Objects_Id id, void *arg )
>    Thread_Wait_flags  wait_flags;
>    bool               unblock;
>
> -  the_thread = arg;
> +  the_thread = RTEMS_CONTAINER_OF( watchdog, Thread_Control,
> Timer.Watchdog );
>    thread_lock = _Thread_Lock_acquire( the_thread, &lock_context );
>
>    wait_flags = _Thread_Wait_flags_get( the_thread );
> diff --git a/cpukit/score/src/watchdog.c b/cpukit/score/src/watchdog.c
> deleted file mode 100644
> index 8d172fb..0000000
> --- a/cpukit/score/src/watchdog.c
> +++ /dev/null
> @@ -1,36 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Watchdog Handler Initialization
> - *  @ingroup ScoreWatchdog
> - */
> -
> -/*
> - *  Watchdog Handler
> - *
> - *
> - *  COPYRIGHT (c) 1989-1999.
> - *  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>
> -
> -Watchdog_Header _Watchdog_Ticks_header;
> -
> -Watchdog_Header _Watchdog_Seconds_header;
> -
> -void _Watchdog_Handler_initialization( void )
> -{
> -  _Watchdog_Ticks_since_boot = 0;
> -
> -  _Watchdog_Header_initialize( &_Watchdog_Ticks_header );
> -  _Watchdog_Header_initialize( &_Watchdog_Seconds_header );
> -}
> diff --git a/cpukit/score/src/watchdogadjust.c
> b/cpukit/score/src/watchdogadjust.c
> deleted file mode 100644
> index 32b5f79..0000000
> --- a/cpukit/score/src/watchdogadjust.c
> +++ /dev/null
> @@ -1,80 +0,0 @@
> -/**
> - *  @file
> - *
> - *  @brief Watchdog Adjust
> - *  @ingroup ScoreWatchdog
> - */
> -
> -/*
> - *  COPYRIGHT (c) 1989-1999.
> - *  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>
> -
> -void _Watchdog_Adjust_backward_locked(
> -  Watchdog_Header   *header,
> -  Watchdog_Interval  units
> -)
> -{
> -  if ( !_Watchdog_Is_empty( header ) ) {
> -     _Watchdog_First( header )->delta_interval += units;
> -  }
> -}
> -
> -void _Watchdog_Adjust_backward(
> -  Watchdog_Header   *header,
> -  Watchdog_Interval  units
> -)
> -{
> -  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 );
> -
> -    if ( units < first->delta_interval ) {
> -      first->delta_interval -= units;
> -      break;
> -    } else {
> -      units -= first->delta_interval;
> -      first->delta_interval = 1;
> -
> -      _Watchdog_Release( header, lock_context );
> -
> -      _Watchdog_Tickle( header );
> -
> -      _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/watchdoginsert.c
> b/cpukit/score/src/watchdoginsert.c
> index db15f55..22fc7a5 100644
> --- a/cpukit/score/src/watchdoginsert.c
> +++ b/cpukit/score/src/watchdoginsert.c
> @@ -1,17 +1,22 @@
>  /**
> - * @file
> + * @file
>   *
>   * @brief Watchdog Insert
>   * @ingroup ScoreWatchdog
>   */
> -
> +
>  /*
> - *  COPYRIGHT (c) 1989-1999.
> - *  On-Line Applications Research Corporation (OAR).
> + * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
> + *
> + *  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
> - *  http://www.rtems.org/license/LICENSE.
> + * 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
> @@ -20,106 +25,41 @@
>
>  #include <rtems/score/watchdogimpl.h>
>
> -static void _Watchdog_Insert_fixup(
> -  Watchdog_Header   *header,
> -  Watchdog_Control  *the_watchdog,
> -  Watchdog_Interval  delta,
> -  Watchdog_Control  *next_watchdog,
> -  Watchdog_Interval  delta_next
> -)
> -{
> -  const Chain_Node *iterator_tail;
> -  Chain_Node       *iterator_node;
> -
> -  next_watchdog->delta_interval = delta_next - delta;
> -
> -  iterator_node = _Chain_First( &header->Iterators );
> -  iterator_tail = _Chain_Immutable_tail( &header->Iterators );
> -
> -  while ( iterator_node != iterator_tail ) {
> -    Watchdog_Iterator *iterator;
> -
> -    iterator = (Watchdog_Iterator *) iterator_node;
> -
> -    if ( iterator->current == &next_watchdog->Node ) {
> -      iterator->current = &the_watchdog->Node;
> -    }
> -
> -    iterator_node = _Chain_Next( iterator_node );
> -  }
> -}
> -
> -void _Watchdog_Insert_locked(
> +void _Watchdog_Insert(
>    Watchdog_Header  *header,
>    Watchdog_Control *the_watchdog,
> -  ISR_lock_Context *lock_context
> +  uint64_t          expire
>  )
>  {
> -  if ( the_watchdog->state == WATCHDOG_INACTIVE ) {
> -    Watchdog_Iterator  iterator;
> -    Chain_Node        *current;
> -    Chain_Node        *next;
> -    Watchdog_Interval  delta;
> -
> -    the_watchdog->state = WATCHDOG_BEING_INSERTED;
> -
> -    _Chain_Append_unprotected( &header->Iterators, &iterator.Node );
> -
> -    delta = the_watchdog->initial;
> -    current = _Chain_Head( &header->Watchdogs );
> +  RBTree_Node **link;
> +  RBTree_Node  *parent;
> +  RBTree_Node  *old_first;
> +  RBTree_Node  *new_first;
>
> -    while (
> -      ( next = _Chain_Next( current ) ) != _Chain_Tail(
> &header->Watchdogs )
> -    ) {
> -      Watchdog_Control  *next_watchdog;
> -      Watchdog_Interval  delta_next;
> +  _Assert( _Watchdog_Get_state( the_watchdog ) == WATCHDOG_INACTIVE );
>
> -      next_watchdog = (Watchdog_Control *) next;
> -      delta_next = next_watchdog->delta_interval;
> +  link = _RBTree_Root_reference( &header->Watchdogs );
> +  parent = NULL;
> +  old_first = header->first;
> +  new_first = &the_watchdog->Node.RBTree;
>
> -      if ( delta < delta_next ) {
> -        _Watchdog_Insert_fixup(
> -          header,
> -          the_watchdog,
> -          delta,
> -          next_watchdog,
> -          delta_next
> -        );
> -        break;
> -      }
> +  the_watchdog->expire = expire;
>
> -      iterator.delta_interval = delta - delta_next;
> -      iterator.current = next;
> +  while ( *link != NULL ) {
> +    Watchdog_Control *parent_watchdog;
>
> -      _Watchdog_Flash( header, lock_context );
> +    parent = *link;
> +    parent_watchdog = (Watchdog_Control *) parent;
>
> -      if ( the_watchdog->state != WATCHDOG_BEING_INSERTED ) {
> -        goto abort_insert;
> -      }
> -
> -      delta = iterator.delta_interval;
> -      current = iterator.current;
> +    if ( expire < parent_watchdog->expire ) {
> +      link = _RBTree_Left_reference( parent );
> +    } else {
> +      link = _RBTree_Right_reference( parent );
> +      new_first = old_first;
>      }
> -
> -    the_watchdog->delta_interval = delta;
> -    the_watchdog->start_time = _Watchdog_Ticks_since_boot;
> -    _Watchdog_Activate( the_watchdog );
> -    _Chain_Insert_unprotected( current, &the_watchdog->Node );
> -
> -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 );
> +  header->first = new_first;
> +  _RBTree_Add_child( &the_watchdog->Node.RBTree, parent, link );
> +  _RBTree_Insert_color( &header->Watchdogs, &the_watchdog->Node.RBTree );
>  }
> diff --git a/cpukit/score/src/watchdogremove.c
> b/cpukit/score/src/watchdogremove.c
> index 2aa72a4..2605a67 100644
> --- a/cpukit/score/src/watchdogremove.c
> +++ b/cpukit/score/src/watchdogremove.c
> @@ -1,17 +1,22 @@
>  /**
>   * @file
>   *
> - * @brief Remove Watchdog from List
> + * @brief Remove Watchdog
>   * @ingroup ScoreWatchdog
>   */
>
>  /*
> - *  COPYRIGHT (c) 1989-1999.
> - *  On-Line Applications Research Corporation (OAR).
> + * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
>   *
> - *  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.
> + *  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
> + * http://www.rtems.org/license/LICENSE.
>   */
>
>  #if HAVE_CONFIG_H
> @@ -19,161 +24,18 @@
>  #endif
>
>  #include <rtems/score/watchdogimpl.h>
> -#include <rtems/score/assert.h>
> -
> -static void _Watchdog_Remove_it(
> -  Watchdog_Header   *header,
> -  Watchdog_Control  *the_watchdog
> -)
> -{
> -  Chain_Node        *next;
> -  Watchdog_Interval  delta;
> -  const Chain_Node  *iterator_tail;
> -  Chain_Node        *iterator_node;
> -
> -  _Assert( the_watchdog->state == WATCHDOG_ACTIVE );
> -
> -  the_watchdog->state = WATCHDOG_INACTIVE;
> -  the_watchdog->stop_time = _Watchdog_Ticks_since_boot;
> -
> -  next = _Chain_Next( &the_watchdog->Node );
> -  delta = the_watchdog->delta_interval;
> -
> -  if ( next != _Chain_Tail( &header->Watchdogs ) ) {
> -    Watchdog_Control *next_watchdog;
> -
> -    next_watchdog = (Watchdog_Control *) next;
> -    next_watchdog->delta_interval += delta;
> -  }
> -
> -  _Chain_Extract_unprotected( &the_watchdog->Node );
> -
> -  iterator_node = _Chain_First( &header->Iterators );
> -  iterator_tail = _Chain_Immutable_tail( &header->Iterators );
> -
> -  while ( iterator_node != iterator_tail ) {
> -    Watchdog_Iterator *iterator;
> -
> -    iterator = (Watchdog_Iterator *) iterator_node;
> -
> -    if ( iterator->current == next ) {
> -      iterator->delta_interval += delta;
> -    }
> -
> -    if ( iterator->current == &the_watchdog->Node ) {
> -      Chain_Node *previous = _Chain_Previous( &the_watchdog->Node );
> -
> -      iterator->current = previous;
> -
> -      if ( previous != _Chain_Head( &header->Watchdogs ) ) {
> -        Watchdog_Control *previous_watchdog;
> -
> -        previous_watchdog = (Watchdog_Control *) previous;
> -        iterator->delta_interval += previous_watchdog->delta_interval;
> -      }
> -    }
> -
> -    iterator_node = _Chain_Next( iterator_node );
> -  }
> -}
>
> -Watchdog_States _Watchdog_Remove(
> +void _Watchdog_Remove(
>    Watchdog_Header  *header,
>    Watchdog_Control *the_watchdog
>  )
>  {
> -  ISR_lock_Context  lock_context;
> -  Watchdog_States   previous_state;
> -  Watchdog_Interval now;
> -
> -  _Watchdog_Acquire( header, &lock_context );
> -  previous_state = the_watchdog->state;
> -  switch ( previous_state ) {
> -    case WATCHDOG_INACTIVE:
> -      break;
> -
> -    case WATCHDOG_BEING_INSERTED:
> -
> -      /*
> -       *  It is not actually on the chain so just change the state and
> -       *  the Insert operation we interrupted will be aborted.
> -       */
> -      the_watchdog->state = WATCHDOG_INACTIVE;
> -      now = _Watchdog_Ticks_since_boot;
> -      the_watchdog->start_time = now;
> -      the_watchdog->stop_time = now;
> -      break;
> -
> -    case WATCHDOG_ACTIVE:
> -      _Watchdog_Remove_it( header, the_watchdog );
> -      break;
> -  }
> -
> -  _Watchdog_Release( header, &lock_context );
> -  return( previous_state );
> -}
> -
> -void _Watchdog_Tickle(
> -  Watchdog_Header *header
> -)
> -{
> -  ISR_lock_Context lock_context;
> -
> -  _Watchdog_Acquire( header, &lock_context );
> -
> -  if ( !_Watchdog_Is_empty( header ) ) {
> -    Watchdog_Control  *first;
> -    Watchdog_Interval  delta;
> -
> -    first = _Watchdog_First( header );
> -    delta = first->delta_interval;
> -
> -    /*
> -     * Although it is forbidden to insert watchdogs with a delta interval
> of
> -     * zero it is possible to observe watchdogs with a delta interval of
> zero
> -     * at this point.  For example lets have a watchdog chain of one
> watchdog
> -     * with a delta interval of one and insert a new one with an initial
> value
> -     * of one.  At the start of the insert procedure it will advance one
> step
> -     * and reduce its delta interval by one yielding zero.  Now a tick
> happens.
> -     * This will remove the watchdog on the chain and update the insert
> -     * iterator.  Now the insert operation continues and will insert the
> new
> -     * watchdog with a delta interval of zero.
> -     */
> -    if ( delta > 0 ) {
> -      --delta;
> -      first->delta_interval = delta;
> +  if ( _Watchdog_Is_scheduled( the_watchdog ) ) {
> +    if ( header->first == &the_watchdog->Node.RBTree ) {
> +      _Watchdog_Next_first( header, the_watchdog );
>      }
>
> -    while ( delta == 0 ) {
> -      bool                            run;
> -      Watchdog_Service_routine_entry  routine;
> -      Objects_Id                      id;
> -      void                           *user_data;
> -
> -      run = ( first->state == WATCHDOG_ACTIVE );
> -
> -      _Watchdog_Remove_it( header, first );
> -
> -      routine = first->routine;
> -      id = first->id;
> -      user_data = first->user_data;
> -
> -      _Watchdog_Release( header, &lock_context );
> -
> -      if ( run ) {
> -        (*routine)( id, user_data );
> -      }
> -
> -      _Watchdog_Acquire( header, &lock_context );
> -
> -      if ( _Watchdog_Is_empty( header ) ) {
> -        break;
> -      }
> -
> -      first = _Watchdog_First( header );
> -      delta = first->delta_interval;
> -    }
> +    _RBTree_Extract( &header->Watchdogs, &the_watchdog->Node.RBTree );
> +    _Watchdog_Set_state( the_watchdog, WATCHDOG_INACTIVE );
>    }
> -
> -  _Watchdog_Release( header, &lock_context );
>  }
> diff --git a/cpukit/score/src/watchdogtick.c
> b/cpukit/score/src/watchdogtick.c
> index e89c088..ab7eadc 100644
> --- a/cpukit/score/src/watchdogtick.c
> +++ b/cpukit/score/src/watchdogtick.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
> + * Copyright (c) 2015, 2016 embedded brains GmbH.  All rights reserved.
>   *
>   *  embedded brains GmbH
>   *  Dornierstr. 4
> @@ -12,25 +12,81 @@
>   * http://www.rtems.org/license/LICENSE.
>   */
>
> -#include <rtems/score/assert.h>
> +#if HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <rtems/score/watchdogimpl.h>
>  #include <rtems/score/schedulerimpl.h>
>  #include <rtems/score/threaddispatch.h>
> -#include <rtems/score/todimpl.h>
> -#include <rtems/score/watchdogimpl.h>
> +#include <rtems/score/timecounter.h>
>
> -#if HAVE_CONFIG_H
> -#include "config.h"
> +void _Watchdog_Do_tickle(
> +  Watchdog_Header  *header,
> +  uint64_t          now,
> +#ifdef RTEMS_SMP
> +  ISR_lock_Control *lock,
>  #endif
> +  ISR_lock_Context *lock_context
> +)
> +{
> +  while ( true ) {
> +    Watchdog_Control *the_watchdog;
> +
> +    the_watchdog = (Watchdog_Control *) header->first;
> +
> +    if ( the_watchdog == NULL ) {
> +      break;
> +    }
> +
> +    if ( the_watchdog->expire <= now ) {
> +      Watchdog_Service_routine_entry routine;
> +
> +      _Watchdog_Next_first( header, the_watchdog );
> +      _RBTree_Extract( &header->Watchdogs, &the_watchdog->Node.RBTree );
> +      _Watchdog_Set_state( the_watchdog, WATCHDOG_INACTIVE );
> +      routine = the_watchdog->routine;
> +
> +      _ISR_lock_Release_and_ISR_enable( lock, lock_context );
> +      ( *routine )( the_watchdog );
> +      _ISR_lock_ISR_disable_and_acquire( lock, lock_context );
> +    } else {
> +      break;
> +    }
> +  }
> +
> +  _ISR_lock_Release_and_ISR_enable( lock, lock_context );
> +}
>
>  void _Watchdog_Tick( Per_CPU_Control *cpu )
>  {
> -  _Assert( !_Thread_Dispatch_is_enabled() );
> +  ISR_lock_Context lock_context;
> +  uint64_t         ticks;
> +  struct timespec  now;
>
>    if ( _Per_CPU_Is_boot_processor( cpu ) ) {
> -    _TOD_Tickle_ticks();
> +    ++_Watchdog_Ticks_since_boot;
> +  }
>
> -    _Watchdog_Tickle_ticks();
> +  _ISR_lock_ISR_disable_and_acquire( &cpu->Watchdog.Lock, &lock_context );
>
> -    _Scheduler_Tick();
> -  }
> +  ticks = cpu->Watchdog.ticks;
> +  _Assert( ticks < UINT64_MAX );
> +  ++ticks;
> +  cpu->Watchdog.ticks = ticks;
> +
> +  _Watchdog_Tickle(
> +    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
> +    ticks,
> +    &cpu->Watchdog.Lock,
> +    &lock_context
> +  );
> +
> +  _Timecounter_Getnanotime( &now );
> +  _Watchdog_Per_CPU_tickle_absolute(
> +    cpu,
> +    _Watchdog_Ticks_from_timespec( &now )
> +  );
> +
> +  _Scheduler_Tick( cpu );
>  }
> diff --git a/testsuites/smptests/Makefile.am
> b/testsuites/smptests/Makefile.am
> index 92f4528..610f313 100644
> --- a/testsuites/smptests/Makefile.am
> +++ b/testsuites/smptests/Makefile.am
> @@ -14,6 +14,7 @@ SUBDIRS += smpatomic01
>  SUBDIRS += smpcache01
>  SUBDIRS += smpcapture01
>  SUBDIRS += smpcapture02
> +SUBDIRS += smpclock01
>  SUBDIRS += smpfatal01
>  SUBDIRS += smpfatal02
>  SUBDIRS += smpfatal03
> diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/
> configure.ac
> index 27e8f9c..a89b796 100644
> --- a/testsuites/smptests/configure.ac
> +++ b/testsuites/smptests/configure.ac
> @@ -69,6 +69,7 @@ smpatomic01/Makefile
>  smpcache01/Makefile
>  smpcapture01/Makefile
>  smpcapture02/Makefile
> +smpclock01/Makefile
>  smpfatal01/Makefile
>  smpfatal02/Makefile
>  smpfatal03/Makefile
> diff --git a/testsuites/smptests/smpclock01/Makefile.am
> b/testsuites/smptests/smpclock01/Makefile.am
> new file mode 100644
> index 0000000..49e274b
> --- /dev/null
> +++ b/testsuites/smptests/smpclock01/Makefile.am
> @@ -0,0 +1,20 @@
> +rtems_tests_PROGRAMS = smpclock01
> +smpclock01_SOURCES = init.c
> +smpclock01_SOURCES += ../../support/src/spin.c
> +
> +dist_rtems_tests_DATA = smpclock01.scn smpclock01.doc
> +
> +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
> +include $(top_srcdir)/../automake/compile.am
> +include $(top_srcdir)/../automake/leaf.am
> +
> +AM_CPPFLAGS += -I$(top_srcdir)/../support/include
> +
> +LINK_OBJS = $(smpclock01_OBJECTS)
> +LINK_LIBS = $(smpclock01_LDLIBS)
> +
> +smpclock01$(EXEEXT): $(smpclock01_OBJECTS) $(smpclock01_DEPENDENCIES)
> +       @rm -f smpclock01$(EXEEXT)
> +       $(make-exe)
> +
> +include $(top_srcdir)/../automake/local.am
> diff --git a/testsuites/smptests/smpclock01/init.c
> b/testsuites/smptests/smpclock01/init.c
> new file mode 100644
> index 0000000..36016ef
> --- /dev/null
> +++ b/testsuites/smptests/smpclock01/init.c
> @@ -0,0 +1,206 @@
> +/*
> + * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
> + *
> + *  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
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +  #include "config.h"
> +#endif
> +
> +#include "tmacros.h"
> +
> +#include <rtems.h>
> +#include <rtems/libcsupport.h>
> +#include <rtems/score/percpu.h>
> +#include <rtems/score/smpbarrier.h>
> +
> +#include <test_support.h>
> +
> +#define CPU_COUNT 2
> +
> +#define SCHEDULER_A rtems_build_name(' ', ' ', ' ', 'A')
> +
> +#define SCHEDULER_B rtems_build_name(' ', ' ', ' ', 'B')
> +
> +const char rtems_test_name[] = "SMPCLOCK 1";
> +
> +typedef struct {
> +  SMP_barrier_Control barrier;
> +  SMP_barrier_State delay_barrier_state;
> +  SMP_barrier_State timer_barrier_state;
> +} test_context;
> +
> +static test_context test_instance = {
> +  .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
> +  .delay_barrier_state = SMP_BARRIER_STATE_INITIALIZER,
> +  .timer_barrier_state = SMP_BARRIER_STATE_INITIALIZER
> +};
> +
> +static void wait(test_context *ctx, SMP_barrier_State *bs)
> +{
> +  _SMP_barrier_Wait(&ctx->barrier, bs, CPU_COUNT);
> +}
> +
> +static void timer_isr(rtems_id id, void *arg)
> +{
> +  test_context *ctx = arg;
> +
> +  /* (B) */
> +  wait(ctx, &ctx->timer_barrier_state);
> +}
> +
> +static void timer_task(rtems_task_argument arg)
> +{
> +  test_context *ctx = (test_context *) arg;
> +  rtems_status_code sc;
> +  rtems_id timer_id;
> +
> +  rtems_test_assert(rtems_get_current_processor() == 1);
> +
> +  sc = rtems_timer_create(SCHEDULER_B, &timer_id);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  /* (A) */
> +  wait(ctx, &ctx->timer_barrier_state);
> +
> +  sc = rtems_timer_fire_after(timer_id, 1, timer_isr, ctx);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_task_wake_after(1);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_timer_delete(timer_id);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  /* (C) */
> +  wait(ctx, &ctx->timer_barrier_state);
> +
> +  while (true) {
> +    /* Wait for deletion */
> +  }
> +}
> +
> +static void delay_clock_tick(test_context *ctx)
> +{
> +  rtems_interrupt_level level;
> +  const Per_CPU_Control *cpu_self = _Per_CPU_Get_by_index(0);
> +  const Per_CPU_Control *cpu_other = _Per_CPU_Get_by_index(1);
> +  uint64_t ticks;
> +
> +  rtems_test_assert(rtems_get_current_processor() == 0);
> +
> +  rtems_test_spin_until_next_tick();
> +  ticks = cpu_self->Watchdog.ticks;
> +
> +  rtems_interrupt_local_disable(level);
> +
> +  /* (A) */
> +  wait(ctx, &ctx->delay_barrier_state);
> +
> +  /* (B) */
> +  wait(ctx, &ctx->delay_barrier_state);
> +
> +  rtems_test_assert(cpu_self->Watchdog.ticks == ticks);
> +  rtems_test_assert(cpu_other->Watchdog.ticks == ticks + 1);
> +
> +  rtems_interrupt_local_enable(level);
> +
> +  rtems_test_assert(cpu_self->Watchdog.ticks == ticks + 1);
> +  rtems_test_assert(cpu_other->Watchdog.ticks == ticks + 1);
> +
> +  /* (C) */
> +  wait(ctx, &ctx->delay_barrier_state);
> +}
> +
> +static void test(void)
> +{
> +  test_context *ctx = &test_instance;
> +  rtems_status_code sc;
> +  rtems_id scheduler_b_id;
> +  rtems_id task_id;
> +
> +  sc = rtems_scheduler_ident(SCHEDULER_B, &scheduler_b_id);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_task_create(
> +    SCHEDULER_B,
> +    1,
> +    RTEMS_MINIMUM_STACK_SIZE,
> +    RTEMS_DEFAULT_MODES,
> +    RTEMS_DEFAULT_ATTRIBUTES,
> +    &task_id
> +  );
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_task_set_scheduler(task_id, scheduler_b_id);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_task_start(task_id, timer_task, (rtems_task_argument) ctx);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  delay_clock_tick(ctx);
> +
> +  sc = rtems_task_delete(task_id);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +}
> +
> +static void Init(rtems_task_argument arg)
> +{
> +  rtems_resource_snapshot snapshot;
> +
> +  TEST_BEGIN();
> +
> +  rtems_resource_snapshot_take(&snapshot);
> +
> +  if (rtems_get_processor_count() == CPU_COUNT) {
> +    test();
> +  }
> +
> +  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
> +
> +  TEST_END();
> +  rtems_test_exit(0);
> +}
> +
> +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
> +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> +
> +#define CONFIGURE_SMP_APPLICATION
> +
> +#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
> +
> +#define CONFIGURE_SCHEDULER_SIMPLE_SMP
> +
> +#include <rtems/scheduler.h>
> +
> +RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a);
> +RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
> +
> +#define CONFIGURE_SCHEDULER_CONTROLS \
> +  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(a, SCHEDULER_A), \
> +  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHEDULER_B)
> +
> +#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
> +  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
> +  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
> +
> +#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
> +
> +#define CONFIGURE_MAXIMUM_TIMERS 1
> +
> +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
> +
> +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
> +
> +#define CONFIGURE_INIT
> +
> +#include <rtems/confdefs.h>
> diff --git a/testsuites/smptests/smpclock01/smpclock01.doc
> b/testsuites/smptests/smpclock01/smpclock01.doc
> new file mode 100644
> index 0000000..130644a
> --- /dev/null
> +++ b/testsuites/smptests/smpclock01/smpclock01.doc
> @@ -0,0 +1,11 @@
> +This file describes the directives and concepts tested by this test set.
> +
> +test set name: smpclock01
> +
> +directives:
> +
> +  - Clock driver interrupt
> +
> +concepts:
> +
> +  - Ensures that the clock interrupt is distributed to all online
> processors.
> diff --git a/testsuites/smptests/smpclock01/smpclock01.scn
> b/testsuites/smptests/smpclock01/smpclock01.scn
> new file mode 100644
> index 0000000..192ed83
> --- /dev/null
> +++ b/testsuites/smptests/smpclock01/smpclock01.scn
> @@ -0,0 +1,2 @@
> +*** BEGIN OF TEST SMPCLOCK 1 ***
> +*** END OF TEST SMPCLOCK 1 ***
> diff --git a/testsuites/smptests/smpwakeafter01/smpwakeafter01.scn
> b/testsuites/smptests/smpwakeafter01/smpwakeafter01.scn
> index 9bbb558..7fa203d 100644
> --- a/testsuites/smptests/smpwakeafter01/smpwakeafter01.scn
> +++ b/testsuites/smptests/smpwakeafter01/smpwakeafter01.scn
> @@ -9,36 +9,196 @@
>  3 seconds remaining
>  2 seconds remaining
>  1 seconds remaining
> -counts[0][0] = 15479
> -counts[0][1] = 17039
> -counts[0][2] = 12389
> -counts[0][3] = 8077
> -counts[0][4] = 3
> -counts[0][5] = 2431
> -counts[0][6] = 2630
> -counts[0][7] = 2128
> -counts[1][0] = 15461
> -counts[1][1] = 16813
> -counts[1][2] = 12248
> -counts[1][3] = 7483
> -counts[1][4] = 5499
> -counts[1][5] = 3170
> -counts[1][6] = 2549
> -counts[1][7] = 1748
> -counts[2][0] = 71
> -counts[2][1] = 17068
> -counts[2][2] = 7661
> -counts[2][3] = 8190
> -counts[2][4] = 5513
> -counts[2][5] = 3864
> -counts[2][6] = 1454
> -counts[2][7] = 1993
> -counts[3][0] = 14511
> -counts[3][1] = 16115
> -counts[3][2] = 12561
> -counts[3][3] = 7281
> -counts[3][4] = 5507
> -counts[3][5] = 3828
> -counts[3][6] = 2687
> -counts[3][7] = 1278
> +counts[0][0] = 10013
> +counts[0][1] = 5007
> +counts[0][2] = 3339
> +counts[0][3] = 2004
> +counts[0][4] = 1432
> +counts[0][5] = 912
> +counts[0][6] = 771
> +counts[0][7] = 590
> +counts[1][0] = 10027
> +counts[1][1] = 5015
> +counts[1][2] = 3344
> +counts[1][3] = 2007
> +counts[1][4] = 1434
> +counts[1][5] = 913
> +counts[1][6] = 773
> +counts[1][7] = 591
> +counts[2][0] = 10041
> +counts[2][1] = 5022
> +counts[2][2] = 3349
> +counts[2][3] = 2010
> +counts[2][4] = 1436
> +counts[2][5] = 914
> +counts[2][6] = 774
> +counts[2][7] = 592
> +counts[3][0] = 10055
> +counts[3][1] = 5029
> +counts[3][2] = 3353
> +counts[3][3] = 2013
> +counts[3][4] = 1438
> +counts[3][5] = 915
> +counts[3][6] = 775
> +counts[3][7] = 593
> +counts[4][0] = 10070
> +counts[4][1] = 5036
> +counts[4][2] = 3358
> +counts[4][3] = 2015
> +counts[4][4] = 1440
> +counts[4][5] = 917
> +counts[4][6] = 776
> +counts[4][7] = 594
> +counts[5][0] = 10084
> +counts[5][1] = 5043
> +counts[5][2] = 3363
> +counts[5][3] = 2018
> +counts[5][4] = 1442
> +counts[5][5] = 918
> +counts[5][6] = 777
> +counts[5][7] = 594
> +counts[6][0] = 10098
> +counts[6][1] = 5050
> +counts[6][2] = 3368
> +counts[6][3] = 2021
> +counts[6][4] = 1444
> +counts[6][5] = 919
> +counts[6][6] = 778
> +counts[6][7] = 595
> +counts[7][0] = 10113
> +counts[7][1] = 5058
> +counts[7][2] = 3373
> +counts[7][3] = 2024
> +counts[7][4] = 1446
> +counts[7][5] = 921
> +counts[7][6] = 779
> +counts[7][7] = 596
> +counts[8][0] = 10127
> +counts[8][1] = 5065
> +counts[8][2] = 3377
> +counts[8][3] = 2027
> +counts[8][4] = 1448
> +counts[8][5] = 922
> +counts[8][6] = 780
> +counts[8][7] = 597
> +counts[9][0] = 10142
> +counts[9][1] = 5072
> +counts[9][2] = 3382
> +counts[9][3] = 2030
> +counts[9][4] = 1450
> +counts[9][5] = 923
> +counts[9][6] = 781
> +counts[9][7] = 598
> +counts[10][0] = 10156
> +counts[10][1] = 5079
> +counts[10][2] = 3387
> +counts[10][3] = 2033
> +counts[10][4] = 1452
> +counts[10][5] = 925
> +counts[10][6] = 783
> +counts[10][7] = 599
> +counts[11][0] = 10170
> +counts[11][1] = 5086
> +counts[11][2] = 3392
> +counts[11][3] = 2036
> +counts[11][4] = 1454
> +counts[11][5] = 926
> +counts[11][6] = 784
> +counts[11][7] = 599
> +counts[12][0] = 10185
> +counts[12][1] = 5094
> +counts[12][2] = 3397
> +counts[12][3] = 2039
> +counts[12][4] = 1457
> +counts[12][5] = 927
> +counts[12][6] = 785
> +counts[12][7] = 600
> +counts[13][0] = 10200
> +counts[13][1] = 5101
> +counts[13][2] = 3402
> +counts[13][3] = 2042
> +counts[13][4] = 1459
> +counts[13][5] = 929
> +counts[13][6] = 786
> +counts[13][7] = 601
> +counts[14][0] = 10215
> +counts[14][1] = 5109
> +counts[14][2] = 3407
> +counts[14][3] = 2045
> +counts[14][4] = 1461
> +counts[14][5] = 930
> +counts[14][6] = 787
> +counts[14][7] = 602
> +counts[15][0] = 10230
> +counts[15][1] = 5116
> +counts[15][2] = 3412
> +counts[15][3] = 2048
> +counts[15][4] = 1463
> +counts[15][5] = 931
> +counts[15][6] = 788
> +counts[15][7] = 603
> +counts[16][0] = 10245
> +counts[16][1] = 5124
> +counts[16][2] = 3417
> +counts[16][3] = 2051
> +counts[16][4] = 1465
> +counts[16][5] = 933
> +counts[16][6] = 789
> +counts[16][7] = 604
> +counts[17][0] = 10260
> +counts[17][1] = 5131
> +counts[17][2] = 3422
> +counts[17][3] = 2054
> +counts[17][4] = 1467
> +counts[17][5] = 934
> +counts[17][6] = 791
> +counts[17][7] = 605
> +counts[18][0] = 10275
> +counts[18][1] = 5139
> +counts[18][2] = 3427
> +counts[18][3] = 2057
> +counts[18][4] = 1469
> +counts[18][5] = 935
> +counts[18][6] = 792
> +counts[18][7] = 606
> +counts[19][0] = 10290
> +counts[19][1] = 5146
> +counts[19][2] = 3432
> +counts[19][3] = 2060
> +counts[19][4] = 1472
> +counts[19][5] = 937
> +counts[19][6] = 793
> +counts[19][7] = 607
> +counts[20][0] = 10305
> +counts[20][1] = 5154
> +counts[20][2] = 3437
> +counts[20][3] = 2063
> +counts[20][4] = 1474
> +counts[20][5] = 938
> +counts[20][6] = 794
> +counts[20][7] = 607
> +counts[21][0] = 10320
> +counts[21][1] = 5161
> +counts[21][2] = 3442
> +counts[21][3] = 2066
> +counts[21][4] = 1476
> +counts[21][5] = 940
> +counts[21][6] = 795
> +counts[21][7] = 608
> +counts[22][0] = 10335
> +counts[22][1] = 5169
> +counts[22][2] = 3447
> +counts[22][3] = 2069
> +counts[22][4] = 1478
> +counts[22][5] = 941
> +counts[22][6] = 796
> +counts[22][7] = 609
> +counts[23][0] = 10350
> +counts[23][1] = 5176
> +counts[23][2] = 3452
> +counts[23][3] = 2072
> +counts[23][4] = 1480
> +counts[23][5] = 942
> +counts[23][6] = 798
> +counts[23][7] = 610
>  *** END OF TEST SMPWAKEAFTER 1 ***
> diff --git a/testsuites/sptests/Makefile.am
> b/testsuites/sptests/Makefile.am
> index c5210a5..43f3d82 100644
> --- a/testsuites/sptests/Makefile.am
> +++ b/testsuites/sptests/Makefile.am
> @@ -25,7 +25,7 @@ _SUBDIRS = \
>      spintrcritical05 spintrcritical06 spintrcritical07 spintrcritical08 \
>      spintrcritical09 spintrcritical10 spintrcritical11 spintrcritical12 \
>      spintrcritical13 spintrcritical14 spintrcritical15 spintrcritical16 \
> -    spintrcritical17 spintrcritical18 spmkdir spmountmgr01 spheapprot \
> +    spintrcritical18 spmkdir spmountmgr01 spheapprot \
>      sppagesize spsem01 spsem02 spsimplesched01 spsimplesched02 \
>      spsimplesched03 spnsext01 spedfsched01 spedfsched02 spedfsched03 \
>      spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01 \
> @@ -77,6 +77,7 @@ _SUBDIRS += speventsystem01
>  _SUBDIRS += spinternalerror01
>  _SUBDIRS += spinternalerror02
>  _SUBDIRS += sptimer_err01 sptimer_err02
> +_SUBDIRS += sptimerserver01
>  _SUBDIRS += spclock_err02
>
>  if HAS_CPUSET
> diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/
> configure.ac
> index e46f6fa..eeebc91 100644
> --- a/testsuites/sptests/configure.ac
> +++ b/testsuites/sptests/configure.ac
> @@ -46,6 +46,7 @@ AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" =
> "yes")
>
>  # Explicitly list all Makefiles here
>  AC_CONFIG_FILES([Makefile
> +sptimerserver01/Makefile
>  spsysinit01/Makefile
>  splinkersets01/Makefile
>  spstdthreads01/Makefile
> @@ -216,7 +217,6 @@ spintrcritical13/Makefile
>  spintrcritical14/Makefile
>  spintrcritical15/Makefile
>  spintrcritical16/Makefile
> -spintrcritical17/Makefile
>  spheapprot/Makefile
>  spmkdir/Makefile
>  spmountmgr01/Makefile
> diff --git a/testsuites/sptests/sp31/task1.c
> b/testsuites/sptests/sp31/task1.c
> index f4e526a..c3f0ae1 100644
> --- a/testsuites/sptests/sp31/task1.c
> +++ b/testsuites/sptests/sp31/task1.c
> @@ -40,14 +40,6 @@ static rtems_timer_service_routine Do_nothing(
>    /* Do nothing */
>  }
>
> -static Watchdog_Interval schedule_time( void )
> -{
> -  const Watchdog_Control *watchdog =
> -    &_Timer_server->Interval_watchdogs.System_watchdog;
> -
> -  return watchdog->initial + watchdog->start_time;
> -}
> -
>  rtems_task Task_1(
>    rtems_task_argument argument
>  )
> @@ -119,10 +111,6 @@ rtems_task Task_1(
>      "Timer 1 scheduled for %" PRIdWatchdog_Interval " ticks since boot\n",
>      info.start_time + info.initial
>    );
> -  printf(
> -    "Timer Server scheduled for %" PRIdWatchdog_Interval " ticks since
> boot\n",
> -    schedule_time()
> -  );
>
>    puts( "TA1 - rtems_task_wake_after - 1 second" );
>    status = rtems_task_wake_after( 1 * rtems_clock_get_ticks_per_second()
> );
> @@ -139,11 +127,6 @@ rtems_task Task_1(
>      "Timer 1 scheduled for %" PRIdWatchdog_Interval " ticks since boot\n",
>      info.start_time + info.initial
>    );
> -  printf(
> -    "Timer Server scheduled for %" PRIdWatchdog_Interval " ticks since
> boot\n",
> -    schedule_time()
> -  );
> -  rtems_test_assert( (info.start_time + info.initial) == schedule_time()
> );
>
>    puts( "TA1 - rtems_task_wake_after - 1 second" );
>    status = rtems_task_wake_after( 1 * rtems_clock_get_ticks_per_second()
> );
> @@ -160,11 +143,6 @@ rtems_task Task_1(
>      "Timer 1 scheduled for %" PRIdWatchdog_Interval " ticks since boot\n",
>       info.start_time + info.initial
>    );
> -  printf(
> -    "Timer Server scheduled for %" PRIdWatchdog_Interval " ticks since
> boot\n",
> -     schedule_time()
> -  );
> -  rtems_test_assert( (info.start_time + info.initial) == schedule_time()
> );
>
>    puts( "TA1 - rtems_timer_cancel - timer 1" );
>    status = rtems_timer_cancel( tmid );
> diff --git a/testsuites/sptests/spintrcritical08/init.c
> b/testsuites/sptests/spintrcritical08/init.c
> index f375cd4..3610e65 100644
> --- a/testsuites/sptests/spintrcritical08/init.c
> +++ b/testsuites/sptests/spintrcritical08/init.c
> @@ -46,23 +46,21 @@ static rtems_timer_service_routine
> test_release_from_isr(
>    void     *arg
>  )
>  {
> -  Watchdog_Header *header = &_Watchdog_Ticks_header;
> +  Per_CPU_Control *cpu = _Per_CPU_Get();
> +  Watchdog_Header *header = &cpu->Watchdog.Header[
> PER_CPU_WATCHDOG_RELATIVE ];
> +  Watchdog_Control *watchdog = (Watchdog_Control *) header->first;
>
> -  if ( !_Watchdog_Is_empty( header ) ) {
> -    Watchdog_Control *watchdog = _Watchdog_First( header );
> +  if (
> +    watchdog != NULL
> +      && watchdog->expire == cpu->Watchdog.ticks
> +      && watchdog->routine == _Rate_monotonic_Timeout
> +  ) {
> +    _Watchdog_Per_CPU_remove_relative( watchdog );
>
> -    if (
> -      watchdog->delta_interval == 0
> -        && watchdog->routine == _Rate_monotonic_Timeout
> -    ) {
> -      Watchdog_States state = _Watchdog_Remove_ticks( watchdog );
> +    (*watchdog->routine)( watchdog );
>
> -      rtems_test_assert( state == WATCHDOG_ACTIVE );
> -      (*watchdog->routine)( watchdog->id, watchdog->user_data );
> -
> -      if ( getState() == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING ) {
> -        case_hit = true;
> -      }
> +    if ( getState() == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING ) {
> +      case_hit = true;
>      }
>    }
>  }
> diff --git a/testsuites/sptests/spintrcritical09/init.c
> b/testsuites/sptests/spintrcritical09/init.c
> index cc119e8..44eccc7 100644
> --- a/testsuites/sptests/spintrcritical09/init.c
> +++ b/testsuites/sptests/spintrcritical09/init.c
> @@ -15,6 +15,7 @@
>  #include <intrcritical.h>
>
>  #include <rtems/score/threadimpl.h>
> +#include <rtems/score/threadimpl.h>
>  #include <rtems/score/watchdogimpl.h>
>
>  const char rtems_test_name[] = "SPINTRCRITICAL 9";
> @@ -37,23 +38,21 @@ static rtems_timer_service_routine
> test_release_from_isr(
>    void     *arg
>  )
>  {
> -  Watchdog_Header *header = &_Watchdog_Ticks_header;
> -
> -  if ( !_Watchdog_Is_empty( header ) ) {
> -    Watchdog_Control *watchdog = _Watchdog_First( header );
> +  Per_CPU_Control *cpu_self = _Per_CPU_Get();
> +  Watchdog_Header *header = &cpu_self->Watchdog.Header[
> PER_CPU_WATCHDOG_RELATIVE ];
> +  Watchdog_Control *watchdog = (Watchdog_Control *) header->first;
>
> -    if (
> -      watchdog->delta_interval == 0
> -        && watchdog->routine == _Thread_Timeout
> -    ) {
> -      Watchdog_States state = _Watchdog_Remove_ticks( watchdog );
> +  if (
> +    watchdog != NULL
> +      && watchdog->expire == cpu_self->Watchdog.ticks
> +      && watchdog->routine == _Thread_Timeout
> +  ) {
> +    _Watchdog_Per_CPU_remove( watchdog, cpu_self, header );
>
> -      rtems_test_assert( state == WATCHDOG_ACTIVE );
> -      (*watchdog->routine)( watchdog->id, watchdog->user_data );
> +    (*watchdog->routine)( watchdog );
>
> -      if ( is_interrupt_timeout() ) {
> -        case_hit = true;
> -      }
> +    if ( is_interrupt_timeout() ) {
> +      case_hit = true;
>      }
>    }
>  }
> diff --git a/testsuites/sptests/spintrcritical10/init.c
> b/testsuites/sptests/spintrcritical10/init.c
> index e4a2a94..25be23a 100644
> --- a/testsuites/sptests/spintrcritical10/init.c
> +++ b/testsuites/sptests/spintrcritical10/init.c
> @@ -78,7 +78,7 @@ static void any_satisfy_before_timeout(rtems_id timer,
> void *arg)
>      );
>      rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
>
> -    _Thread_Timeout(0, thread);
> +    _Thread_Timeout(&thread->Timer.Watchdog);
>
>      rtems_test_assert(
>        *(rtems_event_set *) thread->Wait.return_argument == GREEN
> @@ -175,7 +175,7 @@ static void all_satisfy_before_timeout(rtems_id timer,
> void *arg)
>      );
>      rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
>
> -    _Thread_Timeout(0, thread);
> +    _Thread_Timeout(&thread->Timer.Watchdog);
>
>      rtems_test_assert(
>        *(rtems_event_set *) thread->Wait.return_argument == EVENTS
> @@ -251,7 +251,7 @@ static void timeout_before_satisfied(rtems_id timer,
> void *arg)
>      );
>      rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
>
> -    _Thread_Timeout(0, thread);
> +    _Thread_Timeout(&thread->Timer.Watchdog);
>
>      rtems_test_assert(
>        *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
> diff --git a/testsuites/sptests/spintrcritical16/init.c
> b/testsuites/sptests/spintrcritical16/init.c
> index a094b41..3657c06 100644
> --- a/testsuites/sptests/spintrcritical16/init.c
> +++ b/testsuites/sptests/spintrcritical16/init.c
> @@ -43,7 +43,7 @@ static rtems_timer_service_routine test_release_from_isr(
>    }
>
>    if ( Main_TCB->Wait.queue != NULL ) {
> -    _Thread_Timeout( 0, Main_TCB );
> +    _Thread_Timeout( &Main_TCB->Timer.Watchdog );
>    }
>  }
>
> diff --git a/testsuites/sptests/spintrcritical17/Makefile.am
> b/testsuites/sptests/spintrcritical17/Makefile.am
> deleted file mode 100644
> index 20b372c..0000000
> --- a/testsuites/sptests/spintrcritical17/Makefile.am
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -
> -rtems_tests_PROGRAMS = spintrcritical17
> -spintrcritical17_SOURCES = init.c \
> -    ../spintrcritical_support/intrcritical.c
> -spintrcritical17_SOURCES += ../spintrcritical_support/intrcritical.h
> -
> -dist_rtems_tests_DATA = spintrcritical17.scn
> -dist_rtems_tests_DATA += spintrcritical17.doc
> -
> -include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
> -include $(top_srcdir)/../automake/compile.am
> -include $(top_srcdir)/../automake/leaf.am
> -
> -
> -AM_CPPFLAGS += -I$(top_srcdir)/../support/include
> -AM_CPPFLAGS += -I$(top_srcdir)/spintrcritical_support
> -
> -LINK_OBJS = $(spintrcritical17_OBJECTS)
> -LINK_LIBS = $(spintrcritical17_LDLIBS)
> -
> -spintrcritical17$(EXEEXT): $(spintrcritical17_OBJECTS)
> $(spintrcritical17_DEPENDENCIES)
> -       @rm -f spintrcritical17$(EXEEXT)
> -       $(make-exe)
> -
> -include $(top_srcdir)/../automake/local.am
> diff --git a/testsuites/sptests/spintrcritical17/init.c
> b/testsuites/sptests/spintrcritical17/init.c
> deleted file mode 100644
> index 238493e..0000000
> --- a/testsuites/sptests/spintrcritical17/init.c
> +++ /dev/null
> @@ -1,118 +0,0 @@
> -/*
> - * 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
> - * http://www.rtems.org/license/LICENSE.
> - */
> -
> -#ifdef HAVE_CONFIG_H
> -#include "config.h"
> -#endif
> -
> -#include <tmacros.h>
> -#include <intrcritical.h>
> -
> -#include <rtems/rtems/timerimpl.h>
> -
> -const char rtems_test_name[] = "SPINTRCRITICAL 17";
> -
> -typedef struct {
> -  rtems_id timer1;
> -  rtems_id timer2;
> -  bool done;
> -} test_context;
> -
> -static test_context ctx_instance;
> -
> -static void never(rtems_id timer_id, void *arg)
> -{
> -  rtems_test_assert(0);
> -}
> -
> -static void fire(rtems_id timer_id, void *arg)
> -{
> -  /* 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 bool test_body(void *arg)
> -{
> -  test_context *ctx = arg;
> -  rtems_status_code sc;
> -
> -  sc = rtems_timer_reset(ctx->timer1);
> -  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -
> -  return ctx->done;
> -}
> -
> -static void Init(rtems_task_argument ignored)
> -{
> -  test_context *ctx = &ctx_instance;
> -  rtems_status_code sc;
> -
> -  TEST_BEGIN();
> -
> -  sc = rtems_timer_create(
> -    rtems_build_name('T', 'I', 'M', '1'),
> -    &ctx->timer1
> -  );
> -  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -
> -  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
> -  );
> -  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -
> -  sc = rtems_timer_server_fire_after(ctx->timer1, 1000, never, NULL);
> -  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> -
> -  interrupt_critical_section_test(test_body, ctx, fire);
> -  rtems_test_assert(ctx->done);
> -
> -  TEST_END();
> -  rtems_test_exit(0);
> -}
> -
> -#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> -#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
> -
> -#define CONFIGURE_MICROSECONDS_PER_TICK 1000
> -
> -#define CONFIGURE_MAXIMUM_TASKS 2
> -#define CONFIGURE_MAXIMUM_TIMERS 3
> -#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
> -
> -#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
> -
> -#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
> -
> -#define CONFIGURE_INIT
> -
> -#include <rtems/confdefs.h>
> diff --git a/testsuites/sptests/spintrcritical17/spintrcritical17.doc
> b/testsuites/sptests/spintrcritical17/spintrcritical17.doc
> deleted file mode 100644
> index 809a966..0000000
> --- a/testsuites/sptests/spintrcritical17/spintrcritical17.doc
> +++ /dev/null
> @@ -1,18 +0,0 @@
> -#  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
> -#  http://www.rtems.org/license/LICENSE.
> -#
> -
> -This file describes the directives and concepts tested by this test set.
> -
> -test set name:  spintrcritical17
> -
> -directives:
> -
> -  _Timer_server_Update_system_watchdog
> -
> -concepts:
> -
> -+ Test critical sections which are only accessible through an interrupt.
> diff --git a/testsuites/sptests/spintrcritical17/spintrcritical17.scn
> b/testsuites/sptests/spintrcritical17/spintrcritical17.scn
> deleted file mode 100644
> index 14566df..0000000
> --- a/testsuites/sptests/spintrcritical17/spintrcritical17.scn
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -*** TEST INTERRUPT CRITICAL SECTION 17 ***
> -*** END OF INTERRUPT CRITICAL SECTION 17 ***
> diff --git a/testsuites/sptests/spintrcritical20/init.c
> b/testsuites/sptests/spintrcritical20/init.c
> index 7e52211..85c1645 100644
> --- a/testsuites/sptests/spintrcritical20/init.c
> +++ b/testsuites/sptests/spintrcritical20/init.c
> @@ -91,7 +91,7 @@ static bool test_body(void *arg)
>      ctx->thread_queue_was_null = true;
>    }
>
> -  _Thread_Timeout(0, ctx->semaphore_task_tcb);
> +  _Thread_Timeout(&ctx->semaphore_task_tcb->Timer.Watchdog);
>
>    switch (ctx->semaphore_task_tcb->Wait.return_code) {
>      case CORE_SEMAPHORE_STATUS_SUCCESSFUL:
> diff --git a/testsuites/sptests/spsize/size.c
> b/testsuites/sptests/spsize/size.c
> index e9470e3..e19ca99 100644
> --- a/testsuites/sptests/spsize/size.c
> +++ b/testsuites/sptests/spsize/size.c
> @@ -391,8 +391,6 @@ uninitialized =
>  /*userext.h*/   (sizeof _User_extensions_List)            +
>
>  /*watchdog.h*/  (sizeof _Watchdog_Ticks_since_boot)       +
> -                (sizeof _Watchdog_Ticks_header)           +
> -                (sizeof _Watchdog_Seconds_header)         +
>
>  /*wkspace.h*/   (sizeof _Workspace_Area);
>
> diff --git a/testsuites/sptests/sptimecounter01/init.c
> b/testsuites/sptests/sptimecounter01/init.c
> index 7b31064..d87ffec 100644
> --- a/testsuites/sptests/sptimecounter01/init.c
> +++ b/testsuites/sptests/sptimecounter01/init.c
> @@ -24,7 +24,6 @@
>
>  #include <rtems/score/timecounterimpl.h>
>  #include <rtems/score/todimpl.h>
> -#include <rtems/score/watchdogimpl.h>
>  #include <rtems/timecounter.h>
>  #include <rtems/bsd.h>
>
> @@ -57,8 +56,6 @@ void boot_card(const char *cmdline)
>
>    rtems_test_begink();
>
> -  _Watchdog_Handler_initialization();
> -
>    assert(time(NULL) == TOD_SECONDS_1970_THROUGH_1988);
>
>    rtems_bsd_bintime(&bt);
> diff --git a/testsuites/sptests/sptimerserver01/Makefile.am
> b/testsuites/sptests/sptimerserver01/Makefile.am
> new file mode 100644
> index 0000000..2e5048d
> --- /dev/null
> +++ b/testsuites/sptests/sptimerserver01/Makefile.am
> @@ -0,0 +1,19 @@
> +rtems_tests_PROGRAMS = sptimerserver01
> +sptimerserver01_SOURCES = init.c
> +
> +dist_rtems_tests_DATA = sptimerserver01.scn sptimerserver01.doc
> +
> +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
> +include $(top_srcdir)/../automake/compile.am
> +include $(top_srcdir)/../automake/leaf.am
> +
> +AM_CPPFLAGS += -I$(top_srcdir)/../support/include
> +
> +LINK_OBJS = $(sptimerserver01_OBJECTS)
> +LINK_LIBS = $(sptimerserver01_LDLIBS)
> +
> +sptimerserver01$(EXEEXT): $(sptimerserver01_OBJECTS)
> $(sptimerserver01_DEPENDENCIES)
> +       @rm -f sptimerserver01$(EXEEXT)
> +       $(make-exe)
> +
> +include $(top_srcdir)/../automake/local.am
> diff --git a/testsuites/sptests/sptimerserver01/init.c
> b/testsuites/sptests/sptimerserver01/init.c
> new file mode 100644
> index 0000000..88f1fb3
> --- /dev/null
> +++ b/testsuites/sptests/sptimerserver01/init.c
> @@ -0,0 +1,129 @@
> +/*
> + * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
> + *
> + *  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
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +  #include "config.h"
> +#endif
> +
> +#include "tmacros.h"
> +
> +const char rtems_test_name[] = "SPTIMERSERVER 1";
> +
> +#define TIMER_COUNT 2
> +
> +typedef struct {
> +  rtems_id timer[TIMER_COUNT];
> +  rtems_id master;
> +} test_context;
> +
> +static test_context ctx_instance;
> +
> +static const rtems_time_of_day start = {
> +  .year = 2016,
> +  .month = 3,
> +  .day = 1,
> +  .hour = 12,
> +  .minute = 5,
> +  .second = 17
> +};
> +
> +static void cancel(rtems_id id, void *arg)
> +{
> +  test_context *ctx = arg;
> +  rtems_status_code sc;
> +
> +  sc = rtems_timer_cancel(ctx->timer[1]);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_event_transient_send(ctx->master);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +}
> +
> +static void never(rtems_id id, void *arg)
> +{
> +  rtems_test_assert(0);
> +}
> +
> +static void test(void)
> +{
> +  test_context *ctx = &ctx_instance;
> +  rtems_status_code sc;
> +  size_t i;
> +  rtems_time_of_day later;
> +
> +  ctx->master = rtems_task_self();
> +
> +  sc = rtems_timer_initiate_server(
> +    RTEMS_MINIMUM_PRIORITY,
> +    RTEMS_MINIMUM_STACK_SIZE,
> +    RTEMS_DEFAULT_ATTRIBUTES
> +  );
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  for (i = 0; i < TIMER_COUNT; ++i) {
> +    sc = rtems_timer_create(
> +      rtems_build_name('T', 'M', 'R', '0' + i),
> +      &ctx->timer[i]
> +    );
> +    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +  }
> +
> +  sc = rtems_timer_server_fire_after(ctx->timer[0], 10, cancel, ctx);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_timer_server_fire_after(ctx->timer[1], 10, never, NULL);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_clock_set(&start);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  later = start;
> +  ++later.second;
> +
> +  sc = rtems_timer_server_fire_when(ctx->timer[0], &later, cancel, ctx);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_timer_server_fire_when(ctx->timer[1], &later, never, NULL);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +
> +  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
> +  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
> +}
> +
> +static void Init(rtems_task_argument arg)
> +{
> +  TEST_BEGIN();
> +
> +  test();
> +
> +  TEST_END();
> +  rtems_test_exit(0);
> +}
> +
> +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
> +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> +
> +#define CONFIGURE_MAXIMUM_TASKS 2
> +#define CONFIGURE_MAXIMUM_TIMERS TIMER_COUNT
> +
> +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
> +
> +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
> +
> +#define CONFIGURE_INIT
> +
> +#include <rtems/confdefs.h>
> diff --git a/testsuites/sptests/sptimerserver01/sptimerserver01.doc
> b/testsuites/sptests/sptimerserver01/sptimerserver01.doc
> new file mode 100644
> index 0000000..c0dc4ef
> --- /dev/null
> +++ b/testsuites/sptests/sptimerserver01/sptimerserver01.doc
> @@ -0,0 +1,12 @@
> +This file describes the directives and concepts tested by this test set.
> +
> +test set name: sptimerserver01
> +
> +directives:
> +
> +  - rtems_timer_cancel()
> +
> +concepts:
> +
> +  - Ensure that pending timer server timers are cancelled via
> +    rtems_timer_cancel().
> diff --git a/testsuites/sptests/sptimerserver01/sptimerserver01.scn
> b/testsuites/sptests/sptimerserver01/sptimerserver01.scn
> new file mode 100644
> index 0000000..315f030
> --- /dev/null
> +++ b/testsuites/sptests/sptimerserver01/sptimerserver01.scn
> @@ -0,0 +1,2 @@
> +*** BEGIN OF TEST SPTIMERSERVER 1 ***
> +*** END OF TEST SPTIMERSERVER 1 ***
> diff --git a/testsuites/sptests/spwatchdog/init.c
> b/testsuites/sptests/spwatchdog/init.c
> index 025295b..3b08fb5 100644
> --- a/testsuites/sptests/spwatchdog/init.c
> +++ b/testsuites/sptests/spwatchdog/init.c
> @@ -26,241 +26,192 @@
>
>  const char rtems_test_name[] = "SPWATCHDOG";
>
> -static void test_watchdog_routine( Objects_Id id, void *arg )
> -{
> -  (void) id;
> -  (void) arg;
> -
> -  rtems_test_assert( 0 );
> -}
> +typedef struct {
> +  Watchdog_Control Base;
> +  int counter;
> +} test_watchdog;
>
> -static void init_watchdogs(
> -  Watchdog_Header *header,
> -  Watchdog_Control watchdogs[4]
> -)
> +static void test_watchdog_routine( Watchdog_Control *base )
>  {
> -  Watchdog_Control *a = &watchdogs[0];
> -  Watchdog_Control *b = &watchdogs[1];
> -  Watchdog_Control *c = &watchdogs[2];
> -  Watchdog_Control *d = &watchdogs[3];
> -
> -  _Watchdog_Header_initialize( header );
> -  rtems_test_assert( _Watchdog_Is_empty( header ) );
> -  rtems_test_assert( _Chain_Is_empty( &header->Iterators ) );
> -
> -  _Watchdog_Preinitialize( c );
> -  c->initial = 6;
> -  _Watchdog_Insert( header, c );
> -  rtems_test_assert( c->delta_interval == 6 );
> -
> -  rtems_test_assert( !_Watchdog_Is_empty( header ) );
> -  rtems_test_assert( _Chain_Is_empty( &header->Iterators ) );
> -
> -  _Watchdog_Preinitialize( a );
> -  a->initial = 2;
> -  _Watchdog_Insert( header, a );
> -  rtems_test_assert( a->delta_interval == 2 );
> -  rtems_test_assert( c->delta_interval == 4 );
> -
> -  _Watchdog_Preinitialize( b );
> -  b->initial = 4;
> -  _Watchdog_Insert( header, b );
> -  rtems_test_assert( a->delta_interval == 2 );
> -  rtems_test_assert( b->delta_interval == 2 );
> -  rtems_test_assert( c->delta_interval == 2 );
> -
> -  _Watchdog_Preinitialize( d );
> -}
> +  test_watchdog *watchdog = (test_watchdog *) base;
>
> -static void destroy_watchdogs(
> -  Watchdog_Header *header
> -)
> -{
> -  _ISR_lock_Destroy( &header->Lock );
> +  ++watchdog->counter;
>  }
>
> -static void add_iterator(
> -  Watchdog_Header *header,
> -  Watchdog_Iterator *i,
> -  Watchdog_Control *w
> -)
> +static void test_watchdog_static_init( void )
>  {
> -  _Chain_Append_unprotected( &header->Iterators, &i->Node );
> -  i->delta_interval = 2;
> -  i->current = &w->Node;
> -}
> +  static Watchdog_Control a = WATCHDOG_INITIALIZER(
> +    test_watchdog_routine
> +  );
> +  Watchdog_Control b;
>
> -static void test_watchdog_insert_and_remove( void )
> -{
> -  Watchdog_Header header;
> -  Watchdog_Control watchdogs[4];
> -  Watchdog_Control *a = &watchdogs[0];
> -  Watchdog_Control *b = &watchdogs[1];
> -  Watchdog_Control *c = &watchdogs[2];
> -  Watchdog_Control *d = &watchdogs[3];
> -  Watchdog_Iterator i;
> -
> -  init_watchdogs( &header, watchdogs );
> -  add_iterator( &header, &i, c );
> -
> -  /* Remove next watchdog of iterator */
> -  _Watchdog_Remove( &header, c );
> -  rtems_test_assert( i.delta_interval == 4 );
> -  rtems_test_assert( i.current == &b->Node );
> -
> -  /* Remove watchdog before the current watchdog of iterator */
> -  _Watchdog_Remove( &header, a );
> -  rtems_test_assert( i.delta_interval == 6 );
> -  rtems_test_assert( i.current == &b->Node );
> -
> -  /* Remove current (= last) watchdog of iterator */
> -  _Watchdog_Remove( &header, b );
> -  rtems_test_assert( i.delta_interval == 6 );
> -  rtems_test_assert( i.current == _Chain_Head( &header.Watchdogs ) );
> -
> -  /* Insert first watchdog */
> -  a->initial = 1;
> -  _Watchdog_Insert( &header, a );
> -  rtems_test_assert( i.delta_interval == 6 );
> -  rtems_test_assert( i.current == _Chain_Head( &header.Watchdogs ) );
> -
> -  destroy_watchdogs( &header );
> -  init_watchdogs( &header, watchdogs );
> -  add_iterator( &header, &i, b );
> -
> -  /* Insert right before current watchdog of iterator */
> -  d->initial = 3;
> -  _Watchdog_Insert( &header, d );
> -  rtems_test_assert( i.delta_interval == 2 );
> -  rtems_test_assert( i.current == &d->Node );
> -
> -  destroy_watchdogs( &header );
> -  init_watchdogs( &header, watchdogs );
> -  add_iterator( &header, &i, b );
> -
> -  /* Insert right after current watchdog of iterator */
> -  d->initial = 5;
> -  _Watchdog_Insert( &header, d );
> -  rtems_test_assert( i.delta_interval == 2 );
> -  rtems_test_assert( i.current == &b->Node );
> -
> -  destroy_watchdogs( &header );
> +  memset( &b, 0, sizeof( b ) );
> +  _Watchdog_Preinitialize( &b, _Per_CPU_Get_by_index( 0 ) );
> +  _Watchdog_Initialize(
> +    &b,
> +    test_watchdog_routine
> +  );
> +
> +  rtems_test_assert( memcmp( &a, &b, sizeof( a ) ) == 0 );
>  }
>
> -static void init_watchdogs_remove_second_and_insert_first(
> -  Watchdog_Header *header,
> -  Watchdog_Control watchdogs[3]
> -)
> +static bool test_watchdog_is_inactive( test_watchdog *watchdog )
>  {
> -  Watchdog_Control *a = &watchdogs[0];
> -  Watchdog_Control *b = &watchdogs[1];
> -  Watchdog_Control *c = &watchdogs[2];
> -
> -  _Watchdog_Preinitialize( a );
> -  _Watchdog_Preinitialize( b );
> -  _Watchdog_Preinitialize( c );
> -
> -  _Watchdog_Header_initialize( header );
> -
> -  a->initial = 6;
> -  _Watchdog_Insert( header, a );
> -  rtems_test_assert( a->delta_interval == 6 );
> -
> -  b->initial = 8;
> -  _Watchdog_Insert( header, b );
> -  rtems_test_assert( a->delta_interval == 6 );
> -  rtems_test_assert( b->delta_interval == 2 );
> +  return _Watchdog_Get_state( &watchdog->Base ) == WATCHDOG_INACTIVE;
>  }
>
> -static void test_watchdog_remove_second_and_insert_first( void )
> +static void test_watchdog_init( test_watchdog *watchdog, int counter )
>  {
> -  Watchdog_Header header;
> -  Watchdog_Control watchdogs[3];
> -  Watchdog_Control *a = &watchdogs[0];
> -  Watchdog_Control *b = &watchdogs[1];
> -  Watchdog_Control *c = &watchdogs[2];
> -  Watchdog_Iterator i;
> -
> -  init_watchdogs_remove_second_and_insert_first( &header, watchdogs );
> -  add_iterator( &header, &i, b );
> -
> -  _Watchdog_Remove( &header, b );
> -  rtems_test_assert( i.delta_interval == 8 );
> -  rtems_test_assert( i.current == &a->Node );
> -
> -  c->initial = 4;
> -  _Watchdog_Insert( &header, c );
> -  rtems_test_assert( a->delta_interval == 2 );
> -  rtems_test_assert( c->delta_interval == 4 );
> -  rtems_test_assert( i.delta_interval == 8 );
> -  rtems_test_assert( i.current == &c->Node );
> -
> -  destroy_watchdogs( &header );
> +  _Watchdog_Preinitialize( &watchdog->Base, _Per_CPU_Get_snapshot() );
> +  _Watchdog_Initialize( &watchdog->Base, test_watchdog_routine );
> +  rtems_test_assert( test_watchdog_is_inactive( watchdog ) ) ;
> +  watchdog->counter = counter;
>  }
>
> -static void init_watchdogs_insert_with_iterator(
> -  Watchdog_Header *header,
> -  Watchdog_Control watchdogs[2]
> -)
> +static uint64_t test_watchdog_tick( Watchdog_Header *header, uint64_t now
> )
>  {
> -  Watchdog_Control *a = &watchdogs[0];
> -  Watchdog_Control *b = &watchdogs[1];
> +  ISR_LOCK_DEFINE( , lock, "Test" )
> +  ISR_lock_Context lock_context;
>
> -  _Watchdog_Preinitialize( a );
> -  _Watchdog_Preinitialize( b );
> +  _ISR_lock_ISR_disable_and_acquire( &lock, &lock_context );
> +  ++now;
> +  _Watchdog_Tickle( header, now, &lock, &lock_context );
> +  _ISR_lock_Destroy( &lock );
>
> -  _Watchdog_Header_initialize( header );
> -
> -  a->initial = 6;
> -  _Watchdog_Insert( header, a );
> -  rtems_test_assert( a->delta_interval == 6 );
> +  return now;
>  }
>
> -static void test_watchdog_insert_with_iterator( void )
> +static void test_watchdog_operations( void )
>  {
>    Watchdog_Header header;
> -  Watchdog_Control watchdogs[2];
> -  Watchdog_Control *a = &watchdogs[0];
> -  Watchdog_Control *b = &watchdogs[1];
> -  Watchdog_Iterator i;
> -
> -  init_watchdogs_insert_with_iterator( &header, watchdogs );
> -  add_iterator( &header, &i, a );
> -
> -  b->initial = 4;
> -  _Watchdog_Insert( &header, b );
> -  rtems_test_assert( a->delta_interval == 2 );
> -  rtems_test_assert( b->delta_interval == 4 );
> -  rtems_test_assert( i.delta_interval == 2 );
> -  rtems_test_assert( i.current == &b->Node );
> -
> -  destroy_watchdogs( &header );
> -}
> -
> -static void test_watchdog_static_init( void )
> -{
> -  #if defined(RTEMS_USE_16_BIT_OBJECT)
> -    #define JUNK_ID 0x1234
> -  #else
> -    #define JUNK_ID 0x12345678
> -  #endif
> -
> -  static Watchdog_Control a = WATCHDOG_INITIALIZER(
> -    test_watchdog_routine,
> -    JUNK_ID,
> -    (void *) 0xdeadbeef
> -  );
> -  Watchdog_Control b;
> -
> -  memset( &b, 0, sizeof( b ) );
> -  _Watchdog_Initialize(
> -    &b,
> -    test_watchdog_routine,
> -    JUNK_ID,
> -    (void *) 0xdeadbeef
> -  );
> -
> -  rtems_test_assert( memcmp( &a, &b, sizeof( a ) ) == 0 );
> +  uint64_t now;
> +  test_watchdog a;
> +  test_watchdog b;
> +  test_watchdog c;
> +
> +  _Watchdog_Header_initialize( &header );
> +  rtems_test_assert( _RBTree_Is_empty( &header.Watchdogs ) );
> +  rtems_test_assert( header.first == NULL );
> +
> +  test_watchdog_init( &a, 10 );
> +  test_watchdog_init( &b, 20 );
> +  test_watchdog_init( &c, 30 );
> +
> +  now = 0;
> +  now = test_watchdog_tick( &header, now );
> +
> +  _Watchdog_Insert( &header, &a.Base, now + 1 );
> +  rtems_test_assert( header.first == &a.Base.Node.RBTree );
> +  rtems_test_assert( !test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 2 );
> +  rtems_test_assert( a.counter == 10 );
> +
> +  _Watchdog_Remove( &header, &a.Base );
> +  rtems_test_assert( header.first == NULL );
> +  rtems_test_assert( test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 2 );
> +  rtems_test_assert( a.counter == 10 );
> +
> +  _Watchdog_Remove( &header, &a.Base );
> +  rtems_test_assert( header.first == NULL );
> +  rtems_test_assert( test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 2 );
> +  rtems_test_assert( a.counter == 10 );
> +
> +  _Watchdog_Insert( &header, &a.Base, now + 1 );
> +  rtems_test_assert( header.first == &a.Base.Node.RBTree );
> +  rtems_test_assert( !test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 2 );
> +  rtems_test_assert( a.counter == 10 );
> +
> +  _Watchdog_Insert( &header, &b.Base, now + 1 );
> +  rtems_test_assert( header.first == &a.Base.Node.RBTree );
> +  rtems_test_assert( !test_watchdog_is_inactive( &b ) ) ;
> +  rtems_test_assert( b.Base.expire == 2 );
> +  rtems_test_assert( b.counter == 20 );
> +
> +  _Watchdog_Insert( &header, &c.Base, now + 2 );
> +  rtems_test_assert( header.first == &a.Base.Node.RBTree );
> +  rtems_test_assert( !test_watchdog_is_inactive( &c ) ) ;
> +  rtems_test_assert( c.Base.expire == 3 );
> +  rtems_test_assert( c.counter == 30 );
> +
> +  _Watchdog_Remove( &header, &a.Base );
> +  rtems_test_assert( header.first == &b.Base.Node.RBTree );
> +  rtems_test_assert( test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 2 );
> +  rtems_test_assert( a.counter == 10 );
> +
> +  _Watchdog_Remove( &header, &b.Base );
> +  rtems_test_assert( header.first == &c.Base.Node.RBTree );
> +  rtems_test_assert( test_watchdog_is_inactive( &b ) ) ;
> +  rtems_test_assert( b.Base.expire == 2 );
> +  rtems_test_assert( b.counter == 20 );
> +
> +  _Watchdog_Remove( &header, &c.Base );
> +  rtems_test_assert( header.first == NULL );
> +  rtems_test_assert( test_watchdog_is_inactive( &c ) ) ;
> +  rtems_test_assert( c.Base.expire == 3 );
> +  rtems_test_assert( c.counter == 30 );
> +
> +  _Watchdog_Insert( &header, &a.Base, now + 2 );
> +  rtems_test_assert( header.first == &a.Base.Node.RBTree );
> +  rtems_test_assert( !test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 3 );
> +  rtems_test_assert( a.counter == 10 );
> +
> +  _Watchdog_Insert( &header, &b.Base, now + 2 );
> +  rtems_test_assert( header.first == &a.Base.Node.RBTree );
> +  rtems_test_assert( !test_watchdog_is_inactive( &b ) ) ;
> +  rtems_test_assert( b.Base.expire == 3 );
> +  rtems_test_assert( b.counter == 20 );
> +
> +  _Watchdog_Insert( &header, &c.Base, now + 3 );
> +  rtems_test_assert( header.first == &a.Base.Node.RBTree );
> +  rtems_test_assert( !test_watchdog_is_inactive( &c ) ) ;
> +  rtems_test_assert( c.Base.expire == 4 );
> +  rtems_test_assert( c.counter == 30 );
> +
> +  now = test_watchdog_tick( &header, now );
> +  rtems_test_assert( !_RBTree_Is_empty( &header.Watchdogs ) );
> +  rtems_test_assert( header.first == &a.Base.Node.RBTree );
> +  rtems_test_assert( !test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 3 );
> +  rtems_test_assert( a.counter == 10 );
> +  rtems_test_assert( !test_watchdog_is_inactive( &b ) ) ;
> +  rtems_test_assert( b.Base.expire == 3 );
> +  rtems_test_assert( b.counter == 20 );
> +  rtems_test_assert( !test_watchdog_is_inactive( &c ) ) ;
> +  rtems_test_assert( c.Base.expire == 4 );
> +  rtems_test_assert( c.counter == 30 );
> +
> +  now = test_watchdog_tick( &header, now );
> +  rtems_test_assert( !_RBTree_Is_empty( &header.Watchdogs ) );
> +  rtems_test_assert( header.first == &c.Base.Node.RBTree );
> +  rtems_test_assert( test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 3 );
> +  rtems_test_assert( a.counter == 11 );
> +  rtems_test_assert( test_watchdog_is_inactive( &b ) ) ;
> +  rtems_test_assert( b.Base.expire == 3 );
> +  rtems_test_assert( b.counter == 21 );
> +  rtems_test_assert( !test_watchdog_is_inactive( &c ) ) ;
> +  rtems_test_assert( c.Base.expire == 4 );
> +  rtems_test_assert( c.counter == 30 );
> +
> +  now = test_watchdog_tick( &header, now );
> +  rtems_test_assert( _RBTree_Is_empty( &header.Watchdogs ) );
> +  rtems_test_assert( header.first == NULL );
> +  rtems_test_assert( test_watchdog_is_inactive( &a ) ) ;
> +  rtems_test_assert( a.Base.expire == 3 );
> +  rtems_test_assert( a.counter == 11 );
> +  rtems_test_assert( test_watchdog_is_inactive( &b ) ) ;
> +  rtems_test_assert( b.Base.expire == 3 );
> +  rtems_test_assert( b.counter == 21 );
> +  rtems_test_assert( test_watchdog_is_inactive( &c ) ) ;
> +  rtems_test_assert( c.Base.expire == 4 );
> +  rtems_test_assert( c.counter == 31 );
> +
> +  _Watchdog_Header_destroy( &header );
>  }
>
>  rtems_task Init(
> @@ -272,10 +223,8 @@ rtems_task Init(
>
>    TEST_BEGIN();
>
> +  test_watchdog_operations();
>    test_watchdog_static_init();
> -  test_watchdog_insert_and_remove();
> -  test_watchdog_remove_second_and_insert_first();
> -  test_watchdog_insert_with_iterator();
>
>    build_time( &time, 12, 31, 1988, 9, 0, 0, 0 );
>
> diff --git a/testsuites/tmtests/tmtimer01/tmtimer01.scn
> b/testsuites/tmtests/tmtimer01/tmtimer01.scn
> index ea882d4..db3ca01 100644
> --- a/testsuites/tmtests/tmtimer01/tmtimer01.scn
> +++ b/testsuites/tmtests/tmtimer01/tmtimer01.scn
> @@ -1,137 +1,137 @@
>  <TMTimer01 timerCount="65504">
>    <Sample>
> -    <ActiveTimers>0</ActiveTimers><First unit="ns">6397</First><Middle
> unit="ns">3290</Middle><Last unit="ns">1527</Last>
> +    <ActiveTimers>0</ActiveTimers><First unit="ns">8812</First><Middle
> unit="ns">1412</Middle><Last unit="ns">917</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>2</ActiveTimers><First unit="ns">1986</First><Middle
> unit="ns">1550</Middle><Last unit="ns">1314</Last>
> +    <ActiveTimers>2</ActiveTimers><First unit="ns">1602</First><Middle
> unit="ns">1010</Middle><Last unit="ns">1367</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>4</ActiveTimers><First unit="ns">1551</First><Middle
> unit="ns">2134</Middle><Last unit="ns">3072</Last>
> +    <ActiveTimers>4</ActiveTimers><First unit="ns">1524</First><Middle
> unit="ns">1089</Middle><Last unit="ns">1086</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>7</ActiveTimers><First unit="ns">2545</First><Middle
> unit="ns">3511</Middle><Last unit="ns">3404</Last>
> +    <ActiveTimers>7</ActiveTimers><First unit="ns">1791</First><Middle
> unit="ns">1121</Middle><Last unit="ns">1838</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>10</ActiveTimers><First unit="ns">1595</First><Middle
> unit="ns">2363</Middle><Last unit="ns">4287</Last>
> +    <ActiveTimers>10</ActiveTimers><First unit="ns">1488</First><Middle
> unit="ns">1016</Middle><Last unit="ns">2134</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>14</ActiveTimers><First unit="ns">1473</First><Middle
> unit="ns">2740</Middle><Last unit="ns">6069</Last>
> +    <ActiveTimers>14</ActiveTimers><First unit="ns">1527</First><Middle
> unit="ns">1698</Middle><Last unit="ns">3186</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>19</ActiveTimers><First unit="ns">1566</First><Middle
> unit="ns">3195</Middle><Last unit="ns">5993</Last>
> +    <ActiveTimers>19</ActiveTimers><First unit="ns">2078</First><Middle
> unit="ns">1665</Middle><Last unit="ns">3397</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>25</ActiveTimers><First unit="ns">1251</First><Middle
> unit="ns">2718</Middle><Last unit="ns">7307</Last>
> +    <ActiveTimers>25</ActiveTimers><First unit="ns">1519</First><Middle
> unit="ns">2368</Middle><Last unit="ns">4464</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>32</ActiveTimers><First unit="ns">2302</First><Middle
> unit="ns">5690</Middle><Last unit="ns">10269</Last>
> +    <ActiveTimers>32</ActiveTimers><First unit="ns">1243</First><Middle
> unit="ns">2623</Middle><Last unit="ns">3549</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>41</ActiveTimers><First unit="ns">1522</First><Middle
> unit="ns">8221</Middle><Last unit="ns">13424</Last>
> +    <ActiveTimers>41</ActiveTimers><First unit="ns">2368</First><Middle
> unit="ns">2578</Middle><Last unit="ns">4105</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>52</ActiveTimers><First unit="ns">1799</First><Middle
> unit="ns">8455</Middle><Last unit="ns">14820</Last>
> +    <ActiveTimers>52</ActiveTimers><First unit="ns">2322</First><Middle
> unit="ns">2563</Middle><Last unit="ns">4126</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>66</ActiveTimers><First unit="ns">1062</First><Middle
> unit="ns">12480</Middle><Last unit="ns">16590</Last>
> +    <ActiveTimers>66</ActiveTimers><First unit="ns">2499</First><Middle
> unit="ns">1855</Middle><Last unit="ns">4919</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>83</ActiveTimers><First unit="ns">1384</First><Middle
> unit="ns">11710</Middle><Last unit="ns">21854</Last>
> +    <ActiveTimers>83</ActiveTimers><First unit="ns">1689</First><Middle
> unit="ns">3128</Middle><Last unit="ns">5894</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>104</ActiveTimers><First unit="ns">1666</First><Middle
> unit="ns">15200</Middle><Last unit="ns">30951</Last>
> +    <ActiveTimers>104</ActiveTimers><First unit="ns">2301</First><Middle
> unit="ns">2647</Middle><Last unit="ns">4595</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>130</ActiveTimers><First unit="ns">1345</First><Middle
> unit="ns">17154</Middle><Last unit="ns">37942</Last>
> +    <ActiveTimers>130</ActiveTimers><First unit="ns">2880</First><Middle
> unit="ns">3183</Middle><Last unit="ns">6222</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>162</ActiveTimers><First unit="ns">1369</First><Middle
> unit="ns">22381</Middle><Last unit="ns">46929</Last>
> +    <ActiveTimers>162</ActiveTimers><First unit="ns">2597</First><Middle
> unit="ns">2376</Middle><Last unit="ns">7118</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>201</ActiveTimers><First unit="ns">2271</First><Middle
> unit="ns">35625</Middle><Last unit="ns">59972</Last>
> +    <ActiveTimers>201</ActiveTimers><First unit="ns">3519</First><Middle
> unit="ns">3466</Middle><Last unit="ns">6673</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>249</ActiveTimers><First unit="ns">1279</First><Middle
> unit="ns">37271</Middle><Last unit="ns">69662</Last>
> +    <ActiveTimers>249</ActiveTimers><First unit="ns">2829</First><Middle
> unit="ns">3177</Middle><Last unit="ns">7784</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>308</ActiveTimers><First unit="ns">864</First><Middle
> unit="ns">44580</Middle><Last unit="ns">87633</Last>
> +    <ActiveTimers>308</ActiveTimers><First unit="ns">2614</First><Middle
> unit="ns">3396</Middle><Last unit="ns">7338</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>381</ActiveTimers><First unit="ns">1078</First><Middle
> unit="ns">53821</Middle><Last unit="ns">106376</Last>
> +    <ActiveTimers>381</ActiveTimers><First unit="ns">3454</First><Middle
> unit="ns">4888</Middle><Last unit="ns">9114</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>470</ActiveTimers><First unit="ns">913</First><Middle
> unit="ns">67021</Middle><Last unit="ns">133201</Last>
> +    <ActiveTimers>470</ActiveTimers><First unit="ns">3397</First><Middle
> unit="ns">2443</Middle><Last unit="ns">7689</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>580</ActiveTimers><First unit="ns">1870</First><Middle
> unit="ns">79863</Middle><Last unit="ns">169394</Last>
> +    <ActiveTimers>580</ActiveTimers><First unit="ns">2233</First><Middle
> unit="ns">4410</Middle><Last unit="ns">9355</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>715</ActiveTimers><First unit="ns">1732</First><Middle
> unit="ns">99965</Middle><Last unit="ns">208901</Last>
> +    <ActiveTimers>715</ActiveTimers><First unit="ns">3787</First><Middle
> unit="ns">5891</Middle><Last unit="ns">6833</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>881</ActiveTimers><First unit="ns">1503</First><Middle
> unit="ns">138820</Middle><Last unit="ns">259314</Last>
> +    <ActiveTimers>881</ActiveTimers><First unit="ns">3839</First><Middle
> unit="ns">5089</Middle><Last unit="ns">9232</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>1085</ActiveTimers><First unit="ns">1096</First><Middle
> unit="ns">166404</Middle><Last unit="ns">337461</Last>
> +    <ActiveTimers>1085</ActiveTimers><First unit="ns">2838</First><Middle
> unit="ns">2739</Middle><Last unit="ns">11575</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>1336</ActiveTimers><First unit="ns">1383</First><Middle
> unit="ns">209434</Middle><Last unit="ns">445806</Last>
> +    <ActiveTimers>1336</ActiveTimers><First unit="ns">3256</First><Middle
> unit="ns">5011</Middle><Last unit="ns">9684</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>1645</ActiveTimers><First unit="ns">1787</First><Middle
> unit="ns">253904</Middle><Last unit="ns">533644</Last>
> +    <ActiveTimers>1645</ActiveTimers><First unit="ns">2293</First><Middle
> unit="ns">5262</Middle><Last unit="ns">10183</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>2025</ActiveTimers><First unit="ns">2082</First><Middle
> unit="ns">327384</Middle><Last unit="ns">657141</Last>
> +    <ActiveTimers>2025</ActiveTimers><First unit="ns">4436</First><Middle
> unit="ns">5934</Middle><Last unit="ns">8804</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>2492</ActiveTimers><First unit="ns">1843</First><Middle
> unit="ns">417457</Middle><Last unit="ns">814380</Last>
> +    <ActiveTimers>2492</ActiveTimers><First unit="ns">4506</First><Middle
> unit="ns">7284</Middle><Last unit="ns">10389</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>3067</ActiveTimers><First unit="ns">1980</First><Middle
> unit="ns">493511</Middle><Last unit="ns">977427</Last>
> +    <ActiveTimers>3067</ActiveTimers><First unit="ns">3832</First><Middle
> unit="ns">4990</Middle><Last unit="ns">9536</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>3774</ActiveTimers><First unit="ns">2695</First><Middle
> unit="ns">622065</Middle><Last unit="ns">1237577</Last>
> +    <ActiveTimers>3774</ActiveTimers><First unit="ns">5088</First><Middle
> unit="ns">4888</Middle><Last unit="ns">9633</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>4644</ActiveTimers><First unit="ns">1463</First><Middle
> unit="ns">827565</Middle><Last unit="ns">1565553</Last>
> +    <ActiveTimers>4644</ActiveTimers><First unit="ns">5590</First><Middle
> unit="ns">5749</Middle><Last unit="ns">8975</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>5714</ActiveTimers><First unit="ns">1866</First><Middle
> unit="ns">1053458</Middle><Last unit="ns">1914932</Last>
> +    <ActiveTimers>5714</ActiveTimers><First unit="ns">4854</First><Middle
> unit="ns">6813</Middle><Last unit="ns">11603</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>7030</ActiveTimers><First unit="ns">3481</First><Middle
> unit="ns">1266198</Middle><Last unit="ns">2450199</Last>
> +    <ActiveTimers>7030</ActiveTimers><First unit="ns">6139</First><Middle
> unit="ns">6132</Middle><Last unit="ns">12630</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>8649</ActiveTimers><First unit="ns">2773</First><Middle
> unit="ns">1558351</Middle><Last unit="ns">2967472</Last>
> +    <ActiveTimers>8649</ActiveTimers><First unit="ns">6877</First><Middle
> unit="ns">3852</Middle><Last unit="ns">10973</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>10640</ActiveTimers><First
> unit="ns">2086</First><Middle unit="ns">2003884</Middle><Last
> unit="ns">3766161</Last>
> +    <ActiveTimers>10640</ActiveTimers><First
> unit="ns">6532</First><Middle unit="ns">6097</Middle><Last
> unit="ns">11725</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>13089</ActiveTimers><First
> unit="ns">3911</First><Middle unit="ns">2501427</Middle><Last
> unit="ns">4619553</Last>
> +    <ActiveTimers>13089</ActiveTimers><First
> unit="ns">5284</First><Middle unit="ns">5392</Middle><Last
> unit="ns">13246</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>16101</ActiveTimers><First
> unit="ns">3276</First><Middle unit="ns">3189159</Middle><Last
> unit="ns">5886373</Last>
> +    <ActiveTimers>16101</ActiveTimers><First
> unit="ns">7077</First><Middle unit="ns">7572</Middle><Last
> unit="ns">14820</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>19806</ActiveTimers><First
> unit="ns">3801</First><Middle unit="ns">4005049</Middle><Last
> unit="ns">7394938</Last>
> +    <ActiveTimers>19806</ActiveTimers><First
> unit="ns">7132</First><Middle unit="ns">8335</Middle><Last
> unit="ns">11668</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>24363</ActiveTimers><First
> unit="ns">3088</First><Middle unit="ns">4977788</Middle><Last
> unit="ns">9138839</Last>
> +    <ActiveTimers>24363</ActiveTimers><First
> unit="ns">8676</First><Middle unit="ns">7919</Middle><Last
> unit="ns">13937</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>29968</ActiveTimers><First
> unit="ns">4089</First><Middle unit="ns">6133462</Middle><Last
> unit="ns">11361012</Last>
> +    <ActiveTimers>29968</ActiveTimers><First
> unit="ns">5970</First><Middle unit="ns">10978</Middle><Last
> unit="ns">16035</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>36862</ActiveTimers><First
> unit="ns">2059</First><Middle unit="ns">7870138</Middle><Last
> unit="ns">14319206</Last>
> +    <ActiveTimers>36862</ActiveTimers><First
> unit="ns">8804</First><Middle unit="ns">8767</Middle><Last
> unit="ns">13089</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>45342</ActiveTimers><First
> unit="ns">2224</First><Middle unit="ns">9917100</Middle><Last
> unit="ns">17754441</Last>
> +    <ActiveTimers>45342</ActiveTimers><First
> unit="ns">8608</First><Middle unit="ns">10305</Middle><Last
> unit="ns">15709</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>55772</ActiveTimers><First
> unit="ns">1979</First><Middle unit="ns">11815557</Middle><Last
> unit="ns">21907509</Last>
> +    <ActiveTimers>55772</ActiveTimers><First
> unit="ns">8949</First><Middle unit="ns">10031</Middle><Last
> unit="ns">16262</Last>
>    </Sample>
>    <Sample>
> -    <ActiveTimers>65503</ActiveTimers><First
> unit="ns">2404</First><Middle unit="ns">13694591</Middle><Last
> unit="ns">26215885</Last>
> +    <ActiveTimers>65503</ActiveTimers><First
> unit="ns">9199</First><Middle unit="ns">10309</Middle><Last
> unit="ns">19090</Last>
>    </Sample>
>  </TMTimer01>
> --
> 1.8.4.5
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20160303/ffaee83f/attachment-0002.html>


More information about the devel mailing list