+++ /dev/null
-/*
- * Copyright (c) 2018 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <kern/priority_queue.h>
-#include <mach/vm_param.h>
-
-#ifdef __LP64__
-static_assert(PRIORITY_QUEUE_ENTRY_CHILD_BITS >= VM_KERNEL_POINTER_SIGNIFICANT_BITS,
- "Priority Queue child pointer packing failed");
-#endif
-
-priority_queue_entry_t
-pqueue_pair_meld(priority_queue_entry_t elt, priority_queue_compare_fn_t cmp_fn)
-{
- priority_queue_entry_t pq_meld_result = NULL;
- priority_queue_entry_t pair_list = NULL;
-
- assert(elt); // caller needs to check this.
-
- /* Phase 1: */
- /* Split the list into a set of pairs going front to back. */
- /* Hook these pairs onto an intermediary list in reverse order of traversal.*/
-
- do {
- /* Consider two elements at a time for pairing */
- priority_queue_entry_t pair_item_a = elt;
- priority_queue_entry_t pair_item_b = elt->next;
- if (pair_item_b == NULL) {
- /* Odd number of elements in the list; link the odd element */
- /* as it is on the intermediate list. */
- pair_item_a->prev = pair_list;
- pair_list = pair_item_a;
- break;
- }
- /* Found two elements to pair up */
- elt = pair_item_b->next;
- priority_queue_entry_t pair = pqueue_merge(pair_item_a, pair_item_b, cmp_fn);
- /* Link the pair onto the intermediary list */
- pair->prev = pair_list;
- pair_list = pair;
- } while (elt != NULL);
-
- /* Phase 2: Merge all the pairs in the pair_list */
- do {
- elt = pair_list->prev;
- pq_meld_result = pqueue_merge(pq_meld_result, pair_list, cmp_fn);
- pair_list = elt;
- } while (pair_list != NULL);
-
- return pq_meld_result;
-}
-
-void
-pqueue_destroy(struct priority_queue *q, size_t offset,
- void (^callback)(void *e))
-{
- assert(callback != NULL);
- priority_queue_entry_t head = pqueue_unpack_root(q);
- priority_queue_entry_t tail = head;
-
- while (head != NULL) {
- priority_queue_entry_t child_list = pqueue_entry_unpack_child(head);
- if (child_list) {
- tail->next = child_list;
- while (tail->next) {
- tail = tail->next;
- }
- }
-
- priority_queue_entry_t elt = head;
- head = head->next;
- callback((void *)elt - offset);
- }
-
- /* poison the queue now that it's destroyed */
- q->pq_root_packed = ~0UL;
-}