xref: /xnu-11215.81.4/tests/recount/recount_test_utils.h (revision d4514f0bc1d3f944c22d92e68b646ac3fb40d452)
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