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