source: rtems/cpukit/score/src/watchdogremove.c @ 0562060

4.115
Last change on this file since 0562060 was fd53d25, checked in by Sebastian Huber <sebastian.huber@…>, on 04/24/15 at 07:53:58

score: Move _Watchdog_Tickle()

Make internal function _Watchdog_Remove_it() static to avoid accidental
usage.

Update #2307.

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Remove Watchdog from List
5 * @ingroup ScoreWatchdog
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/watchdogimpl.h>
22#include <rtems/score/assert.h>
23
24static void _Watchdog_Remove_it(
25  Watchdog_Header   *header,
26  Watchdog_Control  *the_watchdog
27)
28{
29  Chain_Node        *next;
30  Watchdog_Interval  delta;
31  const Chain_Node  *iterator_tail;
32  Chain_Node        *iterator_node;
33
34  _Assert(
35    the_watchdog->state == WATCHDOG_ACTIVE
36      || the_watchdog->state == WATCHDOG_REMOVE_IT
37  );
38
39  the_watchdog->state = WATCHDOG_INACTIVE;
40  the_watchdog->stop_time = _Watchdog_Ticks_since_boot;
41
42  next = _Chain_Next( &the_watchdog->Node );
43  delta = the_watchdog->delta_interval;
44
45  if ( next != _Chain_Tail( &header->Watchdogs ) ) {
46    Watchdog_Control *next_watchdog;
47
48    next_watchdog = (Watchdog_Control *) next;
49    next_watchdog->delta_interval += delta;
50  }
51
52  _Chain_Extract_unprotected( &the_watchdog->Node );
53
54  iterator_node = _Chain_First( &header->Iterators );
55  iterator_tail = _Chain_Immutable_tail( &header->Iterators );
56
57  while ( iterator_node != iterator_tail ) {
58    Watchdog_Iterator *iterator;
59
60    iterator = (Watchdog_Iterator *) iterator_node;
61
62    if ( iterator->current == next ) {
63      iterator->delta_interval += delta;
64    }
65
66    if ( iterator->current == &the_watchdog->Node ) {
67      iterator->current = _Chain_Previous( &the_watchdog->Node );
68    }
69
70    iterator_node = _Chain_Next( iterator_node );
71  }
72}
73
74Watchdog_States _Watchdog_Remove(
75  Watchdog_Header  *header,
76  Watchdog_Control *the_watchdog
77)
78{
79  ISR_lock_Context  lock_context;
80  Watchdog_States   previous_state;
81  Watchdog_Interval now;
82
83  _Watchdog_Acquire( header, &lock_context );
84  previous_state = the_watchdog->state;
85  switch ( previous_state ) {
86    case WATCHDOG_INACTIVE:
87      break;
88
89    case WATCHDOG_BEING_INSERTED:
90
91      /*
92       *  It is not actually on the chain so just change the state and
93       *  the Insert operation we interrupted will be aborted.
94       */
95      the_watchdog->state = WATCHDOG_INACTIVE;
96      now = _Watchdog_Ticks_since_boot;
97      the_watchdog->start_time = now;
98      the_watchdog->stop_time = now;
99      break;
100
101    case WATCHDOG_ACTIVE:
102    case WATCHDOG_REMOVE_IT:
103      _Watchdog_Remove_it( header, the_watchdog );
104      break;
105  }
106
107  _Watchdog_Release( header, &lock_context );
108  return( previous_state );
109}
110
111void _Watchdog_Tickle(
112  Watchdog_Header *header
113)
114{
115  ISR_lock_Context lock_context;
116
117  _Watchdog_Acquire( header, &lock_context );
118
119  if ( !_Watchdog_Is_empty( header ) ) {
120    Watchdog_Control  *first;
121    Watchdog_Interval  delta;
122
123    first = _Watchdog_First( header );
124    delta = first->delta_interval;
125
126    /*
127     * Although it is forbidden to insert watchdogs with a delta interval of
128     * zero it is possible to observe watchdogs with a delta interval of zero
129     * at this point.  For example lets have a watchdog chain of one watchdog
130     * with a delta interval of one and insert a new one with an initial value
131     * of one.  At the start of the insert procedure it will advance one step
132     * and reduce its delta interval by one yielding zero.  Now a tick happens.
133     * This will remove the watchdog on the chain and update the insert
134     * iterator.  Now the insert operation continues and will insert the new
135     * watchdog with a delta interval of zero.
136     */
137    if ( delta > 0 ) {
138      --delta;
139      first->delta_interval = delta;
140    }
141
142    while ( delta == 0 ) {
143      bool                            run;
144      Watchdog_Service_routine_entry  routine;
145      Objects_Id                      id;
146      void                           *user_data;
147
148      run = ( first->state == WATCHDOG_ACTIVE );
149
150      _Watchdog_Remove_it( header, first );
151
152      routine = first->routine;
153      id = first->id;
154      user_data = first->user_data;
155
156      _Watchdog_Release( header, &lock_context );
157
158      if ( run ) {
159        (*routine)( id, user_data );
160      }
161
162      _Watchdog_Acquire( header, &lock_context );
163
164      if ( _Watchdog_Is_empty( header ) ) {
165        break;
166      }
167
168      first = _Watchdog_First( header );
169      delta = first->delta_interval;
170    }
171  }
172
173  _Watchdog_Release( header, &lock_context );
174}
Note: See TracBrowser for help on using the repository browser.