1 /* 2 * Copyright (c) 2024 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 #ifndef _KERN_SCHED_COMMON_H_ 30 #define _KERN_SCHED_COMMON_H_ 31 32 #include <kern/assert.h> 33 #include <kern/qsort.h> 34 #include <kern/smp.h> 35 36 typedef uint8_t pset_id_t; 37 static_assert(MAX_PSETS < UINT8_MAX, "Can store pset ids within 8 bits"); 38 #define PSET_ID_INVALID UINT8_MAX 39 40 #if __AMP__ 41 42 /* 43 * sched_pset_search_order_t 44 * 45 * Used for storing a computed search order of pset ids, relative to a 46 * scanning pset not included in the list. 47 * 48 * Storing/accessing the search order atomically avoids issues caused 49 * by editing the search order while processors are in the middle of 50 * traversing it, for example causing them to miss a pset or visit a 51 * particular pset more than once. Instead, the search order should be 52 * read atomically before traversing, so that new edits are ignored by 53 * that processor until its traversal is complete. 54 */ 55 typedef union { 56 pset_id_t spso_search_order[MAX_PSETS - 1]; 57 unsigned __int128 spso_packed; 58 } sched_pset_search_order_t; 59 60 static_assert(sizeof(sched_pset_search_order_t) <= sizeof(unsigned __int128), 61 "(MAX_PSETS - 1) * 8 bits fits in 128 bits, allowing sched_pset_search_order_t fields " 62 "to be accessed atomically"); 63 64 typedef struct processor_set *processor_set_t; 65 66 /* 67 * sched_pset_search_order_sort_data_t 68 * 69 * Pset data used when generating search orders, expected to be 70 * populated for each pset before calling sched_pset_search_order_compute() 71 */ 72 typedef struct { 73 processor_set_t spsosd_src_pset; 74 uint64_t spsosd_migration_weight; 75 pset_id_t spsosd_dst_pset_id; 76 } sched_pset_search_order_sort_data_t; 77 78 /* 79 * sched_pset_search_order_sort_cmpfunc_t 80 * 81 * Expected to compare two sched_pset_search_order_sort_data_t pointers, 82 * for the purpose of generating a pset search order. 83 */ 84 typedef cmpfunc_t sched_pset_search_order_sort_cmpfunc_t; 85 86 /* 87 * sched_pset_search_order_compute() 88 * 89 * Generates a pset search order by sorting the per-pset search order datas 90 * using the given comparator. 91 */ 92 void 93 sched_pset_search_order_compute(sched_pset_search_order_t *search_order_out, 94 sched_pset_search_order_sort_data_t *datas, size_t num_datas, 95 sched_pset_search_order_sort_cmpfunc_t cmp); 96 97 /* 98 * sched_pset_search_order_init() 99 * 100 * Generates a search order of all psets sorted by increasing pset id, still 101 * excluding the source pset. 102 */ 103 void 104 sched_pset_search_order_init(processor_set_t src_pset, sched_pset_search_order_t *search_order_out); 105 106 /* 107 * sched_pset_iterate_state_t 108 * 109 * Used for tracking state across calls to sched_iterate_psets_ordered() 110 * for the same search order traversal, and for returning the current pset_id. 111 */ 112 typedef struct { 113 int spis_search_index; 114 sched_pset_search_order_t spis_cached_search_order; 115 int spis_pset_id; // out 116 } sched_pset_iterate_state_t; 117 118 #define SCHED_PSET_ITERATE_STATE_INIT ((sched_pset_iterate_state_t) { .spis_search_index = -1 }) 119 120 /* 121 * sched_iterate_psets_ordered() 122 * 123 * Routine to iterate through candidate psets based on a given search_order 124 * and starting from starting_pset. 125 * Returns true if iteration continues and another candidate pset was found, 126 * which will be stored at istate->spis_pset_id. Returns false and 127 * istate->spis_pset_id of -1 once iteration is complete. Iterate state should 128 * start out initialized to SCHED_PSET_ITERATE_STATE_INIT. 129 */ 130 bool 131 sched_iterate_psets_ordered(processor_set_t starting_pset, sched_pset_search_order_t *search_order, 132 uint64_t candidate_map, sched_pset_iterate_state_t *istate); 133 134 #endif /* __AMP__ */ 135 136 #endif /* _KERN_SCHED_COMMON_H_ */ 137