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