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