xref: /xnu-8796.101.5/tests/zero_to_n_tests.c (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5)
1 #include <darwintest.h>
2 #include <darwintest_utils.h>
3 #include <perfdata/perfdata.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdbool.h>
7 #include <errno.h>
8 #include "test_utils.h"
9 
10 #if defined(__arm64__)
11 T_GLOBAL_META(
12 	T_META_TAG_PERF,
13 	T_META_RUN_CONCURRENTLY(false),
14 	T_META_BOOTARGS_SET("enable_skstsct=1"),
15 	T_META_CHECK_LEAKS(false),
16 	T_META_ASROOT(true),
17 	T_META_REQUIRES_SYSCTL_EQ("kern.hv_vmm_present", 0),
18 	T_META_RADAR_COMPONENT_NAME("xnu"),
19 	T_META_RADAR_COMPONENT_VERSION("scheduler"),
20 	T_META_OWNER("ngamble")
21 	);
22 #else
23 T_GLOBAL_META(
24 	T_META_TAG_PERF,
25 	T_META_RUN_CONCURRENTLY(false),
26 	T_META_CHECK_LEAKS(false),
27 	T_META_ASROOT(true),
28 	T_META_REQUIRES_SYSCTL_EQ("kern.hv_vmm_present", 0),
29 	T_META_RADAR_COMPONENT_NAME("xnu"),
30 	T_META_RADAR_COMPONENT_VERSION("scheduler"),
31 	T_META_OWNER("ngamble")
32 	);
33 #endif
34 
35 static void
log_cmd(char ** cmd)36 log_cmd(char **cmd)
37 {
38 #define MAX_CMD_STR 1024
39 	char cmd_str[MAX_CMD_STR] = "";
40 	char *s;
41 
42 	while ((s = *cmd) != NULL) {
43 		strlcat(cmd_str, s, MAX_CMD_STR);
44 		strlcat(cmd_str, " ", MAX_CMD_STR);
45 		cmd++;
46 	}
47 	T_LOG("%s\n", cmd_str);
48 }
49 
50 static void
run_zn(char * name,char ** cmd)51 run_zn(char *name, char **cmd)
52 {
53 	char tracefile_path[MAXPATHLEN] = "zn.artrace";
54 	snprintf(tracefile_path, MAXPATHLEN, "%s.artrace", name);
55 
56 	int ret = dt_resultfile(tracefile_path, sizeof(tracefile_path));
57 	if (ret) {
58 		T_ASSERT_FAIL("get file path for trace file failed with errno %d", errno);
59 	}
60 
61 	cmd[3] = tracefile_path;
62 	log_cmd(cmd);
63 
64 	__block bool test_failed = true;
65 	__block bool test_skipped = false;
66 
67 	pid_t test_pid;
68 	test_pid = dt_launch_tool_pipe(cmd, false, NULL, ^bool (__unused char *data, __unused size_t data_size, __unused dt_pipe_data_handler_context_t *context) {
69 		T_LOG("%s", data);
70 		if (strstr(data, "TEST PASSED")) {
71 		        test_failed = false;
72 		}
73 		if (strstr(data, "TEST FAILED")) {
74 		        test_failed = true;
75 		}
76 		if (strstr(data, "TEST SKIPPED")) {
77 		        test_skipped = true;
78 		}
79 		return false;
80 	}, ^bool (__unused char *data, __unused size_t data_size, __unused dt_pipe_data_handler_context_t *context) {
81 		T_LOG("%s", data);
82 		return false;
83 	}, BUFFER_PATTERN_LINE, NULL);
84 
85 	if (test_pid == 0) {
86 		T_ASSERT_FAIL("dt_launch_tool_pipe() failed unexpectedly with errno %d", errno);
87 	}
88 
89 	int exitstatus;
90 	dt_waitpid(test_pid, &exitstatus, NULL, 0);
91 	if (exitstatus != 0) {
92 		T_LOG("ktrace artrace exitstatus=%d\n", exitstatus);
93 	}
94 	if (test_skipped) {
95 		unlink(tracefile_path);
96 		T_SKIP("%s", name);
97 	} else if (test_failed) {
98 		T_FAIL("%s", name);
99 	} else {
100 		unlink(tracefile_path);
101 		T_PASS("%s", name);
102 	}
103 
104 	pdwriter_t writer = pdwriter_open_tmp("xnu", name, 0, 0, NULL, 0);
105 	T_WITH_ERRNO;
106 	T_ASSERT_NOTNULL(writer, "pdwriter_open_tmp");
107 	pdwriter_new_value(writer, "scheduler_ok", PDUNIT_CUSTOM(passing), !test_failed);
108 	pdwriter_close(writer);
109 	T_END;
110 }
111 
112 T_DECL(zn_rt, "Schedule 1 RT thread per performance core, and test max latency", T_META_ENABLED(!TARGET_OS_TV), XNU_T_META_SOC_SPECIFIC)
113 {
114 	char *cmd[] = {"/usr/bin/ktrace", "artrace", "-o", "zn.artrace", "-c",
115 		       "/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
116 		       "0", "broadcast-single-sem", "realtime", "1000",
117 		       "--spin-time", "200000",
118 		       "--spin-all",
119 		       "--test-rt",
120 #if defined(__x86_64__)
121 		       "--trace", "2000000",
122 #else
123 		       "--trace", "500000",
124 #endif
125 		       NULL};
126 
127 	run_zn("zn_rt", cmd);
128 }
129 
130 T_DECL(zn_rt_smt, "Schedule 1 RT thread per primary core, verify that the secondaries are idle iff the RT threads are running", T_META_ENABLED(TARGET_CPU_X86_64))
131 {
132 	char *cmd[] = {"/usr/bin/ktrace", "artrace", "-o", "zn.artrace", "-c",
133 		       "/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
134 		       "0", "broadcast-single-sem", "realtime", "1000",
135 		       "--spin-time", "200000",
136 		       "--spin-all",
137 		       "--churn-pri", "4",
138 		       "--test-rt-smt",
139 		       "--trace", "2000000",
140 		       NULL};
141 
142 	run_zn("zn_rt_smt", cmd);
143 }
144 
145 T_DECL(zn_rt_avoid0, "Schedule 1 RT thread per primary core except for CPU 0", T_META_ASROOT(true), T_META_ENABLED(TARGET_CPU_X86_64))
146 {
147 	char *cmd[] = {"/usr/bin/ktrace", "artrace", "-o", "zn.artrace", "-c",
148 		       "/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
149 		       "0", "broadcast-single-sem", "realtime", "1000",
150 		       "--spin-time", "200000",
151 		       "--spin-all",
152 		       "--test-rt-avoid0",
153 		       "--trace", "2000000",
154 		       NULL};
155 
156 	run_zn("zn_rt_avoid0", cmd);
157 }
158 
159 T_DECL(zn_rt_apt, "Emulate AVID Pro Tools with default latency deadlines", T_META_ENABLED(!TARGET_OS_TV))
160 {
161 	char *cmd[] = {"/usr/bin/ktrace", "artrace", "-o", "zn.artrace", "-c",
162 		       "/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
163 		       "0", "chain", "realtime", "1000",
164 		       "--extra-thread-count", "-3",
165 		       "--spin-time", "200000",
166 		       "--spin-all",
167 		       "--churn-pri", "31", "--churn-random",
168 		       "--test-rt",
169 #if defined(__x86_64__)
170 		       "--trace", "2000000",
171 #else
172 		       "--trace", "500000",
173 #endif
174 		       NULL};
175 
176 	run_zn("zn_rt_apt", cmd);
177 }
178 
179 T_DECL(zn_rt_apt_ll, "Emulate AVID Pro Tools with low latency deadlines", XNU_T_META_SOC_SPECIFIC)
180 {
181 	char *cmd[] = {"/usr/bin/ktrace", "artrace", "-o", "zn.artrace", "-c",
182 		       "/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
183 		       "0", "chain", "realtime", "1000",
184 		       "--extra-thread-count", "-3",
185 		       "--spin-time", "200000",
186 		       "--spin-all",
187 		       "--churn-pri", "31", "--churn-random",
188 		       "--test-rt",
189 		       "--rt-ll",
190 		       "--trace", "500000",
191 		       NULL};
192 
193 	run_zn("zn_rt_apt_ll", cmd);
194 }
195 
196 T_DECL(zn_rt_edf, "Test max latency of earliest deadline RT threads in the presence of later deadline threads", T_META_ENABLED(!TARGET_OS_TV), XNU_T_META_SOC_SPECIFIC)
197 {
198 	char *cmd[] = {"/usr/bin/ktrace", "artrace", "-o", "zn.artrace", "-c",
199 		       "/AppleInternal/CoreOS/tests/xnu/zero-to-n/zn",
200 		       "0", "broadcast-single-sem", "realtime", "1000",
201 		       "--extra-thread-count", "-1",
202 		       "--spin-time", "200000",
203 		       "--spin-all",
204 		       "--rt-churn",
205 		       "--test-rt",
206 #if defined(__x86_64__)
207 		       "--trace", "2000000",
208 #else
209 		       "--trace", "500000",
210 #endif
211 		       NULL};
212 
213 	run_zn("zn_rt_edf", cmd);
214 }
215