sched/hrtimer: Add guard timer.

This commit added the guard timer for hrtimer.
The guard timer uses a small memory footprint, offering two main advantages:
- Reduced branches checking for an empty hrtimer queue, simplifying code implementation and improving the performance.
- Additional health monitoring allows the system to enter a safe state in case of time acquisition errors, and supports custom error handling callback functions.

Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
ouyangxiangzhen
2026-01-26 16:56:31 +08:00
committed by Donny(董九柱)
parent 78dce81c5a
commit 5bab9fcc7f
4 changed files with 28 additions and 18 deletions
+2 -2
View File
@@ -84,6 +84,7 @@ extern seqcount_t g_hrtimer_lock;
/* Red-Black tree containing all active high-resolution timers */
extern struct hrtimer_tree_s g_hrtimer_tree;
extern struct hrtimer_s g_hrtimer_guard;
extern struct FAR hrtimer_s *g_hrtimer_head;
#else
/* List containing all active high-resolution timers */
@@ -262,8 +263,7 @@ static inline_function bool hrtimer_insert(FAR hrtimer_t *hrtimer)
bool is_head = false;
RB_INSERT(hrtimer_tree_s, &g_hrtimer_tree, hrtimer);
if (g_hrtimer_head == NULL ||
HRTIMER_TIME_BEFORE(hrtimer->expired, g_hrtimer_head->expired))
if (HRTIMER_TIME_BEFORE(hrtimer->expired, g_hrtimer_head->expired))
{
g_hrtimer_head = hrtimer;
is_head = true;
+1 -4
View File
@@ -97,11 +97,8 @@ int hrtimer_cancel(FAR hrtimer_t *hrtimer)
if (hrtimer_remove(hrtimer))
{
uint64_t next_expired;
first = hrtimer_get_first();
next_expired = first != NULL ? first->expired : UINT64_MAX;
hrtimer_reprogram(next_expired);
hrtimer_reprogram(first->expired);
}
}
+19 -6
View File
@@ -58,15 +58,28 @@ seqcount_t g_hrtimer_lock = SEQLOCK_INITIALIZER;
* both configurations.
*/
struct hrtimer_s g_hrtimer_guard =
{
#ifdef CONFIG_HRTIMER_TREE
/* Red-black tree for hrtimer storage (requires CONFIG_HRTIMER_TREE) */
struct hrtimer_tree_s g_hrtimer_tree = RB_INITIALIZER(g_hrtimer_tree);
struct FAR hrtimer_s *g_hrtimer_head;
{ NULL },
#else
/* Linked list for hrtimer storage (fallback when tree is disabled) */
{ &g_hrtimer_list, &g_hrtimer_list },
#endif
NULL,
INT64_MAX
};
struct list_node g_hrtimer_list = LIST_INITIAL_VALUE(g_hrtimer_list);
#ifdef CONFIG_HRTIMER_TREE
struct hrtimer_tree_s g_hrtimer_tree =
{
&g_hrtimer_guard
};
struct FAR hrtimer_s *g_hrtimer_head = &g_hrtimer_guard;
#else
struct list_node g_hrtimer_list =
{
&g_hrtimer_guard.node, &g_hrtimer_guard.node
};
#endif
/****************************************************************************
+6 -6
View File
@@ -84,16 +84,15 @@ void hrtimer_process(uint64_t now)
/* Fetch the earliest active timer */
hrtimer = hrtimer_get_first();
expired = hrtimer->expired;
/* Check if the timer has expired */
while (hrtimer != NULL && HRTIMER_TIME_BEFORE_EQ(hrtimer->expired, now))
while (HRTIMER_TIME_BEFORE_EQ(expired, now))
{
func = hrtimer->func;
expired = hrtimer->expired;
/* Remove the expired timer from the timer queue */
func = hrtimer->func;
hrtimer_remove(hrtimer);
hrtimer_mark_running(hrtimer, cpu);
@@ -130,17 +129,18 @@ void hrtimer_process(uint64_t now)
/* Fetch the next earliest timer */
hrtimer = hrtimer_get_first();
expired = hrtimer->expired;
}
hrtimer_unmark_running(cpu);
/* Schedule the next timer expiration */
if (hrtimer != NULL)
if (expired != now)
{
/* Start timer for the next earliest expiration */
hrtimer_reprogram(hrtimer->expired);
hrtimer_reprogram(expired);
}
/* Release the lock and give up the ownership of the hrtimer queue. */