xref: /xnu-8796.121.2/tests/recount/coalition_info_tests.c (revision c54f35ca767986246321eb901baf8f5ff7923f6a)
1 #include <darwintest.h>
2 #include <inttypes.h>
3 #include <mach/coalition.h>
4 #include <stdint.h>
5 #include <sys/coalition.h>
6 #include <sys/sysctl.h>
7 #include <libproc.h>
8 #include <unistd.h>
9 
10 #include "test_utils.h"
11 
12 T_GLOBAL_META(
13 	T_META_RADAR_COMPONENT_NAME("xnu"),
14 	T_META_RADAR_COMPONENT_VERSION("RM"),
15     T_META_OWNER("mwidmann"),
16     T_META_RUN_CONCURRENTLY(true),
17     T_META_ASROOT(true),
18     T_META_CHECK_LEAKS(false));
19 
20 static void
skip_if_monotonic_unsupported(void)21 skip_if_monotonic_unsupported(void)
22 {
23 	int r;
24 	int supported = 0;
25 	size_t supported_size = sizeof(supported);
26 
27 	r = sysctlbyname("kern.monotonic.supported", &supported, &supported_size,
28 	    NULL, 0);
29 	if (r < 0) {
30 		T_WITH_ERRNO;
31 		T_SKIP("could not find \"kern.monotonic.supported\" sysctl");
32 	}
33 
34 	if (!supported) {
35 		T_SKIP("monotonic is not supported on this platform");
36 	}
37 }
38 
39 T_DECL(coalition_resource_info_counters,
40     "ensure that coalition resource info produces valid counter data")
41 {
42 	skip_if_monotonic_unsupported();
43 
44 	T_SETUPBEGIN;
45 
46 	struct proc_pidcoalitioninfo idinfo = {};
47 	int ret = proc_pidinfo(getpid(), PROC_PIDCOALITIONINFO, 0,
48 	    &idinfo, sizeof(idinfo));
49 	T_ASSERT_POSIX_SUCCESS(ret, "proc_pidinfo(... PROC_PIDCOALITIONINFO ...)");
50 
51 	uint64_t resid = idinfo.coalition_id[COALITION_TYPE_RESOURCE];
52 
53 	struct coalition_resource_usage coalusage[2] = {};
54 	ret = coalition_info_resource_usage(resid, &coalusage[0],
55 	    sizeof(coalusage[0]));
56 	T_ASSERT_POSIX_SUCCESS(ret, "coalition_info_resource_usage()");
57 
58 	T_SETUPEND;
59 
60 	T_EXPECT_GT(coalusage[0].cpu_instructions, UINT64_C(0),
61 	    "instruction count is non-zero");
62 	T_EXPECT_GT(coalusage[0].cpu_cycles, UINT64_C(0),
63 	    "cycle count is non-zero");
64 
65 	sleep(1);
66 
67 	T_SETUPBEGIN;
68 	ret = coalition_info_resource_usage(resid, &coalusage[1],
69 	    sizeof(coalusage[1]));
70 	T_ASSERT_POSIX_SUCCESS(ret, "coalition_info_resource_usage()");
71 	T_SETUPEND;
72 
73 	T_EXPECT_GE(coalusage[1].cpu_instructions, coalusage[0].cpu_instructions,
74 	    "instruction count is monotonically increasing (+%" PRIu64 ")",
75 	    coalusage[1].cpu_instructions - coalusage[0].cpu_instructions);
76 	T_EXPECT_GE(coalusage[1].cpu_cycles, coalusage[0].cpu_cycles,
77 	    "cycle count is monotonically increasing (+%" PRIu64 ")",
78 	    coalusage[1].cpu_cycles - coalusage[0].cpu_cycles);
79 }
80 
81 T_DECL(coalition_resource_info_kernel_ptime_sane,
82     "ensure that coalition resource info for the kernel has a sane P-CPU time")
83 {
84 	T_SETUPBEGIN;
85 	struct proc_pidcoalitioninfo idinfo = {};
86 	int ret = proc_pidinfo(0, PROC_PIDCOALITIONINFO, 0, &idinfo,
87 	    sizeof(idinfo));
88 	T_ASSERT_POSIX_SUCCESS(ret, "proc_pidinfo(... PROC_PIDCOALITIONINFO ...)");
89 
90 	uint64_t resid = idinfo.coalition_id[COALITION_TYPE_RESOURCE];
91 
92 	struct coalition_resource_usage coalusage = {};
93 	ret = coalition_info_resource_usage(resid, &coalusage,
94 	    sizeof(coalusage));
95 	T_ASSERT_POSIX_SUCCESS(ret, "coalition_info_resource_usage()");
96 	T_SETUPEND;
97 
98 	uint64_t non_ptime = coalusage.cpu_time - coalusage.cpu_ptime;
99 	T_LOG("CPU time = %llu, P-CPU time = %llu (non-P-CPU time = %llu/%.2g%%)",
100 	    coalusage.cpu_time, coalusage.cpu_ptime, non_ptime,
101 	    (double)non_ptime / (double)coalusage.cpu_time * 100.0);
102 	T_EXPECT_GT(coalusage.cpu_time, UINT64_C(0), "CPU time is non-zero");
103 	T_EXPECT_GT(coalusage.cpu_time, coalusage.cpu_ptime,
104 	    "P-CPU time is <= CPU time");
105 }
106