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