xref: /xnu-12377.41.6/tests/sched/sched_test_utils.h (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1 // Copyright (c) 2024 Apple Inc.  All rights reserved.
2 #ifndef XNU_SCHED_TEST_UTILS_H
3 #define XNU_SCHED_TEST_UTILS_H
4 
5 #include <stdbool.h>
6 #include <stdint.h>
7 #include <pthread.h>
8 
9 /* -- Meta-controls -- */
10 
11 /* Verbose printing mode is enabled by default */
12 void disable_verbose_sched_utils(void);
13 void reenable_verbose_sched_utils(void);
14 
15 /* -- Time conversions -- */
16 uint64_t nanos_to_abs(uint64_t nanos);
17 uint64_t abs_to_nanos(uint64_t abs);
18 
19 /* -- �� Thread orchestration -- */
20 void spin_for_duration(uint32_t seconds);
21 void stop_spinning_threads(void);
22 
23 /*
24  * Cluster-binding interfaces perform a soft bind on the current
25  * thread and require "enable_skstb=1" boot-arg to be set.
26  */
27 
28 /* Returns the old bound type ('0' for unbound) */
29 char bind_to_cluster_of_type(char type);
30 /* Returns the old bound id (-1 for unbound) */
31 int bind_to_cluster_id(int cluster_id);
32 
33 /*
34  * Functions to create pthreads, optionally configured with
35  * a number of pthread attributes:
36  */
37 void create_thread_pri(pthread_t *thread_handle, int priority, void *(*func)(void *), void *arg);
38 typedef enum {
39 	eDetached,
40 	eJoinable, // default
41 } detach_state_t;
42 typedef enum {
43 	eSchedFIFO = 4,
44 	eSchedRR = 2,
45 	eSchedOther = 1,
46 	eSchedDefault = 0, // default
47 } sched_policy_t;
48 #define DEFAULT_STACK_SIZE 0
49 // Default qos_class is QOS_CLASS_UNSPECIFIED
50 pthread_attr_t *
51 create_pthread_attr(int priority,
52     detach_state_t detach_state, qos_class_t qos_class,
53     sched_policy_t sched_policy, size_t stack_size);
54 void create_thread(pthread_t *thread_handle, pthread_attr_t *attr, void *(*func)(void *), void *arg);
55 pthread_t *create_threads(int num_threads, int priority,
56     detach_state_t detach_state, qos_class_t qos_class,
57     sched_policy_t sched_policy, size_t stack_size,
58     void *(*func)(void *), void *arg_array[]);
59 
60 /* -- ��️ Platform checks -- */
61 bool platform_is_amp(void);
62 bool platform_is_virtual_machine(void);
63 char *platform_sched_policy(void);
64 unsigned int platform_num_clusters(void);
65 const char *platform_perflevel_name(unsigned int perflevel);
66 unsigned int platform_perflevel_ncpus(unsigned int perflevel);
67 unsigned int platform_nperflevels(void);
68 const char *platform_train_descriptor(void);
69 
70 /* -- ���� Monitor system performance state -- */
71 
72 /*
73  * Returns true if the system successfully quiesced below the specified threshold
74  * within the specified timeout, and false otherwise.
75  * idle_threshold is given as a ratio between [0.0, 1.0], defaulting to 0.9.
76  * Passing argument --no-quiesce disables waiting for quiescence.
77  */
78 bool wait_for_quiescence(int argc, char *const argv[], double idle_threshold, int timeout_seconds);
79 bool wait_for_quiescence_default(int argc, char *const argv[]);
80 
81 /* Returns true if all cores on the device are recommended */
82 bool check_recommended_core_mask(uint64_t *core_mask);
83 
84 /* -- ��️ Query/control CPU topology -- */
85 
86 /*
87  * Spawns and waits for clpcctrl with the given arguments.
88  * If read_value is true, returns the value assumed to be elicited from clpcctrl.
89  */
90 uint64_t execute_clpcctrl(char *clpcctrl_args[], bool read_value);
91 
92 /* -- ��️ Record traces -- */
93 
94 /*
95  * Tracing requires root privilege.
96  *
97  * Standard usage of this interface would be to call begin_collect_trace()
98  * followed by end_collect_trace() and allow the library to automatically
99  * handle saving/discarding the collected trace upon test end. Traces will
100  * automatically be saved if a failure occurred during the test run and
101  * discarded otherwise.
102  */
103 
104 typedef void *trace_handle_t;
105 
106 __options_decl(collect_trace_flags_t, uint32_t, {
107 	COLLECT_TRACE_FLAG_NONE                 = 0x00,
108 	COLLECT_TRACE_FLAG_DISABLE_SYSCALLS     = 0x01,
109 	COLLECT_TRACE_FLAG_DISABLE_CLUTCH       = 0x02,
110 });
111 
112 /*
113  * Begins trace collection, using the specified name as a prefix for all
114  * generated filenames. Arguments are parsed to check for --no-trace or
115  * --save-trace options, which disable tracing and enable unconditional
116  * saving of the trace file respectively.
117  *
118  * NOTE: Since scheduler tracing can generate large trace files when left to
119  * run for long durations, take care to begin tracing close to the start of
120  * the period of interest.
121  */
122 trace_handle_t begin_collect_trace(int argc, char *const argv[], char *filename);
123 trace_handle_t begin_collect_trace_fmt(collect_trace_flags_t flags, int argc, char *const argv[], char *filename_fmt, ...);
124 
125 /*
126  * NOTE: It's possible that tests may induce CPU starvation that can
127  * prevent the trace from ending or cause post-processing to take an extra
128  * long time. This can be avoided by terminating or blocking spawned test
129  * threads before calling end_collect_trace().
130  */
131 void end_collect_trace(trace_handle_t handle);
132 
133 /*
134  * Saves the recorded trace file to a tarball and marks the tarball for
135  * upload in BATS as a debugging artifact.
136  */
137 void save_collected_trace(trace_handle_t handle);
138 
139 /* Deletes the recorded trace */
140 void discard_collected_trace(trace_handle_t handle);
141 
142 /* Drop a tracepoint for test failure. */
143 void sched_kdebug_test_fail(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3);
144 
145 #endif /* XNU_SCHED_TEST_UTILS_H */
146