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