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