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