summaryrefslogtreecommitdiffstats
path: root/cpukit/rtems
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-04-10 15:31:31 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-19 12:00:43 +0200
commita382010c62455df73552eb5f0baa1faebe9702c7 (patch)
tree32764a1f1ce7aec8cd5dce3bf4a363ec4c2de179 /cpukit/rtems
parentscore: Move _Watchdog_Tickle() (diff)
downloadrtems-a382010c62455df73552eb5f0baa1faebe9702c7.tar.bz2
score: New timer server implementation
Use mostly the standard watchdog operations. Use a system event for synchronization. This implementation is simpler and offers better SMP performance. Close #2131.
Diffstat (limited to 'cpukit/rtems')
-rw-r--r--cpukit/rtems/include/rtems/rtems/event.h5
-rw-r--r--cpukit/rtems/include/rtems/rtems/timerimpl.h51
-rw-r--r--cpukit/rtems/src/timerserver.c570
3 files changed, 227 insertions, 399 deletions
diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h
index dce7de1165..012452a9d8 100644
--- a/cpukit/rtems/include/rtems/rtems/event.h
+++ b/cpukit/rtems/include/rtems/rtems/event.h
@@ -319,6 +319,11 @@ rtems_status_code rtems_event_receive (
#define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26
/**
+ * @brief Reserved system event for the timer server.
+ */
+#define RTEMS_EVENT_SYSTEM_TIMER_SERVER RTEMS_EVENT_30
+
+/**
* @brief Reserved system event for transient usage.
*/
#define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_31
diff --git a/cpukit/rtems/include/rtems/rtems/timerimpl.h b/cpukit/rtems/include/rtems/rtems/timerimpl.h
index 4f200efb75..e5b37aa5f1 100644
--- a/cpukit/rtems/include/rtems/rtems/timerimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/timerimpl.h
@@ -65,24 +65,43 @@ typedef struct {
Watchdog_Control System_watchdog;
/**
+ * @brief Remaining delta of the system watchdog.
+ */
+ Watchdog_Interval system_watchdog_delta;
+
+ /**
+ * @brief Unique identifier of the context which deals currently with the
+ * system watchdog.
+ */
+ Thread_Control *system_watchdog_helper;
+
+ /**
+ * @brief Each insert and tickle operation increases the generation count so
+ * that the system watchdog dealer notices updates of the watchdog chain.
+ */
+ uint32_t generation;
+
+ /**
* @brief Watchdog header managed by the timer server.
*/
Watchdog_Header Header;
/**
- * @brief Last known time snapshot of the timer server.
+ * @brief Last time snapshot of the timer server.
*
* The units may be ticks or seconds.
*/
- Watchdog_Interval volatile last_snapshot;
-} Timer_server_Watchdogs;
+ Watchdog_Interval last_snapshot;
-struct Timer_server_Control {
/**
- * @brief Timer server thread.
+ * @brief Current time snapshot of the timer server.
+ *
+ * The units may be ticks or seconds.
*/
- Thread_Control *thread;
+ Watchdog_Interval current_snapshot;
+} Timer_server_Watchdogs;
+struct Timer_server_Control {
/**
* @brief The cancel method of the timer server.
*/
@@ -102,26 +121,6 @@ struct Timer_server_Control {
* @brief TOD watchdogs triggered by the timer server.
*/
Timer_server_Watchdogs TOD_watchdogs;
-
- /**
- * @brief Chain of timers scheduled for insert.
- *
- * This pointer is not @c NULL whenever the interval and TOD chains are
- * processed. After the processing this list will be checked and if
- * necessary the processing will be restarted. Processing of these chains
- * can be only interrupted through interrupts.
- */
- Chain_Control *volatile insert_chain;
-
- /**
- * @brief Indicates that the timer server is active or not.
- *
- * The server is active after the delay on a system watchdog. The activity
- * period of the server ends when no more watchdogs managed by the server
- * fire. The system watchdogs must not be manipulated when the server is
- * active.
- */
- bool volatile active;
};
/**
diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c
index 15cbdfd59f..db38f48484 100644
--- a/cpukit/rtems/src/timerserver.c
+++ b/cpukit/rtems/src/timerserver.c
@@ -15,7 +15,7 @@
/* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
- * Copyright (c) 2009 embedded brains GmbH.
+ * Copyright (c) 2009-2015 embedded brains GmbH.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -26,200 +26,128 @@
#include "config.h"
#endif
+#include <rtems.h>
#include <rtems/rtems/timerimpl.h>
#include <rtems/rtems/tasksimpl.h>
-#include <rtems/score/isrlevel.h>
-#include <rtems/score/threadimpl.h>
#include <rtems/score/todimpl.h>
static Timer_server_Control _Timer_server_Default;
-static void _Timer_server_Stop_interval_system_watchdog(
- Timer_server_Control *ts
+static void _Timer_server_Cancel_method(
+ Timer_server_Control *ts,
+ Timer_Control *timer
)
{
- _Watchdog_Remove_ticks( &ts->Interval_watchdogs.System_watchdog );
+ if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
+ _Watchdog_Remove( &ts->Interval_watchdogs.Header, &timer->Ticker );
+ } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
+ _Watchdog_Remove( &ts->TOD_watchdogs.Header, &timer->Ticker );
+ }
}
-static void _Timer_server_Reset_interval_system_watchdog(
- Timer_server_Control *ts
-)
+static Watchdog_Interval _Timer_server_Get_ticks( void )
{
- ISR_Level level;
-
- _Timer_server_Stop_interval_system_watchdog( ts );
-
- _ISR_Disable( level );
- if ( !_Watchdog_Is_empty( &ts->Interval_watchdogs.Header ) ) {
- Watchdog_Interval delta_interval =
- _Watchdog_First( &ts->Interval_watchdogs.Header )->delta_interval;
- _ISR_Enable( level );
-
- /*
- * The unit is TICKS here.
- */
- _Watchdog_Insert_ticks(
- &ts->Interval_watchdogs.System_watchdog,
- delta_interval
- );
- } else {
- _ISR_Enable( level );
- }
+ return _Watchdog_Ticks_since_boot;
}
-static void _Timer_server_Stop_tod_system_watchdog(
- Timer_server_Control *ts
-)
+static Watchdog_Interval _Timer_server_Get_seconds( void )
{
- _Watchdog_Remove_seconds( &ts->TOD_watchdogs.System_watchdog );
+ return _TOD_Seconds_since_epoch();
}
-static void _Timer_server_Reset_tod_system_watchdog(
- Timer_server_Control *ts
+static void _Timer_server_Update_system_watchdog(
+ Timer_server_Watchdogs *watchdogs,
+ Watchdog_Header *system_header
)
{
- ISR_Level level;
+ ISR_lock_Context lock_context;
- _Timer_server_Stop_tod_system_watchdog( ts );
+ _Watchdog_Acquire( &watchdogs->Header, &lock_context );
- _ISR_Disable( level );
- if ( !_Watchdog_Is_empty( &ts->TOD_watchdogs.Header ) ) {
- Watchdog_Interval delta_interval =
- _Watchdog_First( &ts->TOD_watchdogs.Header )->delta_interval;
- _ISR_Enable( level );
+ if ( watchdogs->system_watchdog_helper == NULL ) {
+ Thread_Control *executing;
+ uint32_t my_generation;
- /*
- * The unit is SECONDS here.
- */
- _Watchdog_Insert_seconds(
- &ts->TOD_watchdogs.System_watchdog,
- delta_interval
- );
- } else {
- _ISR_Enable( level );
- }
-}
+ executing = _Thread_Executing;
+ watchdogs->system_watchdog_helper = executing;
-static void _Timer_server_Insert_timer(
- Timer_server_Control *ts,
- Timer_Control *timer
-)
-{
- if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
- _Watchdog_Insert( &ts->Interval_watchdogs.Header, &timer->Ticker );
- } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
- _Watchdog_Insert( &ts->TOD_watchdogs.Header, &timer->Ticker );
+ do {
+ my_generation = watchdogs->generation;
+
+ if ( !_Watchdog_Is_empty( &watchdogs->Header ) ) {
+ Watchdog_Control *first;
+ Watchdog_Interval delta;
+
+ first = _Watchdog_First( &watchdogs->Header );
+ delta = first->delta_interval;
+
+ if (
+ watchdogs->System_watchdog.state == WATCHDOG_INACTIVE
+ || delta != watchdogs->system_watchdog_delta
+ ) {
+ watchdogs->system_watchdog_delta = delta;
+ _Watchdog_Release( &watchdogs->Header, &lock_context );
+
+ _Watchdog_Remove( system_header, &watchdogs->System_watchdog );
+ watchdogs->System_watchdog.initial = delta;
+ _Watchdog_Insert( system_header, &watchdogs->System_watchdog );
+
+ _Watchdog_Acquire( &watchdogs->Header, &lock_context );
+ }
+ }
+ } while ( watchdogs->generation != my_generation );
+
+ watchdogs->system_watchdog_helper = NULL;
}
+
+ _Watchdog_Release( &watchdogs->Header, &lock_context );
}
-static void _Timer_server_Insert_timer_and_make_snapshot(
- Timer_server_Control *ts,
- Timer_Control *timer
+static void _Timer_server_Insert_timer(
+ Timer_server_Watchdogs *watchdogs,
+ Timer_Control *timer,
+ Watchdog_Header *system_header,
+ Watchdog_Interval (*get_ticks)( void )
)
{
- Watchdog_Control *first_watchdog;
- Watchdog_Interval delta_interval;
- Watchdog_Interval last_snapshot;
- Watchdog_Interval snapshot;
+ ISR_lock_Context lock_context;
+ Watchdog_Interval now;
Watchdog_Interval delta;
- ISR_Level level;
- /*
- * We have to update the time snapshots here, because otherwise we may have
- * problems with the integer range of the delta values. The time delta DT
- * from the last snapshot to now may be arbitrarily long. The last snapshot
- * is the reference point for the delta chain. Thus if we do not update the
- * reference point we have to add DT to the initial delta of the watchdog
- * being inserted. This could result in an integer overflow.
- */
+ _Watchdog_Acquire( &watchdogs->Header, &lock_context );
- _Thread_Disable_dispatch();
+ now = (*get_ticks)();
+ delta = now - watchdogs->last_snapshot;
+ watchdogs->last_snapshot = now;
+ watchdogs->current_snapshot = now;
- if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
- /*
- * We have to advance the last known ticks value of the server and update
- * the watchdog chain accordingly.
- */
- _ISR_Disable( level );
- snapshot = _Watchdog_Ticks_since_boot;
- last_snapshot = ts->Interval_watchdogs.last_snapshot;
- if ( !_Watchdog_Is_empty( &ts->Interval_watchdogs.Header ) ) {
- first_watchdog = _Watchdog_First( &ts->Interval_watchdogs.Header );
-
- /*
- * We assume adequate unsigned arithmetic here.
- */
- delta = snapshot - last_snapshot;
-
- delta_interval = first_watchdog->delta_interval;
- if (delta_interval > delta) {
- delta_interval -= delta;
- } else {
- delta_interval = 0;
- }
- first_watchdog->delta_interval = delta_interval;
- }
- ts->Interval_watchdogs.last_snapshot = snapshot;
- _ISR_Enable( level );
+ if ( watchdogs->system_watchdog_delta > delta ) {
+ watchdogs->system_watchdog_delta -= delta;
+ } else {
+ watchdogs->system_watchdog_delta = 0;
+ }
- _Watchdog_Insert( &ts->Interval_watchdogs.Header, &timer->Ticker );
+ if ( !_Watchdog_Is_empty( &watchdogs->Header ) ) {
+ Watchdog_Control *first = _Watchdog_First( &watchdogs->Header );
- if ( !ts->active ) {
- _Timer_server_Reset_interval_system_watchdog( ts );
- }
- } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
- /*
- * We have to advance the last known seconds value of the server and update
- * the watchdog chain accordingly.
- */
- _ISR_Disable( level );
- snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch();
- last_snapshot = ts->TOD_watchdogs.last_snapshot;
- if ( !_Watchdog_Is_empty( &ts->TOD_watchdogs.Header ) ) {
- first_watchdog = _Watchdog_First( &ts->TOD_watchdogs.Header );
- delta_interval = first_watchdog->delta_interval;
- if ( snapshot > last_snapshot ) {
- /*
- * We advanced in time.
- */
- delta = snapshot - last_snapshot;
- if (delta_interval > delta) {
- delta_interval -= delta;
- } else {
- delta_interval = 0;
- }
- } else {
- /*
- * Someone put us in the past.
- */
- delta = last_snapshot - snapshot;
- delta_interval += delta;
- }
- first_watchdog->delta_interval = delta_interval;
+ if ( first->delta_interval > delta ) {
+ first->delta_interval -= delta;
+ } else {
+ first->delta_interval = 0;
}
- ts->TOD_watchdogs.last_snapshot = snapshot;
- _ISR_Enable( level );
+ }
- _Watchdog_Insert( &ts->TOD_watchdogs.Header, &timer->Ticker );
+ _Watchdog_Insert_locked(
+ &watchdogs->Header,
+ &timer->Ticker,
+ &lock_context
+ );
- if ( !ts->active ) {
- _Timer_server_Reset_tod_system_watchdog( ts );
- }
- }
+ ++watchdogs->generation;
- _Thread_Enable_dispatch();
-}
+ _Watchdog_Release( &watchdogs->Header, &lock_context );
-static void _Timer_server_Cancel_method(
- Timer_server_Control *ts,
- Timer_Control *timer
-)
-{
- if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
- _Watchdog_Remove( &ts->Interval_watchdogs.Header, &timer->Ticker );
- } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
- _Watchdog_Remove( &ts->TOD_watchdogs.Header, &timer->Ticker );
- }
+ _Timer_server_Update_system_watchdog( watchdogs, system_header );
}
static void _Timer_server_Schedule_operation_method(
@@ -227,143 +155,71 @@ static void _Timer_server_Schedule_operation_method(
Timer_Control *timer
)
{
- if ( ts->insert_chain == NULL ) {
- _Timer_server_Insert_timer_and_make_snapshot( ts, timer );
- } else {
- /*
- * We interrupted a critical section of the timer server. The timer
- * server is not preemptible, so we must be in interrupt context here. No
- * thread dispatch will happen until the timer server finishes its
- * critical section. We have to use the protected chain methods because
- * we may be interrupted by a higher priority interrupt.
- */
- _Chain_Append( ts->insert_chain, &timer->Object.Node );
+ if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) {
+ _Timer_server_Insert_timer(
+ &ts->Interval_watchdogs,
+ timer,
+ &_Watchdog_Ticks_header,
+ _Timer_server_Get_ticks
+ );
+ } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
+ _Timer_server_Insert_timer(
+ &ts->TOD_watchdogs,
+ timer,
+ &_Watchdog_Seconds_header,
+ _Timer_server_Get_seconds
+ );
}
}
-static void _Timer_server_Process_interval_watchdogs(
+static void _Timer_server_Update_current_snapshot(
Timer_server_Watchdogs *watchdogs,
- Chain_Control *fire_chain
+ Watchdog_Interval (*get_ticks)( void )
)
{
- Watchdog_Interval snapshot = _Watchdog_Ticks_since_boot;
+ ISR_lock_Context lock_context;
- /*
- * We assume adequate unsigned arithmetic here.
- */
- Watchdog_Interval delta = snapshot - watchdogs->last_snapshot;
-
- watchdogs->last_snapshot = snapshot;
-
- _Watchdog_Adjust_to_chain( &watchdogs->Header, delta, fire_chain );
+ _Watchdog_Acquire( &watchdogs->Header, &lock_context );
+ watchdogs->current_snapshot = (*get_ticks)();
+ watchdogs->system_watchdog_delta = 0;
+ _Watchdog_Release( &watchdogs->Header, &lock_context );
}
-static void _Timer_server_Process_tod_watchdogs(
+static void _Timer_server_Tickle(
Timer_server_Watchdogs *watchdogs,
- Chain_Control *fire_chain
+ Watchdog_Header *system_header,
+ Watchdog_Interval (*get_ticks)( void ),
+ bool ticks
)
{
- Watchdog_Interval snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch();
- Watchdog_Interval last_snapshot = watchdogs->last_snapshot;
- Watchdog_Interval delta;
-
- /*
- * Process the seconds chain. Start by checking that the Time
- * of Day (TOD) has not been set backwards. If it has then
- * we want to adjust the watchdogs->Header to indicate this.
- */
- if ( snapshot > last_snapshot ) {
- /*
- * This path is for normal forward movement and cases where the
- * TOD has been set forward.
- */
- delta = snapshot - last_snapshot;
- _Watchdog_Adjust_to_chain( &watchdogs->Header, delta, fire_chain );
-
- } else if ( snapshot < last_snapshot ) {
- /*
- * The current TOD is before the last TOD which indicates that
- * TOD has been set backwards.
- */
- delta = last_snapshot - snapshot;
- _Watchdog_Adjust_backward( &watchdogs->Header, delta );
- }
-
- watchdogs->last_snapshot = snapshot;
-}
-
-static void _Timer_server_Process_insertions( Timer_server_Control *ts )
-{
- while ( true ) {
- Timer_Control *timer = (Timer_Control *) _Chain_Get( ts->insert_chain );
+ ISR_lock_Context lock_context;
+ Watchdog_Interval now;
+ Watchdog_Interval last;
- if ( timer == NULL ) {
- break;
- }
-
- _Timer_server_Insert_timer( ts, timer );
- }
-}
-
-static void _Timer_server_Get_watchdogs_that_fire_now(
- Timer_server_Control *ts,
- Chain_Control *insert_chain,
- Chain_Control *fire_chain
-)
-{
- /*
- * Afterwards all timer inserts are directed to this chain and the interval
- * and TOD chains will be no more modified by other parties.
- */
- ts->insert_chain = insert_chain;
+ _Watchdog_Acquire( &watchdogs->Header, &lock_context );
- while ( true ) {
- ISR_Level level;
+ now = watchdogs->current_snapshot;
+ last = watchdogs->last_snapshot;
+ watchdogs->last_snapshot = now;
- /*
- * Remove all the watchdogs that need to fire so we can invoke them.
- */
- _Timer_server_Process_interval_watchdogs(
- &ts->Interval_watchdogs,
- fire_chain
+ if ( ticks || now >= last ) {
+ _Watchdog_Adjust_forward_locked(
+ &watchdogs->Header,
+ now - last,
+ &lock_context
+ );
+ } else {
+ _Watchdog_Adjust_backward_locked(
+ &watchdogs->Header,
+ last - now
);
- _Timer_server_Process_tod_watchdogs( &ts->TOD_watchdogs, fire_chain );
-
- /*
- * The insertions have to take place here, because they reference the
- * current time. The previous process methods take a snapshot of the
- * current time. In case someone inserts a watchdog with an initial value
- * of zero it will be processed in the next iteration of the timer server
- * body loop.
- */
- _Timer_server_Process_insertions( ts );
-
- _ISR_Disable( level );
- if ( _Chain_Is_empty( insert_chain ) ) {
- ts->insert_chain = NULL;
- _ISR_Enable( level );
-
- break;
- } else {
- _ISR_Enable( level );
- }
}
-}
-/* FIXME: This locking approach for SMP is improvable! */
+ ++watchdogs->generation;
-static void _Timer_server_SMP_lock_aquire( void )
-{
-#if defined( RTEMS_SMP )
- _Thread_Disable_dispatch();
-#endif
-}
+ _Watchdog_Release( &watchdogs->Header, &lock_context );
-static void _Timer_server_SMP_lock_release( void )
-{
-#if defined( RTEMS_SMP )
- _Thread_Enable_dispatch();
-#endif
+ _Timer_server_Update_system_watchdog( watchdogs, system_header );
}
/**
@@ -380,81 +236,73 @@ static rtems_task _Timer_server_Body(
)
{
Timer_server_Control *ts = (Timer_server_Control *) arg;
- Chain_Control insert_chain;
- Chain_Control fire_chain;
- _Chain_Initialize_empty( &insert_chain );
- _Chain_Initialize_empty( &fire_chain );
+ while ( true ) {
+ rtems_event_set events;
- _Timer_server_SMP_lock_aquire();
+ _Timer_server_Tickle(
+ &ts->Interval_watchdogs,
+ &_Watchdog_Ticks_header,
+ _Timer_server_Get_ticks,
+ true
+ );
- while ( true ) {
- _Timer_server_Get_watchdogs_that_fire_now( ts, &insert_chain, &fire_chain );
-
- if ( !_Chain_Is_empty( &fire_chain ) ) {
- /*
- * Fire the watchdogs.
- */
- while ( true ) {
- Watchdog_Control *watchdog;
- ISR_Level level;
-
- /*
- * It is essential that interrupts are disable here since an interrupt
- * service routine may remove a watchdog from the chain.
- */
- _ISR_Disable( level );
- watchdog = (Watchdog_Control *) _Chain_Get_unprotected( &fire_chain );
- if ( watchdog != NULL ) {
- watchdog->state = WATCHDOG_INACTIVE;
- _ISR_Enable( level );
- } else {
- _ISR_Enable( level );
-
- break;
- }
+ _Timer_server_Tickle(
+ &ts->TOD_watchdogs,
+ &_Watchdog_Seconds_header,
+ _Timer_server_Get_seconds,
+ false
+ );
- _Timer_server_SMP_lock_release();
+ (void) rtems_event_system_receive(
+ RTEMS_EVENT_SYSTEM_TIMER_SERVER,
+ RTEMS_EVENT_ALL | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+ }
+}
- /*
- * The timer server may block here and wait for resources or time.
- * The system watchdogs are inactive and will remain inactive since
- * the active flag of the timer server is true.
- */
- (*watchdog->routine)( watchdog->id, watchdog->user_data );
+static void _Timer_server_Wakeup(
+ Objects_Id id,
+ void *arg
+)
+{
+ Timer_server_Control *ts = arg;
- _Timer_server_SMP_lock_aquire();
- }
- } else {
- ts->active = false;
+ _Timer_server_Update_current_snapshot(
+ &ts->Interval_watchdogs,
+ _Timer_server_Get_ticks
+ );
- /*
- * Block until there is something to do.
- */
-#if !defined( RTEMS_SMP )
- _Thread_Disable_dispatch();
-#endif
- _Thread_Set_state( ts->thread, STATES_DELAYING );
- _Timer_server_Reset_interval_system_watchdog( ts );
- _Timer_server_Reset_tod_system_watchdog( ts );
-#if !defined( RTEMS_SMP )
- _Thread_Enable_dispatch();
-#endif
+ _Timer_server_Update_current_snapshot(
+ &ts->TOD_watchdogs,
+ _Timer_server_Get_seconds
+ );
- _Timer_server_SMP_lock_release();
- _Timer_server_SMP_lock_aquire();
+ (void) rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TIMER_SERVER );
+}
- ts->active = true;
+static void _Timer_server_Initialize_watchdogs(
+ Timer_server_Control *ts,
+ rtems_id id,
+ Timer_server_Watchdogs *watchdogs,
+ Watchdog_Interval (*get_ticks)( void )
+)
+{
+ Watchdog_Interval now;
- /*
- * Maybe an interrupt did reset the system timers, so we have to stop
- * them here. Since we are active now, there will be no more resets
- * until we are inactive again.
- */
- _Timer_server_Stop_interval_system_watchdog( ts );
- _Timer_server_Stop_tod_system_watchdog( ts );
- }
- }
+ now = (*get_ticks)();
+ watchdogs->last_snapshot = now;
+ watchdogs->current_snapshot = now;
+
+ _Watchdog_Header_initialize( &watchdogs->Header );
+ _Watchdog_Initialize(
+ &watchdogs->System_watchdog,
+ _Timer_server_Wakeup,
+ id,
+ ts
+ );
}
/**
@@ -542,36 +390,18 @@ rtems_status_code rtems_timer_initiate_server(
* Timer Server so we do not have to have a critical section.
*/
- /*
- * We work with the TCB pointer, not the ID, so we need to convert
- * to a TCB pointer from here out.
- */
- ts->thread = (Thread_Control *)_Objects_Get_local_object(
- &_RTEMS_tasks_Information,
- _Objects_Get_index(id)
+ _Timer_server_Initialize_watchdogs(
+ ts,
+ id,
+ &ts->Interval_watchdogs,
+ _Timer_server_Get_ticks
);
- /*
- * Initialize the timer lists that the server will manage.
- */
- _Watchdog_Header_initialize( &ts->Interval_watchdogs.Header );
- _Watchdog_Header_initialize( &ts->TOD_watchdogs.Header );
-
- /*
- * Initialize the timers that will be used to control when the
- * Timer Server wakes up and services the task-based timers.
- */
- _Watchdog_Initialize(
- &ts->Interval_watchdogs.System_watchdog,
- _Thread_Delay_ended,
- 0,
- ts->thread
- );
- _Watchdog_Initialize(
- &ts->TOD_watchdogs.System_watchdog,
- _Thread_Delay_ended,
- 0,
- ts->thread
+ _Timer_server_Initialize_watchdogs(
+ ts,
+ id,
+ &ts->TOD_watchdogs,
+ _Timer_server_Get_seconds
);
/*
@@ -581,12 +411,6 @@ rtems_status_code rtems_timer_initiate_server(
ts->cancel = _Timer_server_Cancel_method;
ts->schedule_operation = _Timer_server_Schedule_operation_method;
- ts->Interval_watchdogs.last_snapshot = _Watchdog_Ticks_since_boot;
- ts->TOD_watchdogs.last_snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch();
-
- ts->insert_chain = NULL;
- ts->active = false;
-
/*
* The default timer server is now available.
*/