Files
linux-stable-mirror/include/linux/timerqueue.h
T
Thomas Gleixner 1339eeb73d timerqueue: Provide linked timerqueue
The hrtimer subsystem wants to peak ahead to the next and previous timer to
evaluated whether a to be rearmed timer can stay at the same position in
the RB tree with the new expiry time.

The linked RB tree provides the infrastructure for this as it maintains
links to the previous and next nodes for each entry in the tree.

Provide timerqueue wrappers around that.

Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260224163431.734827095@kernel.org
2026-02-27 16:40:16 +01:00

85 lines
2.4 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_TIMERQUEUE_H
#define _LINUX_TIMERQUEUE_H
#include <linux/rbtree.h>
#include <linux/timerqueue_types.h>
bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node);
bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node);
struct timerqueue_node *timerqueue_iterate_next(struct timerqueue_node *node);
bool timerqueue_linked_add(struct timerqueue_linked_head *head, struct timerqueue_linked_node *node);
/**
* timerqueue_getnext - Returns the timer with the earliest expiration time
*
* @head: head of timerqueue
*
* Returns a pointer to the timer node that has the earliest expiration time.
*/
static inline struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head)
{
struct rb_node *leftmost = rb_first_cached(&head->rb_root);
return rb_entry_safe(leftmost, struct timerqueue_node, node);
}
static inline void timerqueue_init(struct timerqueue_node *node)
{
RB_CLEAR_NODE(&node->node);
}
static inline bool timerqueue_node_queued(struct timerqueue_node *node)
{
return !RB_EMPTY_NODE(&node->node);
}
static inline void timerqueue_init_head(struct timerqueue_head *head)
{
head->rb_root = RB_ROOT_CACHED;
}
/* Timer queues with linked nodes */
static __always_inline
struct timerqueue_linked_node *timerqueue_linked_first(struct timerqueue_linked_head *head)
{
return rb_entry_safe(head->rb_root.rb_leftmost, struct timerqueue_linked_node, node);
}
static __always_inline
struct timerqueue_linked_node *timerqueue_linked_next(struct timerqueue_linked_node *node)
{
return rb_entry_safe(node->node.next, struct timerqueue_linked_node, node);
}
static __always_inline
struct timerqueue_linked_node *timerqueue_linked_prev(struct timerqueue_linked_node *node)
{
return rb_entry_safe(node->node.prev, struct timerqueue_linked_node, node);
}
static __always_inline
bool timerqueue_linked_del(struct timerqueue_linked_head *head, struct timerqueue_linked_node *node)
{
return rb_erase_linked(&node->node, &head->rb_root);
}
static __always_inline void timerqueue_linked_init(struct timerqueue_linked_node *node)
{
RB_CLEAR_LINKED_NODE(&node->node);
}
static __always_inline bool timerqueue_linked_node_queued(struct timerqueue_linked_node *node)
{
return !RB_EMPTY_LINKED_NODE(&node->node);
}
static __always_inline void timerqueue_linked_init_head(struct timerqueue_linked_head *head)
{
head->rb_root = RB_ROOT_LINKED;
}
#endif /* _LINUX_TIMERQUEUE_H */