19 #ifndef _COBALT_KERNEL_BHEAP_H
20 #define _COBALT_KERNEL_BHEAP_H
23 #include <cobalt/kernel/assert.h>
27 typedef unsigned long long bheap_key_t;
29 typedef struct bheaph {
35 #define bheaph_init(holder) do { } while (0)
36 #define bheaph_key(holder) ((holder)->key)
37 #define bheaph_prio(holder) ((holder)->prio)
38 #define bheaph_pos(holder) ((holder)->pos)
39 #define bheaph_lt(h1, h2) ((long long) ((h1)->key - (h2)->key) < 0 || \
40 ((h1)->key == (h2)->key && \
41 (h1)->prio > (h2)->prio))
43 typedef struct bheap {
49 #define DECLARE_BHEAP_CONTAINER(name, sz) \
52 bheaph_t *elems[sz + 1]; \
56 static inline int bheap_ordered(bheap_t *heap)
59 for (i = 2; i < heap->last; i++)
60 if (bheaph_lt(heap->elems[i], heap->elems[i / 2]))
65 #define BHEAP_CHECK(heap) \
66 XENO_BUG_ON(COBALT, ((heap)->sz == 0) || !bheap_ordered(heap))
68 #define bheap_gethead(heap) \
70 bheap_t *_bheap = &(heap)->bheap; \
71 BHEAP_CHECK(_bheap); \
72 __internal_bheap_gethead(_bheap); \
75 static inline bheaph_t *__internal_bheap_gethead(bheap_t *heap)
80 return heap->elems[1];
83 #define bheap_second(heap) \
85 bheap_t *_bheap = &(heap)->bheap; \
86 BHEAP_CHECK(_bheap); \
87 __internal_bheap_second(_bheap); \
90 #define bheap_next(heap, holder) \
92 bheap_t *_bheap = &(heap)->bheap; \
93 BHEAP_CHECK(_bheap); \
94 __internal_bheap_next(_bheap, holder); \
97 static inline bheaph_t *__internal_bheap_next(bheap_t *heap, bheaph_t *holder)
101 if (unlikely(bheaph_pos(holder) >= heap->last
102 || heap->elems[bheaph_pos(holder)] != holder))
103 return (bheaph_t *) ERR_PTR(-EINVAL);
105 pos = bheaph_pos(holder) + 1;
107 return likely(pos < heap->last) ? heap->elems[pos] : NULL;
110 static inline bheaph_t *bheaph_parent(bheap_t *heap, bheaph_t *holder)
112 const unsigned pos = holder->pos;
114 return likely(pos > 1) ? heap->elems[pos / 2] : NULL;
117 static inline bheaph_t *bheaph_child(bheap_t *heap, bheaph_t *holder,
int side)
119 const unsigned pos = 2 * holder->pos + side;
121 return likely(pos < heap->last) ? heap->elems[pos] : NULL;
124 static inline bheaph_t *__internal_bheap_second(bheap_t *heap)
126 bheaph_t *left, *right, *first = __internal_bheap_gethead(heap);
128 left = bheaph_child(heap, first, 0);
129 right = bheaph_child(heap, first, 1);
132 return left ?: right;
134 return bheaph_lt(left, right) ? left : right;
137 #define bheap_init(heap, sz) __internal_bheap_init(&(heap)->bheap, sz)
139 static inline void __internal_bheap_init(bheap_t *heap,
unsigned sz)
145 #define bheap_destroy(heap) __internal_bheap_destroy(&(heap)->bheap)
147 static inline void __internal_bheap_destroy(bheap_t *heap)
153 static inline void bheap_swap(bheap_t *heap, bheaph_t *h1, bheaph_t *h2)
155 const unsigned pos2 = bheaph_pos(h2);
157 heap->elems[bheaph_pos(h1)] = h2;
158 bheaph_pos(h2) = bheaph_pos(h1);
159 heap->elems[pos2] = h1;
160 bheaph_pos(h1) = pos2;
163 static inline void bheap_up(bheap_t *heap, bheaph_t *holder)
167 while ((parent = bheaph_parent(heap, holder)) && bheaph_lt(holder, parent))
168 bheap_swap(heap, holder, parent);
171 static inline void bheap_down(bheap_t *heap, bheaph_t *holder)
173 bheaph_t *left, *right, *minchild;
176 left = bheaph_child(heap, holder, 0);
177 right = bheaph_child(heap, holder, 1);
180 minchild = bheaph_lt(left, right) ? left : right;
182 minchild = left ?: right;
184 if (!minchild || bheaph_lt(holder, minchild))
187 bheap_swap(heap, minchild, holder);
191 #define bheap_insert(heap, holder) \
193 bheap_t *_bheap = &(heap)->bheap; \
194 BHEAP_CHECK(_bheap); \
195 __internal_bheap_insert(_bheap, holder); \
198 static inline int __internal_bheap_insert(bheap_t *heap, bheaph_t *holder)
200 if (heap->last == heap->sz + 1)
203 heap->elems[heap->last] = holder;
204 bheaph_pos(holder) = heap->last;
206 bheap_up(heap, holder);
210 #define bheap_delete(heap, holder) \
212 bheap_t *_bheap = &(heap)->bheap; \
213 BHEAP_CHECK(_bheap); \
214 __internal_bheap_delete(_bheap, holder); \
217 static inline int __internal_bheap_delete(bheap_t *heap, bheaph_t *holder)
221 if (unlikely(bheaph_pos(holder) >= heap->last
222 || heap->elems[bheaph_pos(holder)] != holder))
226 if (heap->last != bheaph_pos(holder)) {
228 lasth = heap->elems[heap->last];
229 heap->elems[bheaph_pos(holder)] = lasth;
230 bheaph_pos(lasth) = bheaph_pos(holder);
231 if ((parent = bheaph_parent(heap, lasth)) && bheaph_lt(lasth, parent))
232 bheap_up(heap, lasth);
234 bheap_down(heap, lasth);
240 #define bheap_get(heap) \
242 bheap_t *_bheap = &(heap)->bheap; \
243 BHEAP_CHECK(_bheap); \
244 __internal_bheap_get(_bheap, holder); \
247 static inline bheaph_t *__internal_bheap_get(bheap_t *heap)
249 bheaph_t *holder = __internal_bheap_gethead(heap);
254 __internal_bheap_delete(heap, holder);
259 #define bheap_empty(heap) \
261 bheap_t *_bheap = &(heap)->bheap; \
262 BHEAP_CHECK(_bheap); \