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_BUGON(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_next(heap, holder) \
85 bheap_t *_bheap = &(heap)->bheap; \
86 BHEAP_CHECK(_bheap); \
87 __internal_bheap_next(_bheap, holder); \
90 static inline bheaph_t *__internal_bheap_next(bheap_t *heap, bheaph_t *holder)
94 if (unlikely(bheaph_pos(holder) >= heap->last
95 || heap->elems[bheaph_pos(holder)] != holder))
96 return (bheaph_t *) ERR_PTR(-EINVAL);
98 pos = bheaph_pos(holder) + 1;
100 return likely(pos < heap->last) ? heap->elems[pos] : NULL;
103 static inline bheaph_t *bheaph_parent(bheap_t *heap, bheaph_t *holder)
105 const unsigned pos = holder->pos;
107 return likely(pos > 1) ? heap->elems[pos / 2] : NULL;
110 static inline bheaph_t *bheaph_child(bheap_t *heap, bheaph_t *holder,
int side)
112 const unsigned pos = 2 * holder->pos + side;
114 return likely(pos < heap->last) ? heap->elems[pos] : NULL;
117 #define bheap_init(heap, sz) __internal_bheap_init(&(heap)->bheap, sz)
119 static inline void __internal_bheap_init(bheap_t *heap,
unsigned sz)
125 #define bheap_destroy(heap) __internal_bheap_destroy(&(heap)->bheap)
127 static inline void __internal_bheap_destroy(bheap_t *heap)
133 static inline void bheap_swap(bheap_t *heap, bheaph_t *h1, bheaph_t *h2)
135 const unsigned pos2 = bheaph_pos(h2);
137 heap->elems[bheaph_pos(h1)] = h2;
138 bheaph_pos(h2) = bheaph_pos(h1);
139 heap->elems[pos2] = h1;
140 bheaph_pos(h1) = pos2;
143 static inline void bheap_up(bheap_t *heap, bheaph_t *holder)
147 while ((parent = bheaph_parent(heap, holder)) && bheaph_lt(holder, parent))
148 bheap_swap(heap, holder, parent);
151 static inline void bheap_down(bheap_t *heap, bheaph_t *holder)
153 bheaph_t *left, *right, *minchild;
156 left = bheaph_child(heap, holder, 0);
157 right = bheaph_child(heap, holder, 1);
160 minchild = bheaph_lt(left, right) ? left : right;
162 minchild = left ?: right;
164 if (!minchild || bheaph_lt(holder, minchild))
167 bheap_swap(heap, minchild, holder);
171 #define bheap_insert(heap, holder) \
173 bheap_t *_bheap = &(heap)->bheap; \
174 BHEAP_CHECK(_bheap); \
175 __internal_bheap_insert(_bheap, holder); \
178 static inline int __internal_bheap_insert(bheap_t *heap, bheaph_t *holder)
180 if (heap->last == heap->sz + 1)
183 heap->elems[heap->last] = holder;
184 bheaph_pos(holder) = heap->last;
186 bheap_up(heap, holder);
190 #define bheap_delete(heap, holder) \
192 bheap_t *_bheap = &(heap)->bheap; \
193 BHEAP_CHECK(_bheap); \
194 __internal_bheap_delete(_bheap, holder); \
197 static inline int __internal_bheap_delete(bheap_t *heap, bheaph_t *holder)
201 if (unlikely(bheaph_pos(holder) >= heap->last
202 || heap->elems[bheaph_pos(holder)] != holder))
206 if (heap->last != bheaph_pos(holder)) {
208 lasth = heap->elems[heap->last];
209 heap->elems[bheaph_pos(holder)] = lasth;
210 bheaph_pos(lasth) = bheaph_pos(holder);
211 if ((parent = bheaph_parent(heap, lasth)) && bheaph_lt(lasth, parent))
212 bheap_up(heap, lasth);
214 bheap_down(heap, lasth);
220 #define bheap_get(heap) \
222 bheap_t *_bheap = &(heap)->bheap; \
223 BHEAP_CHECK(_bheap); \
224 __internal_bheap_get(_bheap, holder); \
227 static inline bheaph_t *__internal_bheap_get(bheap_t *heap)
229 bheaph_t *holder = __internal_bheap_gethead(heap);
234 __internal_bheap_delete(heap, holder);
239 #define bheap_empty(heap) \
241 bheap_t *_bheap = &(heap)->bheap; \
242 BHEAP_CHECK(_bheap); \