summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/watchdogtick.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-02-18 08:36:26 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-03-04 13:36:10 +0100
commit03b900d3ed120ea919ea3eded7edbece3488cff3 (patch)
tree182781fc14fe15fd67caeb80e46f1c58495839c2 /cpukit/score/src/watchdogtick.c
parentscore: Distribute clock tick to all online CPUs (diff)
downloadrtems-03b900d3ed120ea919ea3eded7edbece3488cff3.tar.bz2
score: Replace watchdog handler implementation
Use a red-black tree instead of delta chains. Close #2344. Update #2554. Update #2555. Close #2606.
Diffstat (limited to 'cpukit/score/src/watchdogtick.c')
-rw-r--r--cpukit/score/src/watchdogtick.c78
1 files changed, 67 insertions, 11 deletions
diff --git a/cpukit/score/src/watchdogtick.c b/cpukit/score/src/watchdogtick.c
index e89c088350..ab7eadcf1d 100644
--- a/cpukit/score/src/watchdogtick.c
+++ b/cpukit/score/src/watchdogtick.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2015, 2016 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -12,25 +12,81 @@
* http://www.rtems.org/license/LICENSE.
*/
-#include <rtems/score/assert.h>
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/watchdogimpl.h>
#include <rtems/score/schedulerimpl.h>
#include <rtems/score/threaddispatch.h>
-#include <rtems/score/todimpl.h>
-#include <rtems/score/watchdogimpl.h>
+#include <rtems/score/timecounter.h>
-#if HAVE_CONFIG_H
-#include "config.h"
+void _Watchdog_Do_tickle(
+ Watchdog_Header *header,
+ uint64_t now,
+#ifdef RTEMS_SMP
+ ISR_lock_Control *lock,
#endif
+ ISR_lock_Context *lock_context
+)
+{
+ while ( true ) {
+ Watchdog_Control *the_watchdog;
+
+ the_watchdog = (Watchdog_Control *) header->first;
+
+ if ( the_watchdog == NULL ) {
+ break;
+ }
+
+ if ( the_watchdog->expire <= now ) {
+ Watchdog_Service_routine_entry routine;
+
+ _Watchdog_Next_first( header, the_watchdog );
+ _RBTree_Extract( &header->Watchdogs, &the_watchdog->Node.RBTree );
+ _Watchdog_Set_state( the_watchdog, WATCHDOG_INACTIVE );
+ routine = the_watchdog->routine;
+
+ _ISR_lock_Release_and_ISR_enable( lock, lock_context );
+ ( *routine )( the_watchdog );
+ _ISR_lock_ISR_disable_and_acquire( lock, lock_context );
+ } else {
+ break;
+ }
+ }
+
+ _ISR_lock_Release_and_ISR_enable( lock, lock_context );
+}
void _Watchdog_Tick( Per_CPU_Control *cpu )
{
- _Assert( !_Thread_Dispatch_is_enabled() );
+ ISR_lock_Context lock_context;
+ uint64_t ticks;
+ struct timespec now;
if ( _Per_CPU_Is_boot_processor( cpu ) ) {
- _TOD_Tickle_ticks();
+ ++_Watchdog_Ticks_since_boot;
+ }
- _Watchdog_Tickle_ticks();
+ _ISR_lock_ISR_disable_and_acquire( &cpu->Watchdog.Lock, &lock_context );
- _Scheduler_Tick();
- }
+ ticks = cpu->Watchdog.ticks;
+ _Assert( ticks < UINT64_MAX );
+ ++ticks;
+ cpu->Watchdog.ticks = ticks;
+
+ _Watchdog_Tickle(
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
+ ticks,
+ &cpu->Watchdog.Lock,
+ &lock_context
+ );
+
+ _Timecounter_Getnanotime( &now );
+ _Watchdog_Per_CPU_tickle_absolute(
+ cpu,
+ _Watchdog_Ticks_from_timespec( &now )
+ );
+
+ _Scheduler_Tick( cpu );
}