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