mirror of
https://github.com/apache/nuttx.git
synced 2026-06-03 22:20:31 +08:00
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:
committed by
Donny(董九柱)
parent
78dce81c5a
commit
5bab9fcc7f
@@ -84,6 +84,7 @@ extern seqcount_t g_hrtimer_lock;
|
|||||||
/* Red-Black tree containing all active high-resolution timers */
|
/* Red-Black tree containing all active high-resolution timers */
|
||||||
|
|
||||||
extern struct hrtimer_tree_s g_hrtimer_tree;
|
extern struct hrtimer_tree_s g_hrtimer_tree;
|
||||||
|
extern struct hrtimer_s g_hrtimer_guard;
|
||||||
extern struct FAR hrtimer_s *g_hrtimer_head;
|
extern struct FAR hrtimer_s *g_hrtimer_head;
|
||||||
#else
|
#else
|
||||||
/* List containing all active high-resolution timers */
|
/* 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;
|
bool is_head = false;
|
||||||
RB_INSERT(hrtimer_tree_s, &g_hrtimer_tree, hrtimer);
|
RB_INSERT(hrtimer_tree_s, &g_hrtimer_tree, hrtimer);
|
||||||
|
|
||||||
if (g_hrtimer_head == NULL ||
|
if (HRTIMER_TIME_BEFORE(hrtimer->expired, g_hrtimer_head->expired))
|
||||||
HRTIMER_TIME_BEFORE(hrtimer->expired, g_hrtimer_head->expired))
|
|
||||||
{
|
{
|
||||||
g_hrtimer_head = hrtimer;
|
g_hrtimer_head = hrtimer;
|
||||||
is_head = true;
|
is_head = true;
|
||||||
|
|||||||
@@ -97,11 +97,8 @@ int hrtimer_cancel(FAR hrtimer_t *hrtimer)
|
|||||||
|
|
||||||
if (hrtimer_remove(hrtimer))
|
if (hrtimer_remove(hrtimer))
|
||||||
{
|
{
|
||||||
uint64_t next_expired;
|
|
||||||
|
|
||||||
first = hrtimer_get_first();
|
first = hrtimer_get_first();
|
||||||
next_expired = first != NULL ? first->expired : UINT64_MAX;
|
hrtimer_reprogram(first->expired);
|
||||||
hrtimer_reprogram(next_expired);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,15 +58,28 @@ seqcount_t g_hrtimer_lock = SEQLOCK_INITIALIZER;
|
|||||||
* both configurations.
|
* both configurations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct hrtimer_s g_hrtimer_guard =
|
||||||
|
{
|
||||||
#ifdef CONFIG_HRTIMER_TREE
|
#ifdef CONFIG_HRTIMER_TREE
|
||||||
/* Red-black tree for hrtimer storage (requires CONFIG_HRTIMER_TREE) */
|
{ NULL },
|
||||||
|
|
||||||
struct hrtimer_tree_s g_hrtimer_tree = RB_INITIALIZER(g_hrtimer_tree);
|
|
||||||
struct FAR hrtimer_s *g_hrtimer_head;
|
|
||||||
#else
|
#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
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -84,16 +84,15 @@ void hrtimer_process(uint64_t now)
|
|||||||
/* Fetch the earliest active timer */
|
/* Fetch the earliest active timer */
|
||||||
|
|
||||||
hrtimer = hrtimer_get_first();
|
hrtimer = hrtimer_get_first();
|
||||||
|
expired = hrtimer->expired;
|
||||||
|
|
||||||
/* Check if the timer has 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 */
|
/* Remove the expired timer from the timer queue */
|
||||||
|
|
||||||
|
func = hrtimer->func;
|
||||||
hrtimer_remove(hrtimer);
|
hrtimer_remove(hrtimer);
|
||||||
|
|
||||||
hrtimer_mark_running(hrtimer, cpu);
|
hrtimer_mark_running(hrtimer, cpu);
|
||||||
@@ -130,17 +129,18 @@ void hrtimer_process(uint64_t now)
|
|||||||
/* Fetch the next earliest timer */
|
/* Fetch the next earliest timer */
|
||||||
|
|
||||||
hrtimer = hrtimer_get_first();
|
hrtimer = hrtimer_get_first();
|
||||||
|
expired = hrtimer->expired;
|
||||||
}
|
}
|
||||||
|
|
||||||
hrtimer_unmark_running(cpu);
|
hrtimer_unmark_running(cpu);
|
||||||
|
|
||||||
/* Schedule the next timer expiration */
|
/* Schedule the next timer expiration */
|
||||||
|
|
||||||
if (hrtimer != NULL)
|
if (expired != now)
|
||||||
{
|
{
|
||||||
/* Start timer for the next earliest expiration */
|
/* 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. */
|
/* Release the lock and give up the ownership of the hrtimer queue. */
|
||||||
|
|||||||
Reference in New Issue
Block a user