1 // Copyright (c) 2021-2022 Apple Inc. All rights reserved. 2 3 #pragma once 4 5 #include <mach/time_value.h> 6 #include <os/base.h> 7 #include <pthread/pthread.h> 8 #include <stdbool.h> 9 #include <stdint.h> 10 11 #define ARRAY_COUNT(_a) (sizeof((_a)) / sizeof((_a[0]))) 12 13 #define REQUIRE_RECOUNT_PMCS \ 14 T_META_REQUIRES_SYSCTL_EQ("kern.monotonic.supported", 1) 15 #define REQUIRE_RECOUNT_ENERGY \ 16 T_META_REQUIRES_SYSTCL_EQ("kern.pervasive_energy", 1) 17 #define REQUIRE_MULTIPLE_PERF_LEVELS \ 18 T_META_REQUIRES_SYSCTL_NE("hw.nperflevels", 1) 19 #define REQUIRE_EXCLAVES \ 20 T_META_REQUIRES_SYSCTL_EQ("kern.exclaves_status", 1) 21 #define SET_THREAD_BIND_BOOTARG \ 22 T_META_BOOTARGS_SET("enable_skstb=1") 23 24 // Enable/disable `T_MAYFAIL` for any expects annotated with 25 // `T_MAYFAIL_IF_ENABLED`. Defaults to disabled. 26 void set_expects_may_fail(bool may_fail); 27 28 // Returns whether may-fail is currently enabled (for expects 29 // annotated with `T_MAYFAIL_IF_ENABLED`). 30 bool expects_may_fail(void); 31 32 #define T_MAYFAIL_IF_ENABLED(reason) { if (expects_may_fail()) { T_MAYFAIL_WITH_REASON(reason); } } 33 34 // Returns true if the system implicitly tracks CPI. 35 bool has_cpi(void); 36 37 // Returns true if precise user kernel (system) times are being tracked, 38 // and false otherwise. 39 bool has_user_system_times(void); 40 41 // Returns true if the system can track energy usage. 42 bool has_energy(void); 43 44 // Bind the current thread to the given cluster. 45 void bind_to_cluster(char type); 46 47 // Returns the name of the current scheduler policy. 48 char *sched_policy_name(void); 49 50 // Returns the number of perf-levels on the system. 51 unsigned int perf_level_count(void); 52 53 // Returns the name of the specified perf-level. 54 const char *perf_level_name(unsigned int perf_level); 55 56 // Returns the index of the named perf-level. 57 unsigned int perf_level_index(const char *name); 58 59 // Run temporarily on all perf levels -- must have `SET_THREAD_BIND_BOOTARG`. 60 void run_on_all_perf_levels(void); 61 62 // Run temporarily in exclaves on all perf levels -- must have 63 // `SET_THREAD_BIND_BOOTARG` and 64 void run_in_exclaves_on_all_perf_levels(void); 65 66 // Return the nanoseconds represented by a Mach time. 67 uint64_t ns_from_mach(uint64_t mach_time); 68 69 // Return the nanoseconds represented by a timeval. 70 uint64_t ns_from_timeval(struct timeval tv); 71 72 // Return the timeval represented by nanoseconds. 73 struct timeval timeval_from_ns(uint64_t ns); 74 75 // Return the nanoseconds represented by a Mach time_value. 76 uint64_t ns_from_time_value(struct time_value tv); 77 78 // Return the Mach time_value represented by nanoseconds. 79 struct time_value time_value_from_ns(uint64_t ns); 80 81 // What an actor should do when it's running. 82 __enum_decl(role_t, uint32_t, { 83 ROLE_NONE, 84 ROLE_SPIN, 85 ROLE_WAIT, 86 }); 87 88 // A thread doing work according to a script. 89 struct actor { 90 pthread_t act_thread; 91 role_t act_role; 92 void *act_context; 93 }; 94 95 struct scene { 96 unsigned int scn_actor_count; 97 uintptr_t scn_spin_sync; 98 void *scn_wait_sync; 99 struct actor scn_actors[]; 100 }; 101 102 // Start `n` threads that follow a given pattern of scripts. 103 struct scene *scene_start(unsigned int n, role_t *roles); 104 105 // Stop and destroy previously-started actors. 106 void scene_end(struct scene *scene); 107 108 // Launch a `T_HELPER_DECL`-based helper. 109 pid_t launch_helper(char *name); 110