source: rtems/cpukit/score/src/watchdogtickle.c @ 1ccbd052

4.115
Last change on this file since 1ccbd052 was 1ccbd052, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 15, 2015 at 8:53:29 AM

score: Add Watchdog_Iterator

Rewrite the _Watchdog_Insert(), _Watchdog_Remove() and
_Watchdog_Tickle() functions to use iterator items to synchronize
concurrent operations. This makes it possible to get rid of the global
variables _Watchdog_Sync_level and _Watchdog_Sync_count which are a
blocking point for scalable SMP solutions.

Update #2307.

  • Property mode set to 100644
File size: 2.2 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreWatchdog
5 * @brief Watchdog Tickle
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
23void _Watchdog_Tickle(
24  Watchdog_Header *header
25)
26{
27  ISR_lock_Context lock_context;
28
29  _Watchdog_Acquire( header, &lock_context );
30
31  if ( !_Watchdog_Is_empty( header ) ) {
32    Watchdog_Control  *first;
33    Watchdog_Interval  delta;
34
35    first = _Watchdog_First( header );
36    delta = first->delta_interval;
37
38    /*
39     * Although it is forbidden to insert watchdogs with a delta interval of
40     * zero it is possible to observe watchdogs with a delta interval of zero
41     * at this point.  For example lets have a watchdog chain of one watchdog
42     * with a delta interval of one and insert a new one with an initial value
43     * of one.  At the start of the insert procedure it will advance one step
44     * and reduce its delta interval by one yielding zero.  Now a tick happens.
45     * This will remove the watchdog on the chain and update the insert
46     * iterator.  Now the insert operation continues and will insert the new
47     * watchdog with a delta interval of zero.
48     */
49    if ( delta > 0 ) {
50      --delta;
51      first->delta_interval = delta;
52    }
53
54    while ( delta == 0 ) {
55      bool                            run;
56      Watchdog_Service_routine_entry  routine;
57      Objects_Id                      id;
58      void                           *user_data;
59
60      run = ( first->state == WATCHDOG_ACTIVE );
61
62      _Watchdog_Remove_it( header, first );
63
64      routine = first->routine;
65      id = first->id;
66      user_data = first->user_data;
67
68      _Watchdog_Release( header, &lock_context );
69
70      if ( run ) {
71        (*routine)( id, user_data );
72      }
73
74      _Watchdog_Acquire( header, &lock_context );
75
76      if ( _Watchdog_Is_empty( header ) ) {
77        break;
78      }
79
80      first = _Watchdog_First( header );
81      delta = first->delta_interval;
82    }
83  }
84
85  _Watchdog_Release( header, &lock_context );
86}
Note: See TracBrowser for help on using the repository browser.