1*e7776783SApple OSS Distributions /* 2*e7776783SApple OSS Distributions * Copyright (c) 2018 Apple Inc. All rights reserved. 3*e7776783SApple OSS Distributions * 4*e7776783SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*e7776783SApple OSS Distributions * 6*e7776783SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*e7776783SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*e7776783SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*e7776783SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*e7776783SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*e7776783SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*e7776783SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*e7776783SApple OSS Distributions * terms of an Apple operating system software license agreement. 14*e7776783SApple OSS Distributions * 15*e7776783SApple OSS Distributions * Please obtain a copy of the License at 16*e7776783SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*e7776783SApple OSS Distributions * 18*e7776783SApple OSS Distributions * The Original Code and all software distributed under the License are 19*e7776783SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*e7776783SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*e7776783SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*e7776783SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*e7776783SApple OSS Distributions * Please see the License for the specific language governing rights and 24*e7776783SApple OSS Distributions * limitations under the License. 25*e7776783SApple OSS Distributions * 26*e7776783SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*e7776783SApple OSS Distributions */ 28*e7776783SApple OSS Distributions 29*e7776783SApple OSS Distributions #ifndef _KERN_PRIORITY_QUEUE_H_ 30*e7776783SApple OSS Distributions #define _KERN_PRIORITY_QUEUE_H_ 31*e7776783SApple OSS Distributions 32*e7776783SApple OSS Distributions #if KERNEL 33*e7776783SApple OSS Distributions #include <kern/kern_types.h> 34*e7776783SApple OSS Distributions #include <kern/macro_help.h> 35*e7776783SApple OSS Distributions #include <kern/assert.h> 36*e7776783SApple OSS Distributions #endif 37*e7776783SApple OSS Distributions 38*e7776783SApple OSS Distributions #include <stdbool.h> 39*e7776783SApple OSS Distributions #include <sys/cdefs.h> 40*e7776783SApple OSS Distributions 41*e7776783SApple OSS Distributions #pragma GCC visibility push(hidden) 42*e7776783SApple OSS Distributions 43*e7776783SApple OSS Distributions __BEGIN_DECLS 44*e7776783SApple OSS Distributions 45*e7776783SApple OSS Distributions /* 46*e7776783SApple OSS Distributions * A generic priorty ordered queue implementation based on pairing heaps. 47*e7776783SApple OSS Distributions * 48*e7776783SApple OSS Distributions * Reference Papers: 49*e7776783SApple OSS Distributions * - A Back-to-Basics Empirical Study of Priority Queues (https://arxiv.org/abs/1403.0252) 50*e7776783SApple OSS Distributions * - The Pairing Heap: A New Form of Self-Adjusting Heap 51*e7776783SApple OSS Distributions * (https://www.cs.cmu.edu/~sleator/papers/pairing-heaps.pdf) 52*e7776783SApple OSS Distributions * 53*e7776783SApple OSS Distributions * The XNU implementation is a basic version of the pairing heap. 54*e7776783SApple OSS Distributions * It allows for O(1) insertion and amortized O(log n) deletion. 55*e7776783SApple OSS Distributions * 56*e7776783SApple OSS Distributions * It is not a stable data structure by default since adding stability would 57*e7776783SApple OSS Distributions * need more pointers and hence more memory. 58*e7776783SApple OSS Distributions * 59*e7776783SApple OSS Distributions * Type of queues 60*e7776783SApple OSS Distributions * 61*e7776783SApple OSS Distributions * There are several types of priority queues, with types named: 62*e7776783SApple OSS Distributions * 63*e7776783SApple OSS Distributions * struct priority_queue_<subtype>_<min|max> 64*e7776783SApple OSS Distributions * 65*e7776783SApple OSS Distributions * In the rest of this header, `struct priority_queue` is used as 66*e7776783SApple OSS Distributions * a generic type to mean any priority_queue type. 67*e7776783SApple OSS Distributions * 68*e7776783SApple OSS Distributions * min/max refers to whether the priority queue is a min or a max heap. 69*e7776783SApple OSS Distributions * 70*e7776783SApple OSS Distributions * the subtype can be: 71*e7776783SApple OSS Distributions * 72*e7776783SApple OSS Distributions * - sched, in which case the key is built in the linkage and assumed to 73*e7776783SApple OSS Distributions * be a scheduler priority. 74*e7776783SApple OSS Distributions * 75*e7776783SApple OSS Distributions * - sched_stable, in which case the key is a combination of: 76*e7776783SApple OSS Distributions * * a scheduler priority 77*e7776783SApple OSS Distributions * * whether the entry was preempted or not 78*e7776783SApple OSS Distributions * * a timestamp. 79*e7776783SApple OSS Distributions * 80*e7776783SApple OSS Distributions * - generic, in which case a comparison function must be passed to 81*e7776783SApple OSS Distributions * the priority_queue_init. 82*e7776783SApple OSS Distributions * 83*e7776783SApple OSS Distributions * Element Linkage: 84*e7776783SApple OSS Distributions * 85*e7776783SApple OSS Distributions * Both types use a common queue head and linkage pattern. 86*e7776783SApple OSS Distributions * The head of a priority queue is declared as: 87*e7776783SApple OSS Distributions * 88*e7776783SApple OSS Distributions * struct priority_queue_<subtype>_<min|max> pq_head; 89*e7776783SApple OSS Distributions * 90*e7776783SApple OSS Distributions * Elements in this queue are linked together using one of the struct 91*e7776783SApple OSS Distributions * priority_queue_entry_<subtype> objects embedded within a structure: 92*e7776783SApple OSS Distributions * 93*e7776783SApple OSS Distributions * struct some_data { 94*e7776783SApple OSS Distributions * int field1; 95*e7776783SApple OSS Distributions * int field2; 96*e7776783SApple OSS Distributions * ... 97*e7776783SApple OSS Distributions * struct priority_queue_entry link; 98*e7776783SApple OSS Distributions * ... 99*e7776783SApple OSS Distributions * int last_field; 100*e7776783SApple OSS Distributions * }; 101*e7776783SApple OSS Distributions * struct some_data is referred to as the queue "element" 102*e7776783SApple OSS Distributions * 103*e7776783SApple OSS Distributions * This method uses the next, prev and child pointers of the struct 104*e7776783SApple OSS Distributions * priority_queue_entry linkage object embedded in a queue element to 105*e7776783SApple OSS Distributions * point to other elements in the queue. The head of the priority queue 106*e7776783SApple OSS Distributions * (the priority_queue object) will point to the root of the pairing 107*e7776783SApple OSS Distributions * heap (NULL if heap is empty). This method allows multiple chains 108*e7776783SApple OSS Distributions * through a given object, by embedding multiple priority_queue_entry 109*e7776783SApple OSS Distributions * objects in the structure, while simultaneously providing fast removal 110*e7776783SApple OSS Distributions * and insertion into the heap using only priority_queue_entry object 111*e7776783SApple OSS Distributions * pointers. 112*e7776783SApple OSS Distributions */ 113*e7776783SApple OSS Distributions 114*e7776783SApple OSS Distributions 115*e7776783SApple OSS Distributions /* 116*e7776783SApple OSS Distributions * Priority keys maintained by the data structure. 117*e7776783SApple OSS Distributions * Since the priority is packed in the node itself, it restricts keys to be 16-bits only. 118*e7776783SApple OSS Distributions */ 119*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_KEY_NONE 0 120*e7776783SApple OSS Distributions typedef uint16_t priority_queue_key_t; 121*e7776783SApple OSS Distributions 122*e7776783SApple OSS Distributions #ifdef __LP64__ 123*e7776783SApple OSS Distributions 124*e7776783SApple OSS Distributions /* 125*e7776783SApple OSS Distributions * For 64-bit platforms, pack the priority key into the child pointer 126*e7776783SApple OSS Distributions * The packing/unpacking is done using a compiler trick to sign extend long. 127*e7776783SApple OSS Distributions * This avoids additional NULL checks which are needed in typical packing 128*e7776783SApple OSS Distributions * implementation. The idea is to define the packed location as a long and 129*e7776783SApple OSS Distributions * for unpacking simply cast it to a full pointer which sign extends it. 130*e7776783SApple OSS Distributions */ 131*e7776783SApple OSS Distributions #if CONFIG_KERNEL_TBI && KASAN_TBI 132*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_ENTRY_CHILD_BITS 44 133*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_ENTRY_TAG_BITS 4 134*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_ENTRY_KEY_BITS 16 135*e7776783SApple OSS Distributions #else /* CONFIG_KERNEL_TBI && KASAN_TBI */ 136*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_ENTRY_CHILD_BITS 48 137*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_ENTRY_KEY_BITS 16 138*e7776783SApple OSS Distributions #endif /* CONFIG_KERNEL_TBI && KASAN_TBI */ 139*e7776783SApple OSS Distributions 140*e7776783SApple OSS Distributions typedef struct priority_queue_entry { 141*e7776783SApple OSS Distributions struct priority_queue_entry *next; 142*e7776783SApple OSS Distributions struct priority_queue_entry *prev; 143*e7776783SApple OSS Distributions long __key: PRIORITY_QUEUE_ENTRY_KEY_BITS; 144*e7776783SApple OSS Distributions #if CONFIG_KERNEL_TBI && KASAN_TBI 145*e7776783SApple OSS Distributions unsigned long tag: PRIORITY_QUEUE_ENTRY_TAG_BITS; 146*e7776783SApple OSS Distributions #endif /* CONFIG_KERNEL_TBI && KASAN_TBI */ 147*e7776783SApple OSS Distributions long child: PRIORITY_QUEUE_ENTRY_CHILD_BITS; 148*e7776783SApple OSS Distributions } *priority_queue_entry_t; 149*e7776783SApple OSS Distributions 150*e7776783SApple OSS Distributions typedef struct priority_queue_entry_deadline { 151*e7776783SApple OSS Distributions struct priority_queue_entry_deadline *next; 152*e7776783SApple OSS Distributions struct priority_queue_entry_deadline *prev; 153*e7776783SApple OSS Distributions long __key: PRIORITY_QUEUE_ENTRY_KEY_BITS; 154*e7776783SApple OSS Distributions #if CONFIG_KERNEL_TBI && KASAN_TBI 155*e7776783SApple OSS Distributions unsigned long tag: PRIORITY_QUEUE_ENTRY_TAG_BITS; 156*e7776783SApple OSS Distributions #endif /* CONFIG_KERNEL_TBI && KASAN_TBI */ 157*e7776783SApple OSS Distributions long child: PRIORITY_QUEUE_ENTRY_CHILD_BITS; 158*e7776783SApple OSS Distributions uint64_t deadline; 159*e7776783SApple OSS Distributions } *priority_queue_entry_deadline_t; 160*e7776783SApple OSS Distributions 161*e7776783SApple OSS Distributions typedef struct priority_queue_entry_sched { 162*e7776783SApple OSS Distributions struct priority_queue_entry_sched *next; 163*e7776783SApple OSS Distributions struct priority_queue_entry_sched *prev; 164*e7776783SApple OSS Distributions long key: PRIORITY_QUEUE_ENTRY_KEY_BITS; 165*e7776783SApple OSS Distributions #if CONFIG_KERNEL_TBI && KASAN_TBI 166*e7776783SApple OSS Distributions unsigned long tag: PRIORITY_QUEUE_ENTRY_TAG_BITS; 167*e7776783SApple OSS Distributions #endif /* CONFIG_KERNEL_TBI && KASAN_TBI */ 168*e7776783SApple OSS Distributions long child: PRIORITY_QUEUE_ENTRY_CHILD_BITS; 169*e7776783SApple OSS Distributions } *priority_queue_entry_sched_t; 170*e7776783SApple OSS Distributions 171*e7776783SApple OSS Distributions typedef struct priority_queue_entry_stable { 172*e7776783SApple OSS Distributions struct priority_queue_entry_stable *next; 173*e7776783SApple OSS Distributions struct priority_queue_entry_stable *prev; 174*e7776783SApple OSS Distributions long key: PRIORITY_QUEUE_ENTRY_KEY_BITS; 175*e7776783SApple OSS Distributions #if CONFIG_KERNEL_TBI && KASAN_TBI 176*e7776783SApple OSS Distributions unsigned long tag: PRIORITY_QUEUE_ENTRY_TAG_BITS; 177*e7776783SApple OSS Distributions #endif /* CONFIG_KERNEL_TBI && KASAN_TBI */ 178*e7776783SApple OSS Distributions long child: PRIORITY_QUEUE_ENTRY_CHILD_BITS; 179*e7776783SApple OSS Distributions uint64_t stamp; 180*e7776783SApple OSS Distributions } *priority_queue_entry_stable_t; 181*e7776783SApple OSS Distributions 182*e7776783SApple OSS Distributions #else /* __LP64__ */ 183*e7776783SApple OSS Distributions 184*e7776783SApple OSS Distributions typedef struct priority_queue_entry { 185*e7776783SApple OSS Distributions struct priority_queue_entry *next; 186*e7776783SApple OSS Distributions struct priority_queue_entry *prev; 187*e7776783SApple OSS Distributions long child; 188*e7776783SApple OSS Distributions } *priority_queue_entry_t; 189*e7776783SApple OSS Distributions 190*e7776783SApple OSS Distributions typedef struct priority_queue_entry_deadline { 191*e7776783SApple OSS Distributions struct priority_queue_entry_deadline *next; 192*e7776783SApple OSS Distributions struct priority_queue_entry_deadline *prev; 193*e7776783SApple OSS Distributions long child; 194*e7776783SApple OSS Distributions uint64_t deadline; 195*e7776783SApple OSS Distributions } *priority_queue_entry_deadline_t; 196*e7776783SApple OSS Distributions 197*e7776783SApple OSS Distributions /* 198*e7776783SApple OSS Distributions * For 32-bit platforms, use an extra field to store the key since child pointer packing 199*e7776783SApple OSS Distributions * is not an option. The child is maintained as a long to use the same packing/unpacking 200*e7776783SApple OSS Distributions * routines that work for 64-bit platforms. 201*e7776783SApple OSS Distributions */ 202*e7776783SApple OSS Distributions typedef struct priority_queue_entry_sched { 203*e7776783SApple OSS Distributions struct priority_queue_entry_sched *next; 204*e7776783SApple OSS Distributions struct priority_queue_entry_sched *prev; 205*e7776783SApple OSS Distributions long child; 206*e7776783SApple OSS Distributions priority_queue_key_t key; 207*e7776783SApple OSS Distributions } *priority_queue_entry_sched_t; 208*e7776783SApple OSS Distributions 209*e7776783SApple OSS Distributions typedef struct priority_queue_entry_stable { 210*e7776783SApple OSS Distributions struct priority_queue_entry_stable *next; 211*e7776783SApple OSS Distributions struct priority_queue_entry_stable *prev; 212*e7776783SApple OSS Distributions long child; 213*e7776783SApple OSS Distributions priority_queue_key_t key; 214*e7776783SApple OSS Distributions uint64_t stamp; 215*e7776783SApple OSS Distributions } *priority_queue_entry_stable_t; 216*e7776783SApple OSS Distributions 217*e7776783SApple OSS Distributions #endif /* __LP64__ */ 218*e7776783SApple OSS Distributions 219*e7776783SApple OSS Distributions /* 220*e7776783SApple OSS Distributions * Comparator block prototype 221*e7776783SApple OSS Distributions * Args: 222*e7776783SApple OSS Distributions * - elements to compare 223*e7776783SApple OSS Distributions * Return: 224*e7776783SApple OSS Distributions * comparision result to indicate relative ordering of elements according to the heap type 225*e7776783SApple OSS Distributions */ 226*e7776783SApple OSS Distributions typedef int (^priority_queue_compare_fn_t)(struct priority_queue_entry *e1, 227*e7776783SApple OSS Distributions struct priority_queue_entry *e2); 228*e7776783SApple OSS Distributions 229*e7776783SApple OSS Distributions #define priority_heap_compare_ints(a, b) ((a) < (b) ? 1 : -1) 230*e7776783SApple OSS Distributions 231*e7776783SApple OSS Distributions #define priority_heap_make_comparator(name1, name2, type, field, ...) \ 232*e7776783SApple OSS Distributions (^int(priority_queue_entry_t __e1, priority_queue_entry_t __e2){ \ 233*e7776783SApple OSS Distributions type *name1 = pqe_element_fast(__e1, type, field); \ 234*e7776783SApple OSS Distributions type *name2 = pqe_element_fast(__e2, type, field); \ 235*e7776783SApple OSS Distributions __VA_ARGS__; \ 236*e7776783SApple OSS Distributions }) 237*e7776783SApple OSS Distributions 238*e7776783SApple OSS Distributions /* 239*e7776783SApple OSS Distributions * Type for any priority queue, only used for documentation purposes. 240*e7776783SApple OSS Distributions */ 241*e7776783SApple OSS Distributions struct priority_queue; 242*e7776783SApple OSS Distributions 243*e7776783SApple OSS Distributions /* 244*e7776783SApple OSS Distributions * Type of generic heaps 245*e7776783SApple OSS Distributions */ 246*e7776783SApple OSS Distributions struct priority_queue_min { 247*e7776783SApple OSS Distributions struct priority_queue_entry *pq_root; 248*e7776783SApple OSS Distributions priority_queue_compare_fn_t pq_cmp_fn; 249*e7776783SApple OSS Distributions }; 250*e7776783SApple OSS Distributions struct priority_queue_max { 251*e7776783SApple OSS Distributions struct priority_queue_entry *pq_root; 252*e7776783SApple OSS Distributions priority_queue_compare_fn_t pq_cmp_fn; 253*e7776783SApple OSS Distributions }; 254*e7776783SApple OSS Distributions 255*e7776783SApple OSS Distributions /* 256*e7776783SApple OSS Distributions * Type of deadline heaps 257*e7776783SApple OSS Distributions */ 258*e7776783SApple OSS Distributions struct priority_queue_deadline_min { 259*e7776783SApple OSS Distributions struct priority_queue_entry_deadline *pq_root; 260*e7776783SApple OSS Distributions }; 261*e7776783SApple OSS Distributions struct priority_queue_deadline_max { 262*e7776783SApple OSS Distributions struct priority_queue_entry_deadline *pq_root; 263*e7776783SApple OSS Distributions }; 264*e7776783SApple OSS Distributions 265*e7776783SApple OSS Distributions /* 266*e7776783SApple OSS Distributions * Type of scheduler priority based heaps 267*e7776783SApple OSS Distributions */ 268*e7776783SApple OSS Distributions struct priority_queue_sched_min { 269*e7776783SApple OSS Distributions struct priority_queue_entry_sched *pq_root; 270*e7776783SApple OSS Distributions }; 271*e7776783SApple OSS Distributions struct priority_queue_sched_max { 272*e7776783SApple OSS Distributions struct priority_queue_entry_sched *pq_root; 273*e7776783SApple OSS Distributions }; 274*e7776783SApple OSS Distributions 275*e7776783SApple OSS Distributions /* 276*e7776783SApple OSS Distributions * Type of scheduler priority based stable heaps 277*e7776783SApple OSS Distributions */ 278*e7776783SApple OSS Distributions struct priority_queue_sched_stable_min { 279*e7776783SApple OSS Distributions struct priority_queue_entry_stable *pq_root; 280*e7776783SApple OSS Distributions }; 281*e7776783SApple OSS Distributions struct priority_queue_sched_stable_max { 282*e7776783SApple OSS Distributions struct priority_queue_entry_stable *pq_root; 283*e7776783SApple OSS Distributions }; 284*e7776783SApple OSS Distributions 285*e7776783SApple OSS Distributions #pragma mark generic interface 286*e7776783SApple OSS Distributions 287*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_INITIALIZER { .pq_root = NULL } 288*e7776783SApple OSS Distributions 289*e7776783SApple OSS Distributions #define __pqueue_overloadable __attribute__((overloadable)) 290*e7776783SApple OSS Distributions 291*e7776783SApple OSS Distributions #define priority_queue_is_min_heap(pq) _Generic(pq, \ 292*e7776783SApple OSS Distributions struct priority_queue_min *: true, \ 293*e7776783SApple OSS Distributions struct priority_queue_max *: false, \ 294*e7776783SApple OSS Distributions struct priority_queue_deadline_min *: true, \ 295*e7776783SApple OSS Distributions struct priority_queue_deadline_max *: false, \ 296*e7776783SApple OSS Distributions struct priority_queue_sched_min *: true, \ 297*e7776783SApple OSS Distributions struct priority_queue_sched_max *: false, \ 298*e7776783SApple OSS Distributions struct priority_queue_sched_stable_min *: true, \ 299*e7776783SApple OSS Distributions struct priority_queue_sched_stable_max *: false) 300*e7776783SApple OSS Distributions 301*e7776783SApple OSS Distributions #define priority_queue_is_max_heap(pq) \ 302*e7776783SApple OSS Distributions (!priority_queue_is_min_heap(pq)) 303*e7776783SApple OSS Distributions 304*e7776783SApple OSS Distributions /* 305*e7776783SApple OSS Distributions * Macro: pqe_element_fast 306*e7776783SApple OSS Distributions * Function: 307*e7776783SApple OSS Distributions * Convert a priority_queue_entry_t to a queue element pointer. 308*e7776783SApple OSS Distributions * Get a pointer to the user-defined element containing 309*e7776783SApple OSS Distributions * a given priority_queue_entry_t 310*e7776783SApple OSS Distributions * 311*e7776783SApple OSS Distributions * The fast variant assumes that `qe` is not NULL 312*e7776783SApple OSS Distributions * Header: 313*e7776783SApple OSS Distributions * pqe_element_fast(qe, type, field) 314*e7776783SApple OSS Distributions * <priority_queue_entry_t> qe 315*e7776783SApple OSS Distributions * <type> type of element in priority queue 316*e7776783SApple OSS Distributions * <field> chain field in (*<type>) 317*e7776783SApple OSS Distributions * Returns: 318*e7776783SApple OSS Distributions * <type *> containing qe 319*e7776783SApple OSS Distributions */ 320*e7776783SApple OSS Distributions #define pqe_element_fast(qe, type, field) __container_of(qe, type, field) 321*e7776783SApple OSS Distributions 322*e7776783SApple OSS Distributions /* 323*e7776783SApple OSS Distributions * Macro: pqe_element 324*e7776783SApple OSS Distributions * Function: 325*e7776783SApple OSS Distributions * Convert a priority_queue_entry_t to a queue element pointer. 326*e7776783SApple OSS Distributions * Get a pointer to the user-defined element containing 327*e7776783SApple OSS Distributions * a given priority_queue_entry_t 328*e7776783SApple OSS Distributions * 329*e7776783SApple OSS Distributions * The non fast variant handles NULL `qe` 330*e7776783SApple OSS Distributions * Header: 331*e7776783SApple OSS Distributions * pqe_element(qe, type, field) 332*e7776783SApple OSS Distributions * <priority_queue_entry_t> qe 333*e7776783SApple OSS Distributions * <type> type of element in priority queue 334*e7776783SApple OSS Distributions * <field> chain field in (*<type>) 335*e7776783SApple OSS Distributions * Returns: 336*e7776783SApple OSS Distributions * <type *> containing qe 337*e7776783SApple OSS Distributions */ 338*e7776783SApple OSS Distributions #define pqe_element(qe, type, field) ({ \ 339*e7776783SApple OSS Distributions __auto_type _tmp_entry = (qe); \ 340*e7776783SApple OSS Distributions _tmp_entry ? pqe_element_fast(_tmp_entry, type, field) : ((type *)NULL);\ 341*e7776783SApple OSS Distributions }) 342*e7776783SApple OSS Distributions 343*e7776783SApple OSS Distributions /* 344*e7776783SApple OSS Distributions * Priority Queue functionality routines 345*e7776783SApple OSS Distributions */ 346*e7776783SApple OSS Distributions 347*e7776783SApple OSS Distributions /* 348*e7776783SApple OSS Distributions * Macro: priority_queue_empty 349*e7776783SApple OSS Distributions * Function: 350*e7776783SApple OSS Distributions * Tests whether a priority queue is empty. 351*e7776783SApple OSS Distributions * Header: 352*e7776783SApple OSS Distributions * boolean_t priority_queue_empty(pq) 353*e7776783SApple OSS Distributions * <struct priority_queue *> pq 354*e7776783SApple OSS Distributions */ 355*e7776783SApple OSS Distributions #define priority_queue_empty(pq) ((pq)->pq_root == NULL) 356*e7776783SApple OSS Distributions 357*e7776783SApple OSS Distributions /* 358*e7776783SApple OSS Distributions * Macro: priority_queue_init 359*e7776783SApple OSS Distributions * Function: 360*e7776783SApple OSS Distributions * Initialize a <struct priority_queue *>. 361*e7776783SApple OSS Distributions * Header: 362*e7776783SApple OSS Distributions * priority_queue_init(pq) 363*e7776783SApple OSS Distributions * <struct priority_queue *> pq 364*e7776783SApple OSS Distributions * (optional) <cmp_fn> comparator function 365*e7776783SApple OSS Distributions * Returns: 366*e7776783SApple OSS Distributions * None 367*e7776783SApple OSS Distributions */ 368*e7776783SApple OSS Distributions __pqueue_overloadable 369*e7776783SApple OSS Distributions extern void 370*e7776783SApple OSS Distributions priority_queue_init(struct priority_queue *pq, ...); 371*e7776783SApple OSS Distributions 372*e7776783SApple OSS Distributions /* 373*e7776783SApple OSS Distributions * Macro: priority_queue_entry_init 374*e7776783SApple OSS Distributions * Function: 375*e7776783SApple OSS Distributions * Initialize a priority_queue_entry_t 376*e7776783SApple OSS Distributions * Header: 377*e7776783SApple OSS Distributions * priority_queue_entry_init(qe) 378*e7776783SApple OSS Distributions * <priority_queue_entry_t> qe 379*e7776783SApple OSS Distributions * Returns: 380*e7776783SApple OSS Distributions * None 381*e7776783SApple OSS Distributions */ 382*e7776783SApple OSS Distributions #define priority_queue_entry_init(qe) \ 383*e7776783SApple OSS Distributions __builtin_bzero(qe, sizeof(*(qe))) 384*e7776783SApple OSS Distributions 385*e7776783SApple OSS Distributions /* 386*e7776783SApple OSS Distributions * Macro: priority_queue_destroy 387*e7776783SApple OSS Distributions * Function: 388*e7776783SApple OSS Distributions * Destroy a priority queue safely. This routine accepts a callback 389*e7776783SApple OSS Distributions * to handle any cleanup for elements in the priority queue. The queue does 390*e7776783SApple OSS Distributions * not maintain its invariants while getting destroyed. The priority queue and 391*e7776783SApple OSS Distributions * the linkage nodes need to be re-initialized before re-using them. 392*e7776783SApple OSS Distributions * Header: 393*e7776783SApple OSS Distributions * priority_queue_destroy(pq, type, field, callback) 394*e7776783SApple OSS Distributions * <struct priority_queue *> pq 395*e7776783SApple OSS Distributions * <callback> callback for each element 396*e7776783SApple OSS Distributions * 397*e7776783SApple OSS Distributions * Returns: 398*e7776783SApple OSS Distributions * None 399*e7776783SApple OSS Distributions */ 400*e7776783SApple OSS Distributions #define priority_queue_destroy(pq, type, field, callback) \ 401*e7776783SApple OSS Distributions MACRO_BEGIN \ 402*e7776783SApple OSS Distributions void (^__callback)(type *) = (callback); /* type check */ \ 403*e7776783SApple OSS Distributions _priority_queue_destroy(pq, offsetof(type, field), \ 404*e7776783SApple OSS Distributions (void (^)(void *))(__callback)); \ 405*e7776783SApple OSS Distributions MACRO_END 406*e7776783SApple OSS Distributions 407*e7776783SApple OSS Distributions /* 408*e7776783SApple OSS Distributions * Macro: priority_queue_min 409*e7776783SApple OSS Distributions * Function: 410*e7776783SApple OSS Distributions * Lookup the minimum in a min-priority queue. 411*e7776783SApple OSS Distributions * 412*e7776783SApple OSS Distributions * Header: 413*e7776783SApple OSS Distributions * priority_queue_min(pq, type, field) 414*e7776783SApple OSS Distributions * <struct priority_queue *> pq 415*e7776783SApple OSS Distributions * <type> type of element in priority queue 416*e7776783SApple OSS Distributions * <field> chain field in (*<type>) 417*e7776783SApple OSS Distributions * Returns: 418*e7776783SApple OSS Distributions * <type *> root element 419*e7776783SApple OSS Distributions */ 420*e7776783SApple OSS Distributions #define priority_queue_min(pq, type, field) ({ \ 421*e7776783SApple OSS Distributions static_assert(priority_queue_is_min_heap(pq), "queue is min heap"); \ 422*e7776783SApple OSS Distributions pqe_element((pq)->pq_root, type, field); \ 423*e7776783SApple OSS Distributions }) 424*e7776783SApple OSS Distributions 425*e7776783SApple OSS Distributions /* 426*e7776783SApple OSS Distributions * Macro: priority_queue_max 427*e7776783SApple OSS Distributions * Function: 428*e7776783SApple OSS Distributions * Lookup the maximum element in a max-priority queue. 429*e7776783SApple OSS Distributions * 430*e7776783SApple OSS Distributions * Header: 431*e7776783SApple OSS Distributions * priority_queue_max(pq, type, field) 432*e7776783SApple OSS Distributions * <struct priority_queue *> pq 433*e7776783SApple OSS Distributions * <type> type of element in priority queue 434*e7776783SApple OSS Distributions * <field> chain field in (*<type>) 435*e7776783SApple OSS Distributions * Returns: 436*e7776783SApple OSS Distributions * <type *> root element 437*e7776783SApple OSS Distributions */ 438*e7776783SApple OSS Distributions #define priority_queue_max(pq, type, field) ({ \ 439*e7776783SApple OSS Distributions static_assert(priority_queue_is_max_heap(pq), "queue is max heap"); \ 440*e7776783SApple OSS Distributions pqe_element((pq)->pq_root, type, field); \ 441*e7776783SApple OSS Distributions }) 442*e7776783SApple OSS Distributions 443*e7776783SApple OSS Distributions /* 444*e7776783SApple OSS Distributions * Macro: priority_queue_insert 445*e7776783SApple OSS Distributions * Function: 446*e7776783SApple OSS Distributions * Insert an element into the priority queue 447*e7776783SApple OSS Distributions * 448*e7776783SApple OSS Distributions * The caller must have set the key prio to insertion 449*e7776783SApple OSS Distributions * 450*e7776783SApple OSS Distributions * Header: 451*e7776783SApple OSS Distributions * priority_queue_insert(pq, elt, new_key) 452*e7776783SApple OSS Distributions * <struct priority_queue *> pq 453*e7776783SApple OSS Distributions * <priority_queue_entry_t> elt 454*e7776783SApple OSS Distributions * Returns: 455*e7776783SApple OSS Distributions * Whether the inserted element became the new root 456*e7776783SApple OSS Distributions */ 457*e7776783SApple OSS Distributions extern bool 458*e7776783SApple OSS Distributions priority_queue_insert(struct priority_queue *pq, 459*e7776783SApple OSS Distributions struct priority_queue_entry *elt) __pqueue_overloadable; 460*e7776783SApple OSS Distributions 461*e7776783SApple OSS Distributions /* 462*e7776783SApple OSS Distributions * Macro: priority_queue_remove_min 463*e7776783SApple OSS Distributions * Function: 464*e7776783SApple OSS Distributions * Remove the minimum element in a min-heap priority queue. 465*e7776783SApple OSS Distributions * Header: 466*e7776783SApple OSS Distributions * priority_queue_remove_min(pq, type, field) 467*e7776783SApple OSS Distributions * <struct priority_queue *> pq 468*e7776783SApple OSS Distributions * <type> type of element in priority queue 469*e7776783SApple OSS Distributions * <field> chain field in (*<type>) 470*e7776783SApple OSS Distributions * Returns: 471*e7776783SApple OSS Distributions * <type *> max element 472*e7776783SApple OSS Distributions */ 473*e7776783SApple OSS Distributions #define priority_queue_remove_min(pq, type, field) ({ \ 474*e7776783SApple OSS Distributions static_assert(priority_queue_is_min_heap(pq), "queue is min heap"); \ 475*e7776783SApple OSS Distributions pqe_element(_priority_queue_remove_root(pq), type, field); \ 476*e7776783SApple OSS Distributions }) 477*e7776783SApple OSS Distributions 478*e7776783SApple OSS Distributions /* 479*e7776783SApple OSS Distributions * Macro: priority_queue_remove_max 480*e7776783SApple OSS Distributions * Function: 481*e7776783SApple OSS Distributions * Remove the maximum element in a max-heap priority queue. 482*e7776783SApple OSS Distributions * Header: 483*e7776783SApple OSS Distributions * priority_queue_remove_max(pq, type, field) 484*e7776783SApple OSS Distributions * <struct priority_queue *> pq 485*e7776783SApple OSS Distributions * <type> type of element in priority queue 486*e7776783SApple OSS Distributions * <field> chain field in (*<type>) 487*e7776783SApple OSS Distributions * Returns: 488*e7776783SApple OSS Distributions * <type *> max element 489*e7776783SApple OSS Distributions */ 490*e7776783SApple OSS Distributions #define priority_queue_remove_max(pq, type, field) ({ \ 491*e7776783SApple OSS Distributions static_assert(priority_queue_is_max_heap(pq), "queue is max heap"); \ 492*e7776783SApple OSS Distributions pqe_element(_priority_queue_remove_root(pq), type, field); \ 493*e7776783SApple OSS Distributions }) 494*e7776783SApple OSS Distributions 495*e7776783SApple OSS Distributions /* 496*e7776783SApple OSS Distributions * Macro: priority_queue_remove 497*e7776783SApple OSS Distributions * Function: 498*e7776783SApple OSS Distributions * Removes an element from the priority queue 499*e7776783SApple OSS Distributions * Header: 500*e7776783SApple OSS Distributions * priority_queue_remove(pq, elt) 501*e7776783SApple OSS Distributions * <struct priority_queue *> pq 502*e7776783SApple OSS Distributions * <priority_queue_entry_t> elt 503*e7776783SApple OSS Distributions * Returns: 504*e7776783SApple OSS Distributions * Whether the removed element was the root 505*e7776783SApple OSS Distributions */ 506*e7776783SApple OSS Distributions extern bool 507*e7776783SApple OSS Distributions priority_queue_remove(struct priority_queue *pq, 508*e7776783SApple OSS Distributions struct priority_queue_entry *elt) __pqueue_overloadable; 509*e7776783SApple OSS Distributions 510*e7776783SApple OSS Distributions 511*e7776783SApple OSS Distributions /* 512*e7776783SApple OSS Distributions * Macro: priority_queue_entry_decreased 513*e7776783SApple OSS Distributions * 514*e7776783SApple OSS Distributions * Function: 515*e7776783SApple OSS Distributions * Signal the priority queue that the entry priority has decreased. 516*e7776783SApple OSS Distributions * 517*e7776783SApple OSS Distributions * The new value for the element priority must have been set 518*e7776783SApple OSS Distributions * prior to calling this function. 519*e7776783SApple OSS Distributions * 520*e7776783SApple OSS Distributions * Header: 521*e7776783SApple OSS Distributions * priority_queue_entry_decreased(pq, elt) 522*e7776783SApple OSS Distributions * <struct priority_queue *> pq 523*e7776783SApple OSS Distributions * <priority_queue_entry_t> elt 524*e7776783SApple OSS Distributions * Returns: 525*e7776783SApple OSS Distributions * Whether the update caused the root or its key to change. 526*e7776783SApple OSS Distributions */ 527*e7776783SApple OSS Distributions extern bool 528*e7776783SApple OSS Distributions priority_queue_entry_decreased(struct priority_queue *pq, 529*e7776783SApple OSS Distributions struct priority_queue_entry *elt) __pqueue_overloadable; 530*e7776783SApple OSS Distributions 531*e7776783SApple OSS Distributions /* 532*e7776783SApple OSS Distributions * Macro: priority_queue_entry_increased 533*e7776783SApple OSS Distributions * 534*e7776783SApple OSS Distributions * Function: 535*e7776783SApple OSS Distributions * Signal the priority queue that the entry priority has increased. 536*e7776783SApple OSS Distributions * 537*e7776783SApple OSS Distributions * The new value for the element priority must have been set 538*e7776783SApple OSS Distributions * prior to calling this function. 539*e7776783SApple OSS Distributions * 540*e7776783SApple OSS Distributions * Header: 541*e7776783SApple OSS Distributions * priority_queue_entry_increased(pq, elt, new_key) 542*e7776783SApple OSS Distributions * <struct priority_queue *> pq 543*e7776783SApple OSS Distributions * <priority_queue_entry_t> elt 544*e7776783SApple OSS Distributions * Returns: 545*e7776783SApple OSS Distributions * Whether the update caused the root or its key to change. 546*e7776783SApple OSS Distributions */ 547*e7776783SApple OSS Distributions extern bool 548*e7776783SApple OSS Distributions priority_queue_entry_increased(struct priority_queue *pq, 549*e7776783SApple OSS Distributions struct priority_queue_entry *elt) __pqueue_overloadable; 550*e7776783SApple OSS Distributions 551*e7776783SApple OSS Distributions 552*e7776783SApple OSS Distributions #pragma mark priority_queue_sched_* 553*e7776783SApple OSS Distributions 554*e7776783SApple OSS Distributions __enum_decl(priority_queue_entry_sched_modifier_t, uint8_t, { 555*e7776783SApple OSS Distributions PRIORITY_QUEUE_ENTRY_NONE = 0, 556*e7776783SApple OSS Distributions PRIORITY_QUEUE_ENTRY_PREEMPTED = 1, 557*e7776783SApple OSS Distributions }); 558*e7776783SApple OSS Distributions 559*e7776783SApple OSS Distributions #define priority_queue_is_sched_heap(pq) _Generic(pq, \ 560*e7776783SApple OSS Distributions struct priority_queue_sched_min *: true, \ 561*e7776783SApple OSS Distributions struct priority_queue_sched_max *: true, \ 562*e7776783SApple OSS Distributions struct priority_queue_sched_stable_min *: true, \ 563*e7776783SApple OSS Distributions struct priority_queue_sched_stable_max *: true, \ 564*e7776783SApple OSS Distributions default: false) 565*e7776783SApple OSS Distributions 566*e7776783SApple OSS Distributions /* 567*e7776783SApple OSS Distributions * Macro: priority_queue_entry_set_sched_pri 568*e7776783SApple OSS Distributions * 569*e7776783SApple OSS Distributions * Function: 570*e7776783SApple OSS Distributions * Sets the scheduler priority on an entry supporting this concept. 571*e7776783SApple OSS Distributions * 572*e7776783SApple OSS Distributions * The priority is expected to fit on 8 bits. 573*e7776783SApple OSS Distributions * An optional sorting modifier. 574*e7776783SApple OSS Distributions * 575*e7776783SApple OSS Distributions * Header: 576*e7776783SApple OSS Distributions * priority_queue_entry_set_sched_pri(pq, elt, pri, modifier) 577*e7776783SApple OSS Distributions * <struct priority_queue *> pq 578*e7776783SApple OSS Distributions * <priority_queue_entry_t> elt 579*e7776783SApple OSS Distributions * <uint8_t> pri 580*e7776783SApple OSS Distributions * <priority_queue_entry_sched_modifier_t> modifier 581*e7776783SApple OSS Distributions */ 582*e7776783SApple OSS Distributions #define priority_queue_entry_set_sched_pri(pq, elt, pri, modifier) \ 583*e7776783SApple OSS Distributions MACRO_BEGIN \ 584*e7776783SApple OSS Distributions static_assert(priority_queue_is_sched_heap(pq), "is a sched heap"); \ 585*e7776783SApple OSS Distributions (elt)->key = (priority_queue_key_t)(((pri) << 8) + (modifier)); \ 586*e7776783SApple OSS Distributions MACRO_END 587*e7776783SApple OSS Distributions 588*e7776783SApple OSS Distributions /* 589*e7776783SApple OSS Distributions * Macro: priority_queue_entry_sched_pri 590*e7776783SApple OSS Distributions * 591*e7776783SApple OSS Distributions * Function: 592*e7776783SApple OSS Distributions * Return the scheduler priority on an entry supporting this 593*e7776783SApple OSS Distributions * concept. 594*e7776783SApple OSS Distributions * 595*e7776783SApple OSS Distributions * Header: 596*e7776783SApple OSS Distributions * priority_queue_entry_sched_pri(pq, elt) 597*e7776783SApple OSS Distributions * <struct priority_queue *> pq 598*e7776783SApple OSS Distributions * <priority_queue_entry_t> elt 599*e7776783SApple OSS Distributions * 600*e7776783SApple OSS Distributions * Returns: 601*e7776783SApple OSS Distributions * The scheduler priority of this entry 602*e7776783SApple OSS Distributions */ 603*e7776783SApple OSS Distributions #define priority_queue_entry_sched_pri(pq, elt) ({ \ 604*e7776783SApple OSS Distributions static_assert(priority_queue_is_sched_heap(pq), "is a sched heap"); \ 605*e7776783SApple OSS Distributions (priority_queue_key_t)((elt)->key >> 8); \ 606*e7776783SApple OSS Distributions }) 607*e7776783SApple OSS Distributions 608*e7776783SApple OSS Distributions /* 609*e7776783SApple OSS Distributions * Macro: priority_queue_entry_sched_modifier 610*e7776783SApple OSS Distributions * 611*e7776783SApple OSS Distributions * Function: 612*e7776783SApple OSS Distributions * Return the scheduler modifier on an entry supporting this 613*e7776783SApple OSS Distributions * concept. 614*e7776783SApple OSS Distributions * 615*e7776783SApple OSS Distributions * Header: 616*e7776783SApple OSS Distributions * priority_queue_entry_sched_modifier(pq, elt) 617*e7776783SApple OSS Distributions * <struct priority_queue *> pq 618*e7776783SApple OSS Distributions * <priority_queue_entry_t> elt 619*e7776783SApple OSS Distributions * 620*e7776783SApple OSS Distributions * Returns: 621*e7776783SApple OSS Distributions * The scheduler priority of this entry 622*e7776783SApple OSS Distributions */ 623*e7776783SApple OSS Distributions #define priority_queue_entry_sched_modifier(pq, elt) ({ \ 624*e7776783SApple OSS Distributions static_assert(priority_queue_is_sched_heap(pq), "is a sched heap"); \ 625*e7776783SApple OSS Distributions (priority_queue_entry_sched_modifier_t)(elt)->key; \ 626*e7776783SApple OSS Distributions }) 627*e7776783SApple OSS Distributions 628*e7776783SApple OSS Distributions /* 629*e7776783SApple OSS Distributions * Macro: priority_queue_min_sched_pri 630*e7776783SApple OSS Distributions * 631*e7776783SApple OSS Distributions * Function: 632*e7776783SApple OSS Distributions * Return the scheduler priority of the minimum element 633*e7776783SApple OSS Distributions * of a scheduler priority queue. 634*e7776783SApple OSS Distributions * 635*e7776783SApple OSS Distributions * Header: 636*e7776783SApple OSS Distributions * priority_queue_min_sched_pri(pq) 637*e7776783SApple OSS Distributions * <struct priority_queue *> pq 638*e7776783SApple OSS Distributions * 639*e7776783SApple OSS Distributions * Returns: 640*e7776783SApple OSS Distributions * The scheduler priority of this entry 641*e7776783SApple OSS Distributions */ 642*e7776783SApple OSS Distributions #define priority_queue_min_sched_pri(pq) ({ \ 643*e7776783SApple OSS Distributions static_assert(priority_queue_is_min_heap(pq), "queue is min heap"); \ 644*e7776783SApple OSS Distributions priority_queue_entry_sched_pri(pq, (pq)->pq_root); \ 645*e7776783SApple OSS Distributions }) 646*e7776783SApple OSS Distributions 647*e7776783SApple OSS Distributions /* 648*e7776783SApple OSS Distributions * Macro: priority_queue_max_sched_pri 649*e7776783SApple OSS Distributions * 650*e7776783SApple OSS Distributions * Function: 651*e7776783SApple OSS Distributions * Return the scheduler priority of the maximum element 652*e7776783SApple OSS Distributions * of a scheduler priority queue. 653*e7776783SApple OSS Distributions * 654*e7776783SApple OSS Distributions * Header: 655*e7776783SApple OSS Distributions * priority_queue_max_sched_pri(pq) 656*e7776783SApple OSS Distributions * <struct priority_queue *> pq 657*e7776783SApple OSS Distributions * 658*e7776783SApple OSS Distributions * Returns: 659*e7776783SApple OSS Distributions * The scheduler priority of this entry 660*e7776783SApple OSS Distributions */ 661*e7776783SApple OSS Distributions #define priority_queue_max_sched_pri(pq) ({ \ 662*e7776783SApple OSS Distributions static_assert(priority_queue_is_max_heap(pq), "queue is max heap"); \ 663*e7776783SApple OSS Distributions priority_queue_entry_sched_pri(pq, (pq)->pq_root); \ 664*e7776783SApple OSS Distributions }) 665*e7776783SApple OSS Distributions 666*e7776783SApple OSS Distributions 667*e7776783SApple OSS Distributions #pragma mark implementation details 668*e7776783SApple OSS Distributions 669*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_MAKE_BASE(pqueue_t, pqelem_t) \ 670*e7776783SApple OSS Distributions \ 671*e7776783SApple OSS Distributions __pqueue_overloadable extern void \ 672*e7776783SApple OSS Distributions _priority_queue_destroy(pqueue_t pq, uintptr_t offset, void (^cb)(void *)); \ 673*e7776783SApple OSS Distributions \ 674*e7776783SApple OSS Distributions __pqueue_overloadable extern bool \ 675*e7776783SApple OSS Distributions priority_queue_insert(pqueue_t que, pqelem_t elt); \ 676*e7776783SApple OSS Distributions \ 677*e7776783SApple OSS Distributions __pqueue_overloadable extern pqelem_t \ 678*e7776783SApple OSS Distributions _priority_queue_remove_root(pqueue_t que); \ 679*e7776783SApple OSS Distributions \ 680*e7776783SApple OSS Distributions __pqueue_overloadable extern bool \ 681*e7776783SApple OSS Distributions priority_queue_remove(pqueue_t que, pqelem_t elt); \ 682*e7776783SApple OSS Distributions \ 683*e7776783SApple OSS Distributions __pqueue_overloadable extern bool \ 684*e7776783SApple OSS Distributions priority_queue_entry_decreased(pqueue_t que, pqelem_t elt); \ 685*e7776783SApple OSS Distributions \ 686*e7776783SApple OSS Distributions __pqueue_overloadable extern bool \ 687*e7776783SApple OSS Distributions priority_queue_entry_increased(pqueue_t que, pqelem_t elt) 688*e7776783SApple OSS Distributions 689*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_MAKE(pqueue_t, pqelem_t) \ 690*e7776783SApple OSS Distributions __pqueue_overloadable \ 691*e7776783SApple OSS Distributions static inline void \ 692*e7776783SApple OSS Distributions priority_queue_init(pqueue_t que) \ 693*e7776783SApple OSS Distributions { \ 694*e7776783SApple OSS Distributions __builtin_bzero(que, sizeof(*que)); \ 695*e7776783SApple OSS Distributions } \ 696*e7776783SApple OSS Distributions \ 697*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE_BASE(pqueue_t, pqelem_t) 698*e7776783SApple OSS Distributions 699*e7776783SApple OSS Distributions #define PRIORITY_QUEUE_MAKE_CB(pqueue_t, pqelem_t) \ 700*e7776783SApple OSS Distributions __pqueue_overloadable \ 701*e7776783SApple OSS Distributions static inline void \ 702*e7776783SApple OSS Distributions priority_queue_init(pqueue_t pq, priority_queue_compare_fn_t cmp_fn) \ 703*e7776783SApple OSS Distributions { \ 704*e7776783SApple OSS Distributions pq->pq_root = NULL; \ 705*e7776783SApple OSS Distributions pq->pq_cmp_fn = cmp_fn; \ 706*e7776783SApple OSS Distributions } \ 707*e7776783SApple OSS Distributions \ 708*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE_BASE(pqueue_t, pqelem_t) 709*e7776783SApple OSS Distributions 710*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE_CB(struct priority_queue_min *, priority_queue_entry_t); 711*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE_CB(struct priority_queue_max *, priority_queue_entry_t); 712*e7776783SApple OSS Distributions 713*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE(struct priority_queue_deadline_min *, priority_queue_entry_deadline_t); 714*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE(struct priority_queue_deadline_max *, priority_queue_entry_deadline_t); 715*e7776783SApple OSS Distributions 716*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE(struct priority_queue_sched_min *, priority_queue_entry_sched_t); 717*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE(struct priority_queue_sched_max *, priority_queue_entry_sched_t); 718*e7776783SApple OSS Distributions 719*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE(struct priority_queue_sched_stable_min *, priority_queue_entry_stable_t); 720*e7776783SApple OSS Distributions PRIORITY_QUEUE_MAKE(struct priority_queue_sched_stable_max *, priority_queue_entry_stable_t); 721*e7776783SApple OSS Distributions 722*e7776783SApple OSS Distributions __END_DECLS 723*e7776783SApple OSS Distributions 724*e7776783SApple OSS Distributions #pragma GCC visibility pop 725*e7776783SApple OSS Distributions 726*e7776783SApple OSS Distributions #endif /* _KERN_PRIORITY_QUEUE_H_ */ 727