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