RTEMS  5.1
watchdogimpl.h
Go to the documentation of this file.
1 
12 /*
13  * COPYRIGHT (c) 1989-2004.
14  * On-Line Applications Research Corporation (OAR).
15  *
16  * The license and distribution terms for this file may be
17  * found in the file LICENSE in this distribution or at
18  * http://www.rtems.org/license/LICENSE.
19  */
20 
21 #ifndef _RTEMS_SCORE_WATCHDOGIMPL_H
22 #define _RTEMS_SCORE_WATCHDOGIMPL_H
23 
24 #include <rtems/score/watchdog.h>
26 #include <rtems/score/assert.h>
27 #include <rtems/score/isrlock.h>
28 #include <rtems/score/percpu.h>
29 #include <rtems/score/rbtreeimpl.h>
30 
31 #include <sys/types.h>
32 #include <sys/timespec.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
47 typedef enum {
52 
57 
62 
70 
78 #if defined(RTEMS_SMP)
79  #define WATCHDOG_INITIALIZER( routine ) \
80  { \
81  { { { NULL, NULL, NULL, WATCHDOG_INACTIVE } } }, \
82  &_Per_CPU_Information[ 0 ].per_cpu, \
83  ( routine ), \
84  0 \
85  }
86 #else
87  #define WATCHDOG_INITIALIZER( routine ) \
88  { \
89  { { { NULL, NULL, NULL, WATCHDOG_INACTIVE } } }, \
90  ( routine ), \
91  0 \
92  }
93 #endif
94 
101  Watchdog_Header *header
102 )
103 {
105  header->first = NULL;
106 }
107 
116  const Watchdog_Header *header
117 )
118 {
119  return (Watchdog_Control *) header->first;
120 }
121 
128  Watchdog_Header *header
129 )
130 {
131  /* Do nothing */
132  (void) header;
133 }
134 
140 void _Watchdog_Tick( struct Per_CPU_Control *cpu );
141 
150  const Watchdog_Control *the_watchdog
151 )
152 {
153  return RB_COLOR( &the_watchdog->Node.RBTree, Node );
154 }
155 
163  Watchdog_Control *the_watchdog,
164  Watchdog_State state
165 )
166 {
167  RB_COLOR( &the_watchdog->Node.RBTree, Node ) = state;
168 }
169 
178  const Watchdog_Control *the_watchdog
179 )
180 {
181 #if defined(RTEMS_SMP)
182  return the_watchdog->cpu;
183 #else
184  return _Per_CPU_Get_by_index( 0 );
185 #endif
186 }
187 
195  Watchdog_Control *the_watchdog,
196  Per_CPU_Control *cpu
197 )
198 {
199 #if defined(RTEMS_SMP)
200  the_watchdog->cpu = cpu;
201 #else
202  (void) cpu;
203 #endif
204 }
205 
215  Watchdog_Control *the_watchdog,
216  Per_CPU_Control *cpu
217 )
218 {
219  _Watchdog_Set_CPU( the_watchdog, cpu );
220  _Watchdog_Set_state( the_watchdog, WATCHDOG_INACTIVE );
221 
222 #if defined(RTEMS_DEBUG)
223  the_watchdog->routine = NULL;
224  the_watchdog->expire = 0;
225 #endif
226 }
227 
237  Watchdog_Control *the_watchdog,
239 )
240 {
241  _Assert( _Watchdog_Get_state( the_watchdog ) == WATCHDOG_INACTIVE );
242  the_watchdog->routine = routine;
243 }
244 
257  Watchdog_Header *header,
258  Watchdog_Control *first,
259  uint64_t now,
260 #if defined(RTEMS_SMP)
261  ISR_lock_Control *lock,
262 #endif
263  ISR_lock_Context *lock_context
264 );
265 
266 #if defined(RTEMS_SMP)
267  #define _Watchdog_Tickle( header, first, now, lock, lock_context ) \
268  _Watchdog_Do_tickle( header, first, now, lock, lock_context )
269 #else
270  #define _Watchdog_Tickle( header, first, now, lock, lock_context ) \
271  _Watchdog_Do_tickle( header, first, now, lock_context )
272 #endif
273 
284 void _Watchdog_Insert(
285  Watchdog_Header *header,
286  Watchdog_Control *the_watchdog,
287  uint64_t expire
288 );
289 
299 void _Watchdog_Remove(
300  Watchdog_Header *header,
301  Watchdog_Control *the_watchdog
302 );
303 
319  Watchdog_Header *header,
320  Watchdog_Control *the_watchdog,
321  uint64_t now
322 )
323 {
324  uint64_t expire;
325  uint64_t remaining;
326 
327  expire = the_watchdog->expire;
328 
329  if ( now < expire ) {
330  remaining = expire - now;
331  } else {
332  remaining = 0;
333  }
334 
335  _Watchdog_Remove( header, the_watchdog );
336 
337  return remaining;
338 }
339 
349  const Watchdog_Control *the_watchdog
350 )
351 {
352  return _Watchdog_Get_state( the_watchdog ) < WATCHDOG_INACTIVE;
353 }
354 
367  Watchdog_Header *header,
368  Watchdog_Control *the_watchdog
369 )
370 {
371  RBTree_Node *node = _RBTree_Right( &the_watchdog->Node.RBTree );
372 
373  if ( node != NULL ) {
374  RBTree_Node *left;
375 
376  while ( ( left = _RBTree_Left( node ) ) != NULL ) {
377  node = left;
378  }
379 
380  header->first = node;
381  } else {
382  header->first = _RBTree_Parent( &the_watchdog->Node.RBTree );
383  }
384 }
385 
389 #define WATCHDOG_MAXIMUM_TICKS UINT64_MAX
390 
391 #define WATCHDOG_NANOSECONDS_PER_SECOND 1000000000
392 
401 #define WATCHDOG_BITS_FOR_1E9_NANOSECONDS 30
402 
409 #define WATCHDOG_MAX_SECONDS 0x3ffffffff
410 
420  const struct timespec *ts
421 )
422 {
423  return ts != NULL
424  && (unsigned long) ts->tv_nsec < WATCHDOG_NANOSECONDS_PER_SECOND;
425 }
426 
436  const struct timespec *ts
437 )
438 {
439  return _Watchdog_Is_valid_timespec( ts ) && ts->tv_sec >= 0;
440 }
441 
453  struct timespec *now,
454  const struct timespec *delta
455 )
456 {
457  uint64_t sec;
458 
459  if ( !_Watchdog_Is_valid_interval_timespec( delta ) ) {
460  return NULL;
461  }
462 
463  sec = (uint64_t) now->tv_sec;
464  sec += (uint64_t) delta->tv_sec;
465  now->tv_nsec += delta->tv_nsec;
466 
467  /* We have 2 * (2**63 - 1) + 1 == UINT64_MAX */
468  if ( now->tv_nsec >= WATCHDOG_NANOSECONDS_PER_SECOND ) {
469  now->tv_nsec -= WATCHDOG_NANOSECONDS_PER_SECOND;
470  ++sec;
471  }
472 
473  if ( sec <= INT64_MAX ) {
474  now->tv_sec = sec;
475  } else {
476  now->tv_sec = INT64_MAX;
477  }
478 
479  return now;
480 }
481 
491  const struct timespec *ts
492 )
493 {
494  return ts->tv_sec > WATCHDOG_MAX_SECONDS;
495 }
496 
505  uint32_t seconds
506 )
507 {
508  uint64_t ticks = seconds;
509 
511 
512  return ticks;
513 }
514 
523  const struct timespec *ts
524 )
525 {
526  uint64_t ticks;
527 
529  _Assert( ts->tv_sec >= 0 );
531 
532  ticks = (uint64_t) ts->tv_sec;
534  ticks |= (uint32_t) ts->tv_nsec;
535 
536  return ticks;
537 }
538 
547 {
548  uint64_t ticks = ( sbt >> 32 ) << WATCHDOG_BITS_FOR_1E9_NANOSECONDS;
549 
550  ticks |= ( (uint64_t) 1000000000 * (uint32_t) sbt ) >> 32;
551 
552  return ticks;
553 }
554 
562  Per_CPU_Control *cpu,
563  ISR_lock_Context *lock_context
564 )
565 {
566  _ISR_lock_Acquire( &cpu->Watchdog.Lock, lock_context );
567 }
568 
576  Per_CPU_Control *cpu,
577  ISR_lock_Context *lock_context
578 )
579 {
580  _ISR_lock_Release( &cpu->Watchdog.Lock, lock_context );
581 }
582 
594  Watchdog_Control *the_watchdog,
595  Per_CPU_Control *cpu,
596  Watchdog_Interval ticks
597 )
598 {
599  ISR_lock_Context lock_context;
600  Watchdog_Header *header;
601  uint64_t expire;
602 
603  header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
604 
605  _Watchdog_Set_CPU( the_watchdog, cpu );
606 
607  _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
608  expire = ticks + cpu->Watchdog.ticks;
609  _Watchdog_Insert(header, the_watchdog, expire);
610  _Watchdog_Per_CPU_release_critical( cpu, &lock_context );
611  return expire;
612 }
613 
626  Watchdog_Control *the_watchdog,
627  Per_CPU_Control *cpu,
628  Watchdog_Header *header,
629  uint64_t expire
630 )
631 {
632  ISR_lock_Context lock_context;
633 
634  _Watchdog_Set_CPU( the_watchdog, cpu );
635 
636  _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
637  _Watchdog_Insert( header, the_watchdog, expire );
638  _Watchdog_Per_CPU_release_critical( cpu, &lock_context );
639  return expire;
640 }
641 
650  Watchdog_Control *the_watchdog,
651  Per_CPU_Control *cpu,
652  Watchdog_Header *header
653 )
654 {
655  ISR_lock_Context lock_context;
656 
657  _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
659  header,
660  the_watchdog
661  );
662  _Watchdog_Per_CPU_release_critical( cpu, &lock_context );
663 }
664 
671  Watchdog_Control *the_watchdog
672 )
673 {
674  Per_CPU_Control *cpu;
675 
676  cpu = _Watchdog_Get_CPU( the_watchdog );
678  the_watchdog,
679  cpu,
681  );
682 }
683 
686 #ifdef __cplusplus
687 }
688 #endif
689 
690 #endif
691 /* end of include file */
RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove(Watchdog_Control *the_watchdog, Per_CPU_Control *cpu, Watchdog_Header *header)
Removes the watchdog from the cpu and the scheduled watchdogs.
Definition: watchdogimpl.h:649
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert(Watchdog_Control *the_watchdog, Per_CPU_Control *cpu, Watchdog_Header *header, uint64_t expire)
Sets the watchdog's cpu and inserts it with the given expiration time in the scheduled watchdogs.
Definition: watchdogimpl.h:625
Watchdog_Service_routine(* Watchdog_Service_routine_entry)(Watchdog_Control *)
Pointer to a watchdog service routine.
Definition: watchdog.h:66
RBTree_Node * first
The scheduled watchdog with the earliest expiration time or NULL in case no watchdog is scheduled.
Definition: watchdog.h:81
RTEMS_INLINE_ROUTINE void _Watchdog_Set_CPU(Watchdog_Control *the_watchdog, Per_CPU_Control *cpu)
Sets the cpu for the watchdog.
Definition: watchdogimpl.h:194
RTEMS_INLINE_ROUTINE void _Watchdog_Header_destroy(Watchdog_Header *header)
Destroys the watchdog header.
Definition: watchdogimpl.h:127
The watchdog is inactive.
Definition: watchdogimpl.h:61
RTEMS_INLINE_ROUTINE void _Watchdog_Initialize(Watchdog_Control *the_watchdog, Watchdog_Service_routine_entry routine)
Initializes a watchdog with a new service routine.
Definition: watchdogimpl.h:236
uint32_t Watchdog_Interval
Type is used to specify the length of intervals.
Definition: watchdogticks.h:38
Watchdog_Header Header[PER_CPU_WATCHDOG_COUNT]
Header for watchdogs.
Definition: percpu.h:474
void _Watchdog_Insert(Watchdog_Header *header, Watchdog_Control *the_watchdog, uint64_t expire)
Inserts a watchdog into the set of scheduled watchdogs according to the specified expiration time.
Definition: watchdoginsert.c:29
RTEMS_INLINE_ROUTINE void _RBTree_Initialize_empty(RBTree_Control *the_rbtree)
Initializes this RBTree as empty.
Definition: rbtree.h:410
uint64_t expire
This field is the expiration time point.
Definition: watchdog.h:117
uint64_t ticks
Protects all watchdog operations on this processor.
Definition: percpu.h:467
The control block used to manage each watchdog timer.
Definition: watchdog.h:90
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_valid_interval_timespec(const struct timespec *ts)
Checks if the timespec is a valid interval timespec for a watchdog.
Definition: watchdogimpl.h:435
void _Watchdog_Remove(Watchdog_Header *header, Watchdog_Control *the_watchdog)
In the case the watchdog is scheduled, then it is removed from the set of scheduled watchdogs.
Definition: watchdogremove.c:29
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_scheduled(const Watchdog_Control *the_watchdog)
Checks if the watchdog is scheduled.
Definition: watchdogimpl.h:348
Watchdog_State
Watchdog states.
Definition: watchdogimpl.h:47
RTEMS_INLINE_ROUTINE Per_CPU_Control * _Watchdog_Get_CPU(const Watchdog_Control *the_watchdog)
Gets the watchdog's cpu.
Definition: watchdogimpl.h:177
RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_ticks(Watchdog_Control *the_watchdog)
Removes the watchdog from the cpu and the scheduled watchdogs.
Definition: watchdogimpl.h:670
Red-black tree node.
Definition: rbtree.h:55
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Cancel(Watchdog_Header *header, Watchdog_Control *the_watchdog, uint64_t now)
In the case the watchdog is scheduled, then it is removed from the set of scheduled watchdogs.
Definition: watchdogimpl.h:318
RTEMS_INLINE_ROUTINE void _Watchdog_Next_first(Watchdog_Header *header, Watchdog_Control *the_watchdog)
Sets the first node of the header.
Definition: watchdogimpl.h:366
union Watchdog_Control::@3987 Node
Nodes for the watchdog.
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_sbintime(int64_t sbt)
Converts the sbintime in ticks.
Definition: watchdogimpl.h:546
ISR lock control.
Definition: isrlock.h:56
Watchdog_Service_routine_entry routine
This field is the function to invoke.
Definition: watchdog.h:114
RBTree_Control Watchdogs
Red-black tree of scheduled watchdogs sorted by expiration time.
Definition: watchdog.h:75
RTEMS_INLINE_ROUTINE Watchdog_Control * _Watchdog_Header_first(const Watchdog_Header *header)
Returns the first of the watchdog header.
Definition: watchdogimpl.h:115
Information for the Assert Handler.
RTEMS_INLINE_ROUTINE void _Watchdog_Set_state(Watchdog_Control *the_watchdog, Watchdog_State state)
Sets the state of the watchdog.
Definition: watchdogimpl.h:162
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_seconds(uint32_t seconds)
Converts the seconds to ticks.
Definition: watchdogimpl.h:504
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_timespec(const struct timespec *ts)
Converts the timespec in ticks.
Definition: watchdogimpl.h:522
RTEMS_INLINE_ROUTINE void _Watchdog_Header_initialize(Watchdog_Header *header)
Initializes the watchdog header.
Definition: watchdogimpl.h:100
The watchdog is scheduled and a black node in the red-black tree.
Definition: watchdogimpl.h:51
RTEMS_INLINE_ROUTINE void _Watchdog_Preinitialize(Watchdog_Control *the_watchdog, Per_CPU_Control *cpu)
Pre-initializes a watchdog.
Definition: watchdogimpl.h:214
RBTree_Node RBTree
this field is a red-black tree node structure and allows this to be placed on a red-black tree used t...
Definition: watchdog.h:99
RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_release_critical(Per_CPU_Control *cpu, ISR_lock_Context *lock_context)
Releases the per cpu watchdog lock in a critical section.
Definition: watchdogimpl.h:575
Per CPU Core Structure.
Definition: percpu.h:347
#define WATCHDOG_MAX_SECONDS
The maximum number of seconds representable in the nanoseconds watchdog format.
Definition: watchdogimpl.h:409
void _Watchdog_Do_tickle(Watchdog_Header *header, Watchdog_Control *first, uint64_t now, ISR_lock_Context *lock_context)
Calls the routine of each not expired watchdog control node.
Definition: watchdogtick.c:24
RTEMS_INLINE_ROUTINE const struct timespec * _Watchdog_Future_timespec(struct timespec *now, const struct timespec *delta)
Adds the delta timespec to the current time if the delta is a valid interval timespec.
Definition: watchdogimpl.h:452
#define _ISR_lock_Acquire(_lock, _context)
Acquires an ISR lock inside an ISR disabled section.
Definition: isrlock.h:293
#define _ISR_lock_Release(_lock, _context)
Releases an ISR lock inside an ISR disabled section.
Definition: isrlock.h:316
Constants and Structures Associated with Watchdog Timers.
The watchdog is on a chain of pending watchdogs.
Definition: watchdogimpl.h:68
Inlined Routines Associated with Red-Black Trees.
The watchdog is scheduled and a red node in the red-black tree.
Definition: watchdogimpl.h:56
RTEMS_INLINE_ROUTINE RBTree_Node * _RBTree_Left(const RBTree_Node *the_node)
Returns pointer to the left of this node.
Definition: rbtree.h:311
RTEMS_INLINE_ROUTINE Watchdog_State _Watchdog_Get_state(const Watchdog_Control *the_watchdog)
Gets the state of the watchdog.
Definition: watchdogimpl.h:149
#define WATCHDOG_BITS_FOR_1E9_NANOSECONDS
The bits necessary to store 1000000000 (= WATCHDOG_NANOSECONDS_PER_SECOND) nanoseconds.
Definition: watchdogimpl.h:401
The watchdog header to manage scheduled watchdogs.
Definition: watchdog.h:71
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_timespec(const struct timespec *ts)
Checks if the timespec is too far in the future.
Definition: watchdogimpl.h:490
Constants for the watchdog ticks.
RTEMS_INLINE_ROUTINE RBTree_Node * _RBTree_Parent(const RBTree_Node *the_node)
Returns a pointer to the parent of this node.
Definition: rbtree.h:295
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
Index for tick clock per-CPU watchdog header.
Definition: percpu.h:316
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:66
ISR Locks.
RTEMS_INLINE_ROUTINE bool _Watchdog_Is_valid_timespec(const struct timespec *ts)
Checks if the timespec is a valid timespec for a watchdog.
Definition: watchdogimpl.h:419
RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_acquire_critical(Per_CPU_Control *cpu, ISR_lock_Context *lock_context)
Acquires the per cpu watchdog lock in a critical section.
Definition: watchdogimpl.h:561
RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_ticks(Watchdog_Control *the_watchdog, Per_CPU_Control *cpu, Watchdog_Interval ticks)
Sets the watchdog's cpu to the given instance and sets its expiration time to the watchdog expiration...
Definition: watchdogimpl.h:593
struct Per_CPU_Control::@3977 Watchdog
Watchdog state for this processor.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Definition: assert.h:100
RTEMS_INLINE_ROUTINE RBTree_Node * _RBTree_Right(const RBTree_Node *the_node)
Returns pointer to the right of this node.
Definition: rbtree.h:342
#define NULL
Requests a GPIO pin group configuration.
Definition: bestcomm_api.h:77
void _Watchdog_Tick(struct Per_CPU_Control *cpu)
Performs a watchdog tick.
Definition: watchdogtick.c:54