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