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