1
2
3
4
5
6
7
8
9
10
11
12#include <linux/bug.h>
13#include <linux/timerqueue.h>
14#include <linux/rbtree.h>
15#include <linux/export.h>
16
17#define __node_2_tq(_n) \
18 rb_entry((_n), struct timerqueue_node, node)
19
20static inline bool __timerqueue_less(struct rb_node *a, const struct rb_node *b)
21{
22 return __node_2_tq(a)->expires < __node_2_tq(b)->expires;
23}
24
25
26
27
28
29
30
31
32
33
34
35bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node)
36{
37
38 WARN_ON_ONCE(!RB_EMPTY_NODE(&node->node));
39
40 return rb_add_cached(&node->node, &head->rb_root, __timerqueue_less);
41}
42EXPORT_SYMBOL_GPL(timerqueue_add);
43
44
45
46
47
48
49
50
51
52
53bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node)
54{
55 WARN_ON_ONCE(RB_EMPTY_NODE(&node->node));
56
57 rb_erase_cached(&node->node, &head->rb_root);
58 RB_CLEAR_NODE(&node->node);
59
60 return !RB_EMPTY_ROOT(&head->rb_root.rb_root);
61}
62EXPORT_SYMBOL_GPL(timerqueue_del);
63
64
65
66
67
68
69
70
71
72
73struct timerqueue_node *timerqueue_iterate_next(struct timerqueue_node *node)
74{
75 struct rb_node *next;
76
77 if (!node)
78 return NULL;
79 next = rb_next(&node->node);
80 if (!next)
81 return NULL;
82 return container_of(next, struct timerqueue_node, node);
83}
84EXPORT_SYMBOL_GPL(timerqueue_iterate_next);
85