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