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