summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/watchdogremove.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/watchdogremove.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/watchdogremove.c')
-rw-r--r--cpukit/score/src/watchdogremove.c172
1 files changed, 17 insertions, 155 deletions
diff --git a/cpukit/score/src/watchdogremove.c b/cpukit/score/src/watchdogremove.c
index 2aa72a4e75..2605a67fa4 100644
--- a/cpukit/score/src/watchdogremove.c
+++ b/cpukit/score/src/watchdogremove.c
@@ -1,17 +1,22 @@
/**
* @file
*
- * @brief Remove Watchdog from List
+ * @brief Remove Watchdog
* @ingroup ScoreWatchdog
*/
/*
- * COPYRIGHT (c) 1989-1999.
- * On-Line Applications Research Corporation (OAR).
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
*/
#if HAVE_CONFIG_H
@@ -19,161 +24,18 @@
#endif
#include <rtems/score/watchdogimpl.h>
-#include <rtems/score/assert.h>
-
-static void _Watchdog_Remove_it(
- Watchdog_Header *header,
- Watchdog_Control *the_watchdog
-)
-{
- Chain_Node *next;
- Watchdog_Interval delta;
- const Chain_Node *iterator_tail;
- Chain_Node *iterator_node;
-
- _Assert( the_watchdog->state == WATCHDOG_ACTIVE );
-
- the_watchdog->state = WATCHDOG_INACTIVE;
- the_watchdog->stop_time = _Watchdog_Ticks_since_boot;
-
- next = _Chain_Next( &the_watchdog->Node );
- delta = the_watchdog->delta_interval;
-
- if ( next != _Chain_Tail( &header->Watchdogs ) ) {
- Watchdog_Control *next_watchdog;
-
- next_watchdog = (Watchdog_Control *) next;
- next_watchdog->delta_interval += delta;
- }
-
- _Chain_Extract_unprotected( &the_watchdog->Node );
-
- iterator_node = _Chain_First( &header->Iterators );
- iterator_tail = _Chain_Immutable_tail( &header->Iterators );
-
- while ( iterator_node != iterator_tail ) {
- Watchdog_Iterator *iterator;
-
- iterator = (Watchdog_Iterator *) iterator_node;
-
- if ( iterator->current == next ) {
- iterator->delta_interval += delta;
- }
-
- if ( iterator->current == &the_watchdog->Node ) {
- Chain_Node *previous = _Chain_Previous( &the_watchdog->Node );
-
- iterator->current = previous;
-
- if ( previous != _Chain_Head( &header->Watchdogs ) ) {
- Watchdog_Control *previous_watchdog;
-
- previous_watchdog = (Watchdog_Control *) previous;
- iterator->delta_interval += previous_watchdog->delta_interval;
- }
- }
-
- iterator_node = _Chain_Next( iterator_node );
- }
-}
-Watchdog_States _Watchdog_Remove(
+void _Watchdog_Remove(
Watchdog_Header *header,
Watchdog_Control *the_watchdog
)
{
- ISR_lock_Context lock_context;
- Watchdog_States previous_state;
- Watchdog_Interval now;
-
- _Watchdog_Acquire( header, &lock_context );
- previous_state = the_watchdog->state;
- switch ( previous_state ) {
- case WATCHDOG_INACTIVE:
- break;
-
- case WATCHDOG_BEING_INSERTED:
-
- /*
- * It is not actually on the chain so just change the state and
- * the Insert operation we interrupted will be aborted.
- */
- the_watchdog->state = WATCHDOG_INACTIVE;
- now = _Watchdog_Ticks_since_boot;
- the_watchdog->start_time = now;
- the_watchdog->stop_time = now;
- break;
-
- case WATCHDOG_ACTIVE:
- _Watchdog_Remove_it( header, the_watchdog );
- break;
- }
-
- _Watchdog_Release( header, &lock_context );
- return( previous_state );
-}
-
-void _Watchdog_Tickle(
- Watchdog_Header *header
-)
-{
- ISR_lock_Context lock_context;
-
- _Watchdog_Acquire( header, &lock_context );
-
- if ( !_Watchdog_Is_empty( header ) ) {
- Watchdog_Control *first;
- Watchdog_Interval delta;
-
- first = _Watchdog_First( header );
- delta = first->delta_interval;
-
- /*
- * Although it is forbidden to insert watchdogs with a delta interval of
- * zero it is possible to observe watchdogs with a delta interval of zero
- * at this point. For example lets have a watchdog chain of one watchdog
- * with a delta interval of one and insert a new one with an initial value
- * of one. At the start of the insert procedure it will advance one step
- * and reduce its delta interval by one yielding zero. Now a tick happens.
- * This will remove the watchdog on the chain and update the insert
- * iterator. Now the insert operation continues and will insert the new
- * watchdog with a delta interval of zero.
- */
- if ( delta > 0 ) {
- --delta;
- first->delta_interval = delta;
+ if ( _Watchdog_Is_scheduled( the_watchdog ) ) {
+ if ( header->first == &the_watchdog->Node.RBTree ) {
+ _Watchdog_Next_first( header, the_watchdog );
}
- while ( delta == 0 ) {
- bool run;
- Watchdog_Service_routine_entry routine;
- Objects_Id id;
- void *user_data;
-
- run = ( first->state == WATCHDOG_ACTIVE );
-
- _Watchdog_Remove_it( header, first );
-
- routine = first->routine;
- id = first->id;
- user_data = first->user_data;
-
- _Watchdog_Release( header, &lock_context );
-
- if ( run ) {
- (*routine)( id, user_data );
- }
-
- _Watchdog_Acquire( header, &lock_context );
-
- if ( _Watchdog_Is_empty( header ) ) {
- break;
- }
-
- first = _Watchdog_First( header );
- delta = first->delta_interval;
- }
+ _RBTree_Extract( &header->Watchdogs, &the_watchdog->Node.RBTree );
+ _Watchdog_Set_state( the_watchdog, WATCHDOG_INACTIVE );
}
-
- _Watchdog_Release( header, &lock_context );
}