summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/watchdogimpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/include/rtems/score/watchdogimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/watchdogimpl.h162
1 files changed, 132 insertions, 30 deletions
diff --git a/cpukit/score/include/rtems/score/watchdogimpl.h b/cpukit/score/include/rtems/score/watchdogimpl.h
index e548e7025c..8405232a87 100644
--- a/cpukit/score/include/rtems/score/watchdogimpl.h
+++ b/cpukit/score/include/rtems/score/watchdogimpl.h
@@ -21,6 +21,7 @@
#include <rtems/score/watchdog.h>
#include <rtems/score/chainimpl.h>
+#include <rtems/score/isrlock.h>
#ifdef __cplusplus
extern "C" {
@@ -45,30 +46,49 @@ extern "C" {
}
/**
- * @brief Watchdog header.
+ * @brief Iterator item to synchronize concurrent insert, remove and tickle
+ * operations.
*/
typedef struct {
/**
- * @brief The chain of active or transient watchdogs.
+ * @brief A node for a Watchdog_Header::Iterators chain.
*/
- Chain_Control Watchdogs;
-} Watchdog_Header;
+ Chain_Node Node;
-/**
- * @brief Watchdog synchronization level.
- *
- * This used for synchronization purposes
- * during an insert on a watchdog delta chain.
- */
-SCORE_EXTERN volatile uint32_t _Watchdog_Sync_level;
+ /**
+ * @brief The current delta interval of the new watchdog to insert.
+ */
+ Watchdog_Interval delta_interval;
+
+ /**
+ * @brief The current watchdog of the chain on the way to insert the new
+ * watchdog.
+ */
+ Chain_Node *current;
+} Watchdog_Iterator;
/**
- * @brief Watchdog synchronization count.
- *
- * This used for synchronization purposes
- * during an insert on a watchdog delta chain.
+ * @brief Watchdog header.
*/
-SCORE_EXTERN volatile uint32_t _Watchdog_Sync_count;
+typedef struct {
+ /**
+ * @brief ISR lock to protect this watchdog chain.
+ */
+ ISR_LOCK_MEMBER( Lock )
+
+ /**
+ * @brief The chain of active or transient watchdogs.
+ */
+ Chain_Control Watchdogs;
+
+ /**
+ * @brief Currently active iterators.
+ *
+ * The iterators are registered in _Watchdog_Insert() and updated in case the
+ * watchdog chain changes.
+ */
+ Chain_Control Iterators;
+} Watchdog_Header;
/**
* @brief Watchdog chain which is managed at ticks.
@@ -84,6 +104,30 @@ SCORE_EXTERN Watchdog_Header _Watchdog_Ticks_header;
*/
SCORE_EXTERN Watchdog_Header _Watchdog_Seconds_header;
+RTEMS_INLINE_ROUTINE void _Watchdog_Acquire(
+ Watchdog_Header *header,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_ISR_disable_and_acquire( &header->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Release(
+ Watchdog_Header *header,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release_and_ISR_enable( &header->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Flash(
+ Watchdog_Header *header,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Flash( &header->Lock, lock_context );
+}
+
/**
* @brief Initialize the watchdog handler.
*
@@ -94,15 +138,24 @@ SCORE_EXTERN Watchdog_Header _Watchdog_Seconds_header;
void _Watchdog_Handler_initialization( void );
/**
+ * @brief Triggers a watchdog tick.
+ *
+ * This routine executes TOD, watchdog and scheduler ticks.
+ */
+void _Watchdog_Tick( void );
+
+/**
* @brief Removes @a the_watchdog from the watchdog chain.
*
* This routine removes @a the_watchdog from the watchdog chain on which
* it resides and returns the state @a the_watchdog timer was in.
*
+ * @param[in] header The watchdog chain.
* @param[in] the_watchdog will be removed
* @retval the state in which @a the_watchdog was in when removed
*/
Watchdog_States _Watchdog_Remove (
+ Watchdog_Header *header,
Watchdog_Control *the_watchdog
);
@@ -119,6 +172,22 @@ void _Watchdog_Adjust_backward(
);
/**
+ * @brief Adjusts the watchdogs in backward direction in a locked context.
+ *
+ * The caller must be the owner of the watchdog lock and will be the owner
+ * after the call.
+ *
+ * @param[in] header The watchdog header.
+ * @param[in] units The units of ticks to adjust.
+ *
+ * @see _Watchdog_Adjust_forward().
+ */
+void _Watchdog_Adjust_backward_locked(
+ Watchdog_Header *header,
+ Watchdog_Interval units
+);
+
+/**
* @brief Adjusts the header watchdog chain in the forward direction for units
* ticks.
*
@@ -133,24 +202,22 @@ void _Watchdog_Adjust_forward(
);
/**
- * @brief Adjusts the @a header watchdog chain in the forward
- * @a direction for @a units_arg ticks.
+ * @brief Adjusts the watchdogs in forward direction in a locked context.
*
- * This routine adjusts the @a header watchdog chain in the forward
- * @a direction for @a units_arg ticks.
+ * The caller must be the owner of the watchdog lock and will be the owner
+ * after the call. This function may release and acquire the watchdog lock
+ * internally.
*
- * @param[in] header is the watchdog chain to adjust
- * @param[in] units_arg is the number of units to adjust @a header
- * @param[in] to_fire is a pointer to an initialized Chain_Control to which
- * all watchdog instances that are to be fired will be placed.
+ * @param[in] header The watchdog header.
+ * @param[in] units The units of ticks to adjust.
+ * @param[in] lock_context The lock context.
*
- * @note This always adjusts forward.
+ * @see _Watchdog_Adjust_forward().
*/
-void _Watchdog_Adjust_to_chain(
+void _Watchdog_Adjust_forward_locked(
Watchdog_Header *header,
- Watchdog_Interval units_arg,
- Chain_Control *to_fire
-
+ Watchdog_Interval units,
+ ISR_lock_Context *lock_context
);
/**
@@ -170,6 +237,25 @@ void _Watchdog_Insert (
);
/**
+ * @brief Inserts the watchdog in a locked context.
+ *
+ * The caller must be the owner of the watchdog lock and will be the owner
+ * after the call. This function may release and acquire the watchdog lock
+ * internally.
+ *
+ * @param[in] header The watchdog header.
+ * @param[in] the_watchdog The watchdog.
+ * @param[in] lock_context The lock context.
+ *
+ * @see _Watchdog_Insert().
+ */
+void _Watchdog_Insert_locked(
+ Watchdog_Header *header,
+ Watchdog_Control *the_watchdog,
+ ISR_lock_Context *lock_context
+);
+
+/**
* @brief This routine is invoked at appropriate intervals to update
* the @a header watchdog chain.
*
@@ -306,6 +392,20 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Insert_seconds(
}
+RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_ticks(
+ Watchdog_Control *the_watchdog
+)
+{
+ return _Watchdog_Remove( &_Watchdog_Ticks_header, the_watchdog );
+}
+
+RTEMS_INLINE_ROUTINE Watchdog_States _Watchdog_Remove_seconds(
+ Watchdog_Control *the_watchdog
+)
+{
+ return _Watchdog_Remove( &_Watchdog_Seconds_header, the_watchdog );
+}
+
/**
* This routine resets THE_WATCHDOG timer to its state at INSERT
* time. This routine is valid only on interval watchdog timers
@@ -318,7 +418,7 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Reset_ticks(
)
{
- (void) _Watchdog_Remove( the_watchdog );
+ _Watchdog_Remove_ticks( the_watchdog );
_Watchdog_Insert( &_Watchdog_Ticks_header, the_watchdog );
@@ -391,7 +491,9 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Header_initialize(
Watchdog_Header *header
)
{
+ _ISR_lock_Initialize( &header->Lock, "Watchdog" );
_Chain_Initialize_empty( &header->Watchdogs );
+ _Chain_Initialize_empty( &header->Iterators );
}
/** @} */