xref: /xnu-12377.1.9/osfmk/kern/sched_common.h (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
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