source: rtems/cpukit/score/include/rtems/score/watchdogimpl.h @ 90d8567

5
Last change on this file since 90d8567 was 90d8567, checked in by Sebastian Huber <sebastian.huber@…>, on 02/18/16 at 07:36:16

score: Distribute clock tick to all online CPUs

Update #2554.

  • Property mode set to 100644
File size: 11.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Inlined Routines in the Watchdog Handler
5 *
6 * This file contains the static inline implementation of all inlined
7 * routines in the Watchdog Handler.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2004.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_WATCHDOGIMPL_H
20#define _RTEMS_SCORE_WATCHDOGIMPL_H
21
22#include <rtems/score/watchdog.h>
23#include <rtems/score/assert.h>
24#include <rtems/score/chainimpl.h>
25#include <rtems/score/isrlock.h>
26#include <rtems/score/percpu.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/**
33 *  @addtogroup ScoreWatchdog
34 *  @{
35 */
36
37/**
38 * @brief Watchdog initializer for static initialization.
39 *
40 * @see _Watchdog_Initialize().
41 */
42#define WATCHDOG_INITIALIZER( routine, id, user_data ) \
43  { \
44    { NULL, NULL }, \
45    WATCHDOG_INACTIVE, \
46    0, 0, 0, 0, \
47    ( routine ), ( id ), ( user_data ) \
48  }
49
50/**
51 * @brief Iterator item to synchronize concurrent insert, remove and tickle
52 * operations.
53 */
54typedef struct {
55  /**
56   * @brief A node for a Watchdog_Header::Iterators chain.
57   */
58  Chain_Node Node;
59
60  /**
61   * @brief The current delta interval of the new watchdog to insert.
62   */
63  Watchdog_Interval delta_interval;
64
65  /**
66   * @brief The current watchdog of the chain on the way to insert the new
67   * watchdog.
68   */
69  Chain_Node *current;
70} Watchdog_Iterator;
71
72/**
73 * @brief Watchdog header.
74 */
75typedef struct {
76  /**
77   * @brief ISR lock to protect this watchdog chain.
78   */
79  ISR_LOCK_MEMBER( Lock )
80
81  /**
82   * @brief The chain of active or transient watchdogs.
83   */
84  Chain_Control Watchdogs;
85
86  /**
87   * @brief Currently active iterators.
88   *
89   * The iterators are registered in _Watchdog_Insert() and updated in case the
90   * watchdog chain changes.
91   */
92  Chain_Control Iterators;
93} Watchdog_Header;
94
95/**
96 *  @brief Watchdog chain which is managed at ticks.
97 *
98 *  This is the watchdog chain which is managed at ticks.
99 */
100extern Watchdog_Header _Watchdog_Ticks_header;
101
102/**
103 *  @brief Watchdog chain which is managed at second boundaries.
104 *
105 *  This is the watchdog chain which is managed at second boundaries.
106 */
107extern Watchdog_Header _Watchdog_Seconds_header;
108
109RTEMS_INLINE_ROUTINE void _Watchdog_Acquire(
110  Watchdog_Header  *header,
111  ISR_lock_Context *lock_context
112)
113{
114  _ISR_lock_ISR_disable_and_acquire( &header->Lock, lock_context );
115}
116
117RTEMS_INLINE_ROUTINE void _Watchdog_Release(
118  Watchdog_Header  *header,
119  ISR_lock_Context *lock_context
120)
121{
122  _ISR_lock_Release_and_ISR_enable( &header->Lock, lock_context );
123}
124
125RTEMS_INLINE_ROUTINE void _Watchdog_Flash(
126  Watchdog_Header  *header,
127  ISR_lock_Context *lock_context
128)
129{
130  _ISR_lock_Flash( &header->Lock, lock_context );
131}
132
133/**
134 *  @brief Initialize the watchdog handler.
135 *
136 *  This routine initializes the watchdog handler.  The watchdog
137 *  synchronization flag is initialized and the watchdog chains are
138 *  initialized and emptied.
139 */
140void _Watchdog_Handler_initialization( void );
141
142/**
143 *  @brief Performs a watchdog tick.
144 *
145 *  @param cpu The processor for this watchdog tick.
146 */
147void _Watchdog_Tick( Per_CPU_Control *cpu );
148
149/**
150 *  @brief Removes @a the_watchdog from the watchdog chain.
151 *
152 *  This routine removes @a the_watchdog from the watchdog chain on which
153 *  it resides and returns the state @a the_watchdog timer was in.
154 *
155 *  @param[in] header The watchdog chain.
156 *  @param[in] the_watchdog will be removed
157 *  @retval the state in which @a the_watchdog was in when removed
158 */
159Watchdog_States _Watchdog_Remove (
160  Watchdog_Header  *header,
161  Watchdog_Control *the_watchdog
162);
163
164/**
165 *  @brief Adjusts the header watchdog chain in the backward direction for
166 *  units ticks.
167 *
168 *  @param[in] header The watchdog chain.
169 *  @param[in] units The units of ticks to adjust.
170 */
171void _Watchdog_Adjust_backward(
172  Watchdog_Header   *header,
173  Watchdog_Interval  units
174);
175
176/**
177 * @brief Adjusts the watchdogs in backward direction in a locked context.
178 *
179 * The caller must be the owner of the watchdog lock and will be the owner
180 * after the call.
181 *
182 * @param[in] header The watchdog header.
183 * @param[in] units The units of ticks to adjust.
184 *
185 * @see _Watchdog_Adjust_forward().
186 */
187void _Watchdog_Adjust_backward_locked(
188  Watchdog_Header   *header,
189  Watchdog_Interval  units
190);
191
192/**
193 *  @brief Adjusts the header watchdog chain in the forward direction for units
194 *  ticks.
195 *
196 *  This may lead to several _Watchdog_Tickle() invocations.
197 *
198 *  @param[in] header The watchdog chain.
199 *  @param[in] units The units of ticks to adjust.
200 */
201void _Watchdog_Adjust_forward(
202  Watchdog_Header   *header,
203  Watchdog_Interval  units
204);
205
206/**
207 * @brief Adjusts the watchdogs in forward direction in a locked context.
208 *
209 * The caller must be the owner of the watchdog lock and will be the owner
210 * after the call.  This function may release and acquire the watchdog lock
211 * internally.
212 *
213 * @param[in] header The watchdog header.
214 * @param[in] units The units of ticks to adjust.
215 * @param[in] lock_context The lock context.
216 *
217 * @see _Watchdog_Adjust_forward().
218 */
219void _Watchdog_Adjust_forward_locked(
220  Watchdog_Header   *header,
221  Watchdog_Interval  units,
222  ISR_lock_Context  *lock_context
223);
224
225/**
226 *  @brief Inserts @a the_watchdog into the @a header watchdog chain
227 *  for a time of @a units.
228 *
229 *  This routine inserts @a the_watchdog into the @a header watchdog chain
230 *  for a time of @a units.
231 *  Update the delta interval counters.
232 *
233 *  @param[in] header is @a the_watchdog list to insert @a the_watchdog on
234 *  @param[in] the_watchdog is the watchdog to insert
235 */
236void _Watchdog_Insert (
237  Watchdog_Header  *header,
238  Watchdog_Control *the_watchdog
239);
240
241/**
242 * @brief Inserts the watchdog in a locked context.
243 *
244 * The caller must be the owner of the watchdog lock and will be the owner
245 * after the call.  This function may release and acquire the watchdog lock
246 * internally.
247 *
248 * @param[in] header The watchdog header.
249 * @param[in] the_watchdog The watchdog.
250 * @param[in] lock_context The lock context.
251 *
252 * @see _Watchdog_Insert().
253 */
254void _Watchdog_Insert_locked(
255  Watchdog_Header  *header,
256  Watchdog_Control *the_watchdog,
257  ISR_lock_Context *lock_context
258);
259
260/**
261 *  @brief This routine is invoked at appropriate intervals to update
262 *  the @a header watchdog chain.
263 *
264 *  This routine is invoked at appropriate intervals to update
265 *  the @a header watchdog chain.
266 *  This routine decrements the delta counter in response to a tick.
267 *
268 *  @param[in] header is the watchdog chain to tickle
269 */
270void _Watchdog_Tickle (
271  Watchdog_Header *header
272);
273
274/**
275 * @brief Pre-initializes a watchdog.
276 *
277 * This routine must be called before a watchdog is used in any way.  The
278 * exception are statically initialized watchdogs via WATCHDOG_INITIALIZER().
279 *
280 * @param[in] the_watchdog The uninitialized watchdog.
281 */
282RTEMS_INLINE_ROUTINE void _Watchdog_Preinitialize(
283  Watchdog_Control *the_watchdog
284)
285{
286  the_watchdog->state = WATCHDOG_INACTIVE;
287#if defined(RTEMS_DEBUG)
288  the_watchdog->routine = NULL;
289  the_watchdog->id = 0;
290  the_watchdog->user_data = NULL;
291#endif
292}
293
294/**
295 * This routine initializes the specified watchdog.  The watchdog is
296 * made inactive, the watchdog id and handler routine are set to the
297 * specified values.
298 */
299
300RTEMS_INLINE_ROUTINE void _Watchdog_Initialize(
301  Watchdog_Control               *the_watchdog,
302  Watchdog_Service_routine_entry  routine,
303  Objects_Id                      id,
304  void                           *user_data
305)
306{
307  _Assert( the_watchdog->state == WATCHDOG_INACTIVE );
308  the_watchdog->routine   = routine;
309  the_watchdog->id        = id;
310  the_watchdog->user_data = user_data;
311}
312
313/**
314 * This routine returns true if the watchdog timer is in the ACTIVE
315 * state, and false otherwise.
316 */
317
318RTEMS_INLINE_ROUTINE bool _Watchdog_Is_active(
319  Watchdog_Control *the_watchdog
320)
321{
322
323  return ( the_watchdog->state == WATCHDOG_ACTIVE );
324
325}
326
327/**
328 * This routine activates THE_WATCHDOG timer which is already
329 * on a watchdog chain.
330 */
331
332RTEMS_INLINE_ROUTINE void _Watchdog_Activate(
333  Watchdog_Control *the_watchdog
334)
335{
336
337  the_watchdog->state = WATCHDOG_ACTIVE;
338
339}
340
341/**
342 * This routine is invoked at each clock tick to update the ticks
343 * watchdog chain.
344 */
345
346RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_ticks( void )
347{
348
349  _Watchdog_Tickle( &_Watchdog_Ticks_header );
350
351}
352
353/**
354 * This routine is invoked at each clock tick to update the seconds
355 * watchdog chain.
356 */
357
358RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_seconds( void )
359{
360
361  _Watchdog_Tickle( &_Watchdog_Seconds_header );
362
363}
364
365/**
366 * This routine inserts THE_WATCHDOG into the ticks watchdog chain
367 * for a time of UNITS ticks.  The INSERT_MODE indicates whether
368 * THE_WATCHDOG is to be activated automatically or later, explicitly
369 * by the caller.
370 */
371
372RTEMS_INLINE_ROUTINE void _Watchdog_Insert_ticks(
373  Watchdog_Control      *the_watchdog,
374  Watchdog_Interval      units
375)
376{
377
378  the_watchdog->initial = units;
379
380  _Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
381
382}
383
384/**
385 * This routine inserts THE_WATCHDOG into the seconds watchdog chain
386 * for a time of UNITS seconds.  The INSERT_MODE indicates whether
387 * THE_WATCHDOG is to be activated automatically or later, explicitly
388 * by the caller.
389 */
390
391RTEMS_INLINE_ROUTINE void _Watchdog_Insert_seconds(
392  Watchdog_Control      *the_watchdog,
393  Watchdog_Interval      units
394)
395{
396
397  the_watchdog->initial = units;
398
399  _Watchdog_Insert( &_Watchdog_Seconds_header, the_watchdog );
400
401}
402
403RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_ticks(
404  Watchdog_Control *the_watchdog
405)
406{
407  return _Watchdog_Remove( &_Watchdog_Ticks_header, the_watchdog );
408}
409
410RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_seconds(
411  Watchdog_Control *the_watchdog
412)
413{
414  return _Watchdog_Remove( &_Watchdog_Seconds_header, the_watchdog );
415}
416
417/**
418 * This routine resets THE_WATCHDOG timer to its state at INSERT
419 * time.  This routine is valid only on interval watchdog timers
420 * and is used to make an interval watchdog timer fire "every" so
421 * many ticks.
422 */
423
424RTEMS_INLINE_ROUTINE void _Watchdog_Reset_ticks(
425  Watchdog_Control *the_watchdog
426)
427{
428
429  _Watchdog_Remove_ticks( the_watchdog );
430
431  _Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
432
433}
434
435/**
436 * This routine returns a pointer to the watchdog timer following
437 * THE_WATCHDOG on the watchdog chain.
438 */
439
440RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Next(
441  Watchdog_Control *the_watchdog
442)
443{
444
445  return ( (Watchdog_Control *) the_watchdog->Node.next );
446
447}
448
449/**
450 * This routine returns a pointer to the watchdog timer preceding
451 * THE_WATCHDOG on the watchdog chain.
452 */
453
454RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Previous(
455  Watchdog_Control *the_watchdog
456)
457{
458
459  return ( (Watchdog_Control *) the_watchdog->Node.previous );
460
461}
462
463/**
464 * This routine returns a pointer to the first watchdog timer
465 * on the watchdog chain HEADER.
466 */
467
468RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_First(
469  Watchdog_Header *header
470)
471{
472
473  return ( (Watchdog_Control *) _Chain_First( &header->Watchdogs ) );
474
475}
476
477/**
478 * This routine returns a pointer to the last watchdog timer
479 * on the watchdog chain HEADER.
480 */
481
482RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Last(
483  Watchdog_Header *header
484)
485{
486
487  return ( (Watchdog_Control *) _Chain_Last( &header->Watchdogs ) );
488
489}
490
491RTEMS_INLINE_ROUTINE bool _Watchdog_Is_empty(
492  const Watchdog_Header *header
493)
494{
495  return _Chain_Is_empty( &header->Watchdogs );
496}
497
498RTEMS_INLINE_ROUTINE void _Watchdog_Header_initialize(
499  Watchdog_Header *header
500)
501{
502  _ISR_lock_Initialize( &header->Lock, "Watchdog" );
503  _Chain_Initialize_empty( &header->Watchdogs );
504  _Chain_Initialize_empty( &header->Iterators );
505}
506
507/** @} */
508
509#ifdef __cplusplus
510}
511#endif
512
513#endif
514/* end of include file */
Note: See TracBrowser for help on using the repository browser.