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_EQ("hw.nperflevels", 2) 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 // Returns true if the system implicitly tracks CPI. 25 bool has_cpi(void); 26 27 // Returns true if precise user kernel (system) times are being tracked, 28 // and false otherwise. 29 bool has_user_system_times(void); 30 31 // Returns true if the system can track energy usage. 32 bool has_energy(void); 33 34 // Bind the current thread to the given cluster. 35 void bind_to_cluster(char type); 36 37 // Returns the number of perf-levels on the system. 38 unsigned int perf_level_count(void); 39 40 // Returns the name of the specified perf-level. 41 const char *perf_level_name(unsigned int perf_level); 42 43 // Returns the index of the named perf-level. 44 unsigned int perf_level_index(const char *name); 45 46 // Run temporarily on all perf levels -- must have `SET_THREAD_BIND_BOOTARG`. 47 void run_on_all_perf_levels(void); 48 49 // Run temporarily in exclaves on all perf levels -- must have 50 // `SET_THREAD_BIND_BOOTARG` and 51 void run_in_exclaves_on_all_perf_levels(void); 52 53 // Return the nanoseconds represented by a Mach time. 54 uint64_t ns_from_mach(uint64_t mach_time); 55 56 // Return the nanoseconds represented by a timeval. 57 uint64_t ns_from_timeval(struct timeval tv); 58 59 // Return the timeval represented by nanoseconds. 60 struct timeval timeval_from_ns(uint64_t ns); 61 62 // Return the nanoseconds represented by a Mach time_value. 63 uint64_t ns_from_time_value(struct time_value tv); 64 65 // Return the Mach time_value represented by nanoseconds. 66 struct time_value time_value_from_ns(uint64_t ns); 67 68 // What an actor should do when it's running. 69 __enum_decl(role_t, uint32_t, { 70 ROLE_NONE, 71 ROLE_SPIN, 72 ROLE_WAIT, 73 }); 74 75 // A thread doing work according to a script. 76 struct actor { 77 pthread_t act_thread; 78 role_t act_role; 79 void *act_context; 80 }; 81 82 struct scene { 83 unsigned int scn_actor_count; 84 uintptr_t scn_spin_sync; 85 void *scn_wait_sync; 86 struct actor scn_actors[]; 87 }; 88 89 // Start `n` threads that follow a given pattern of scripts. 90 struct scene *scene_start(unsigned int n, role_t *roles); 91 92 // Stop and destroy previously-started actors. 93 void scene_end(struct scene *scene); 94 95 // Launch a `T_HELPER_DECL`-based helper. 96 pid_t launch_helper(char *name); 97