1*f6217f89SApple OSS Distributions #include <stdio.h>
2*f6217f89SApple OSS Distributions #include <unistd.h>
3*f6217f89SApple OSS Distributions #include <stdlib.h>
4*f6217f89SApple OSS Distributions #include <errno.h>
5*f6217f89SApple OSS Distributions #include <string.h>
6*f6217f89SApple OSS Distributions #include <assert.h>
7*f6217f89SApple OSS Distributions #include <signal.h>
8*f6217f89SApple OSS Distributions #include <spawn.h>
9*f6217f89SApple OSS Distributions #include <spawn_private.h>
10*f6217f89SApple OSS Distributions #include <stdint.h>
11*f6217f89SApple OSS Distributions #include <sys/sysctl.h>
12*f6217f89SApple OSS Distributions #include <sys/spawn_internal.h>
13*f6217f89SApple OSS Distributions #include <sys/kern_memorystatus.h>
14*f6217f89SApple OSS Distributions #include <mach-o/dyld.h>
15*f6217f89SApple OSS Distributions #include <os/voucher_private.h>
16*f6217f89SApple OSS Distributions
17*f6217f89SApple OSS Distributions #include <darwintest.h>
18*f6217f89SApple OSS Distributions #include <darwintest_multiprocess.h>
19*f6217f89SApple OSS Distributions #include <darwintest_utils.h>
20*f6217f89SApple OSS Distributions
21*f6217f89SApple OSS Distributions #include "memorystatus_assertion_helpers.h"
22*f6217f89SApple OSS Distributions
23*f6217f89SApple OSS Distributions T_GLOBAL_META(
24*f6217f89SApple OSS Distributions T_META_NAMESPACE("xnu.memorystatus"),
25*f6217f89SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
26*f6217f89SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("VM"),
27*f6217f89SApple OSS Distributions T_META_CHECK_LEAKS(false),
28*f6217f89SApple OSS Distributions T_META_RUN_CONCURRENTLY(true),
29*f6217f89SApple OSS Distributions T_META_TAG_VM_PREFERRED,
30*f6217f89SApple OSS Distributions T_META_BOOTARGS_SET("memstat_no_task_limit_increase=1")
31*f6217f89SApple OSS Distributions );
32*f6217f89SApple OSS Distributions
33*f6217f89SApple OSS Distributions #define IDLE_AGEOUT_S 30
34*f6217f89SApple OSS Distributions #define AGEOUT_STUCK_S 35
35*f6217f89SApple OSS Distributions
36*f6217f89SApple OSS Distributions /*
37*f6217f89SApple OSS Distributions * This test has multiple sub-tests that set and then verify jetsam priority transitions
38*f6217f89SApple OSS Distributions * as though they were driven by assertions. It uses the MEMORYSTATUS_CMD_SET_MEMLIMIT_PROPERTIES
39*f6217f89SApple OSS Distributions * version of the memorystatus_control() system call and specifically tests the use of the
40*f6217f89SApple OSS Distributions * MEMORYSTATUS_SET_PRIORITY_ASSERTION flag.
41*f6217f89SApple OSS Distributions *
42*f6217f89SApple OSS Distributions * The kernel will apply policy that chooses a maximum jetsam priority, resolving conflicts
43*f6217f89SApple OSS Distributions * between an assertion driven priority and clean/dirty transition policy.
44*f6217f89SApple OSS Distributions *
45*f6217f89SApple OSS Distributions * Processes that do not opt into dirty-tracking should behave as they always have.
46*f6217f89SApple OSS Distributions * This is the typical App transition behavior.
47*f6217f89SApple OSS Distributions *
48*f6217f89SApple OSS Distributions * Processes that do opt into dirty-tracking have more complex policy:
49*f6217f89SApple OSS Distributions * For example:
50*f6217f89SApple OSS Distributions * A MAX assertion priority will prevent a dirty process from transitioning to a clean
51*f6217f89SApple OSS Distributions * state if the process opts into idle-exit.
52*f6217f89SApple OSS Distributions * See: memorystatus_schedule_idle_demotion_locked() where we note that
53*f6217f89SApple OSS Distributions * the process isn't going to be making the trip to the lower bands.
54*f6217f89SApple OSS Distributions *
55*f6217f89SApple OSS Distributions * But a MAX assertion evaluation will not prevent a clean process from transition to dirty.
56*f6217f89SApple OSS Distributions * Assertion driven priorities should not change memory limits, they are expected to
57*f6217f89SApple OSS Distributions * just change a process's position in the jetsam priority bands.
58*f6217f89SApple OSS Distributions *
59*f6217f89SApple OSS Distributions * MEMORYSTATUS_CMD_xxx requires root (in the absence of entitlement).
60*f6217f89SApple OSS Distributions * Use T_META_ASROOT(true) to accomplish this.
61*f6217f89SApple OSS Distributions *
62*f6217f89SApple OSS Distributions * A note on test strategy. It is not necessary to spawn a child to test these
63*f6217f89SApple OSS Distributions * assertion calls. The test can act on itself, that is, it can make calls to
64*f6217f89SApple OSS Distributions * set and relinquish assertion state just like it can make calls to do dirty/clean
65*f6217f89SApple OSS Distributions * transitions. Of course, in reality, we expect only runningboardd to manipulate
66*f6217f89SApple OSS Distributions * assertion based priorities.
67*f6217f89SApple OSS Distributions */
68*f6217f89SApple OSS Distributions
69*f6217f89SApple OSS Distributions static void
proc_will_set_clean(pid_t pid)70*f6217f89SApple OSS Distributions proc_will_set_clean(pid_t pid)
71*f6217f89SApple OSS Distributions {
72*f6217f89SApple OSS Distributions proc_set_dirty(pid, false);
73*f6217f89SApple OSS Distributions T_LOG("pid[%d] --> now clean", pid);
74*f6217f89SApple OSS Distributions return;
75*f6217f89SApple OSS Distributions }
76*f6217f89SApple OSS Distributions
77*f6217f89SApple OSS Distributions static void
proc_will_set_dirty(pid_t pid)78*f6217f89SApple OSS Distributions proc_will_set_dirty(pid_t pid)
79*f6217f89SApple OSS Distributions {
80*f6217f89SApple OSS Distributions proc_set_dirty(pid, true);
81*f6217f89SApple OSS Distributions T_LOG("pid[%d] --> now dirty", pid);
82*f6217f89SApple OSS Distributions return;
83*f6217f89SApple OSS Distributions }
84*f6217f89SApple OSS Distributions
85*f6217f89SApple OSS Distributions static void
proc_set_managed(pid_t pid,bool managed)86*f6217f89SApple OSS Distributions proc_set_managed(pid_t pid, bool managed)
87*f6217f89SApple OSS Distributions {
88*f6217f89SApple OSS Distributions int err;
89*f6217f89SApple OSS Distributions err = memorystatus_control(MEMORYSTATUS_CMD_SET_PROCESS_IS_MANAGED, pid,
90*f6217f89SApple OSS Distributions managed, NULL, 0);
91*f6217f89SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(err,
92*f6217f89SApple OSS Distributions "memorystatus_control(MEMORYSTATUS_CMD_SET_PROCESS_IS_MANAGED)");
93*f6217f89SApple OSS Distributions }
94*f6217f89SApple OSS Distributions
95*f6217f89SApple OSS Distributions /*
96*f6217f89SApple OSS Distributions * Make repetitive (eg: back-to-back) calls using MEMORYSTATUS_SET_PRIORITY_ASSERTION.
97*f6217f89SApple OSS Distributions * We know that runningboardd may try to relinquish its hold on an assertion priority
98*f6217f89SApple OSS Distributions * when it hasn't first set the assertion priority. The kernel must survive this
99*f6217f89SApple OSS Distributions * pattern even though it might be considered poor behavior on runningboardd's part.
100*f6217f89SApple OSS Distributions * When dirty tracking processes are involved, we are exercising the kernel's
101*f6217f89SApple OSS Distributions * idle-deferred paths. Only assertion state (whether or not assertion state is
102*f6217f89SApple OSS Distributions * set or relinquished) is verified in this round of tests.
103*f6217f89SApple OSS Distributions * Test is invoked three times:
104*f6217f89SApple OSS Distributions * Scenario 1) as a non-dirty-tracking process (like a typical app)
105*f6217f89SApple OSS Distributions * relinquish assertion priority multiple times
106*f6217f89SApple OSS Distributions * set same assertion priority multiple times.
107*f6217f89SApple OSS Distributions * Scenario 2) setup a dirty-tracking process that is clean (like a typical extension)
108*f6217f89SApple OSS Distributions * relinquish assertion priority multiple times
109*f6217f89SApple OSS Distributions * set same assertion priority multiple times.
110*f6217f89SApple OSS Distributions * Scenario 3) setup dirty-tracking process that is dirty (like a typical extension)
111*f6217f89SApple OSS Distributions * relinquish assertion priority multiple times
112*f6217f89SApple OSS Distributions * set same assertion priority multiple times.
113*f6217f89SApple OSS Distributions */
114*f6217f89SApple OSS Distributions
115*f6217f89SApple OSS Distributions static void
memorystatus_assertion_test_repetitive(char * test,boolean_t turn_on_dirty_tracking,boolean_t start_clean)116*f6217f89SApple OSS Distributions memorystatus_assertion_test_repetitive(char *test, boolean_t turn_on_dirty_tracking, boolean_t start_clean)
117*f6217f89SApple OSS Distributions {
118*f6217f89SApple OSS Distributions int count;
119*f6217f89SApple OSS Distributions int maxcount = 3;
120*f6217f89SApple OSS Distributions boolean_t verbose;
121*f6217f89SApple OSS Distributions uint32_t state;
122*f6217f89SApple OSS Distributions uint64_t user_data = 0;
123*f6217f89SApple OSS Distributions pid_t mypid = getpid();
124*f6217f89SApple OSS Distributions
125*f6217f89SApple OSS Distributions /* these values will remain fixed during testing */
126*f6217f89SApple OSS Distributions int active_limit_mb = 35; /* arbitrary */
127*f6217f89SApple OSS Distributions int inactive_limit_mb = 25; /* arbitrary */
128*f6217f89SApple OSS Distributions
129*f6217f89SApple OSS Distributions /* these values may vary during test */
130*f6217f89SApple OSS Distributions int requestedpriority = 0;
131*f6217f89SApple OSS Distributions int assertionpriority = 0;
132*f6217f89SApple OSS Distributions
133*f6217f89SApple OSS Distributions T_SETUPBEGIN;
134*f6217f89SApple OSS Distributions
135*f6217f89SApple OSS Distributions requestedpriority = JETSAM_PRIORITY_UI_SUPPORT;
136*f6217f89SApple OSS Distributions assertionpriority = JETSAM_PRIORITY_FOREGROUND;
137*f6217f89SApple OSS Distributions set_memlimits(mypid, active_limit_mb, inactive_limit_mb, true, true);
138*f6217f89SApple OSS Distributions set_priority(mypid, requestedpriority, 0, false);
139*f6217f89SApple OSS Distributions
140*f6217f89SApple OSS Distributions if (turn_on_dirty_tracking) {
141*f6217f89SApple OSS Distributions proc_track_dirty(mypid, (PROC_DIRTY_TRACK | PROC_DIRTY_ALLOW_IDLE_EXIT | PROC_DIRTY_DEFER));
142*f6217f89SApple OSS Distributions
143*f6217f89SApple OSS Distributions if (start_clean) {
144*f6217f89SApple OSS Distributions proc_will_set_clean(mypid);
145*f6217f89SApple OSS Distributions } else {
146*f6217f89SApple OSS Distributions proc_will_set_dirty(mypid);
147*f6217f89SApple OSS Distributions }
148*f6217f89SApple OSS Distributions } else {
149*f6217f89SApple OSS Distributions /*
150*f6217f89SApple OSS Distributions * Do nothing.
151*f6217f89SApple OSS Distributions * Acts like an app with no dirty tracking
152*f6217f89SApple OSS Distributions * By default launches in the requested priority and is
153*f6217f89SApple OSS Distributions * considered idle because it's below FG band.
154*f6217f89SApple OSS Distributions */
155*f6217f89SApple OSS Distributions }
156*f6217f89SApple OSS Distributions
157*f6217f89SApple OSS Distributions proc_set_managed(mypid, true);
158*f6217f89SApple OSS Distributions
159*f6217f89SApple OSS Distributions verbose = false;
160*f6217f89SApple OSS Distributions (void)get_priority_props(mypid, verbose, NULL, NULL, NULL, NULL);
161*f6217f89SApple OSS Distributions
162*f6217f89SApple OSS Distributions /* log current setup state */
163*f6217f89SApple OSS Distributions T_LOG("SETUP STATE COMPLETE: Test %s", test);
164*f6217f89SApple OSS Distributions
165*f6217f89SApple OSS Distributions T_SETUPEND;
166*f6217f89SApple OSS Distributions
167*f6217f89SApple OSS Distributions int i;
168*f6217f89SApple OSS Distributions boolean_t ret;
169*f6217f89SApple OSS Distributions for (i = 0; i < 2; i++) {
170*f6217f89SApple OSS Distributions if (i == 1 && turn_on_dirty_tracking) {
171*f6217f89SApple OSS Distributions T_LOG("Avoid idle-deferred - sleeping for %d s", IDLE_AGEOUT_S);
172*f6217f89SApple OSS Distributions sleep(IDLE_AGEOUT_S);
173*f6217f89SApple OSS Distributions
174*f6217f89SApple OSS Distributions if (start_clean) {
175*f6217f89SApple OSS Distributions proc_will_set_dirty(mypid);
176*f6217f89SApple OSS Distributions } else {
177*f6217f89SApple OSS Distributions proc_will_set_clean(mypid);
178*f6217f89SApple OSS Distributions }
179*f6217f89SApple OSS Distributions
180*f6217f89SApple OSS Distributions (void)get_priority_props(mypid, verbose, NULL, NULL, NULL, &state);
181*f6217f89SApple OSS Distributions }
182*f6217f89SApple OSS Distributions
183*f6217f89SApple OSS Distributions /*
184*f6217f89SApple OSS Distributions * Relinquish assertion priority even though we don't
185*f6217f89SApple OSS Distributions * currently hold an assertion priority.
186*f6217f89SApple OSS Distributions */
187*f6217f89SApple OSS Distributions for (count = 0; count < maxcount; count++) {
188*f6217f89SApple OSS Distributions if (relinquish_assertion_priority(mypid, user_data)) {
189*f6217f89SApple OSS Distributions T_ASSERT_FAIL("relinquish_assertion_priority failed");
190*f6217f89SApple OSS Distributions }
191*f6217f89SApple OSS Distributions }
192*f6217f89SApple OSS Distributions
193*f6217f89SApple OSS Distributions /* Verify assertion state is relinquished */
194*f6217f89SApple OSS Distributions (void)get_priority_props(mypid, verbose, NULL, NULL, NULL, &state);
195*f6217f89SApple OSS Distributions
196*f6217f89SApple OSS Distributions ret = verify_assertion_state(state, ASSERTION_STATE_IS_RELINQUISHED);
197*f6217f89SApple OSS Distributions T_QUIET;
198*f6217f89SApple OSS Distributions T_ASSERT_TRUE(ret, "verify_assertion_state failed");
199*f6217f89SApple OSS Distributions
200*f6217f89SApple OSS Distributions
201*f6217f89SApple OSS Distributions
202*f6217f89SApple OSS Distributions /*
203*f6217f89SApple OSS Distributions * Set an assertion priority multiple times in a row.
204*f6217f89SApple OSS Distributions */
205*f6217f89SApple OSS Distributions for (count = 0; count < maxcount; count++) {
206*f6217f89SApple OSS Distributions if (set_assertion_priority(mypid, assertionpriority, user_data) != 0) {
207*f6217f89SApple OSS Distributions T_ASSERT_FAIL("set_assertion_priority failed");
208*f6217f89SApple OSS Distributions }
209*f6217f89SApple OSS Distributions }
210*f6217f89SApple OSS Distributions
211*f6217f89SApple OSS Distributions /* Verify state holds an assertion priority */
212*f6217f89SApple OSS Distributions (void)get_priority_props(mypid, verbose, NULL, NULL, NULL, &state);
213*f6217f89SApple OSS Distributions
214*f6217f89SApple OSS Distributions ret = verify_assertion_state(state, ASSERTION_STATE_IS_SET);
215*f6217f89SApple OSS Distributions T_QUIET;
216*f6217f89SApple OSS Distributions T_ASSERT_TRUE(ret, "verify_assertion_state failed");
217*f6217f89SApple OSS Distributions }
218*f6217f89SApple OSS Distributions }
219*f6217f89SApple OSS Distributions
220*f6217f89SApple OSS Distributions /*
221*f6217f89SApple OSS Distributions * Process is dirty tracking and opts into pressured exit.
222*f6217f89SApple OSS Distributions */
223*f6217f89SApple OSS Distributions static void
memorystatus_assertion_test_allow_idle_exit(void)224*f6217f89SApple OSS Distributions memorystatus_assertion_test_allow_idle_exit(void)
225*f6217f89SApple OSS Distributions {
226*f6217f89SApple OSS Distributions pid_t mypid = getpid();
227*f6217f89SApple OSS Distributions
228*f6217f89SApple OSS Distributions /* these values will remain fixed during testing */
229*f6217f89SApple OSS Distributions int active_limit_mb = 35; /* arbitrary */
230*f6217f89SApple OSS Distributions int inactive_limit_mb = 25; /* arbitrary */
231*f6217f89SApple OSS Distributions
232*f6217f89SApple OSS Distributions /* these values may vary during test */
233*f6217f89SApple OSS Distributions int requestedpriority = JETSAM_PRIORITY_UI_SUPPORT;
234*f6217f89SApple OSS Distributions
235*f6217f89SApple OSS Distributions T_SETUPBEGIN;
236*f6217f89SApple OSS Distributions
237*f6217f89SApple OSS Distributions set_memlimits(mypid, active_limit_mb, inactive_limit_mb, true, true);
238*f6217f89SApple OSS Distributions set_priority(mypid, requestedpriority, 0, false);
239*f6217f89SApple OSS Distributions
240*f6217f89SApple OSS Distributions proc_track_dirty(mypid, (PROC_DIRTY_TRACK | PROC_DIRTY_ALLOW_IDLE_EXIT | PROC_DIRTY_DEFER));
241*f6217f89SApple OSS Distributions proc_set_managed(mypid, true);
242*f6217f89SApple OSS Distributions
243*f6217f89SApple OSS Distributions proc_will_set_clean(mypid);
244*f6217f89SApple OSS Distributions
245*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_IDLE_DEFERRED, active_limit_mb, 0x0, ASSERTION_STATE_IS_RELINQUISHED, "Clean start");
246*f6217f89SApple OSS Distributions
247*f6217f89SApple OSS Distributions T_LOG("SETUP STATE COMPLETE");
248*f6217f89SApple OSS Distributions
249*f6217f89SApple OSS Distributions int g_jetsam_aging_policy = 0;
250*f6217f89SApple OSS Distributions /*
251*f6217f89SApple OSS Distributions * Jetsam aging policy
252*f6217f89SApple OSS Distributions * Failure to retrieve is not fatal.
253*f6217f89SApple OSS Distributions */
254*f6217f89SApple OSS Distributions size_t size = sizeof(g_jetsam_aging_policy);
255*f6217f89SApple OSS Distributions if (sysctlbyname("kern.jetsam_aging_policy", &g_jetsam_aging_policy, &size, NULL, 0) != 0) {
256*f6217f89SApple OSS Distributions T_LOG(__func__, true, "Unable to retrieve jetsam aging policy (not fatal)");
257*f6217f89SApple OSS Distributions }
258*f6217f89SApple OSS Distributions
259*f6217f89SApple OSS Distributions T_SETUPEND;
260*f6217f89SApple OSS Distributions
261*f6217f89SApple OSS Distributions /*
262*f6217f89SApple OSS Distributions * Relinquish assertion priority even though we don't hold it. No change in state expected.
263*f6217f89SApple OSS Distributions */
264*f6217f89SApple OSS Distributions T_LOG("********Test0 clean: no state change on relinquish");
265*f6217f89SApple OSS Distributions relinquish_assertion_priority(mypid, 0xF00D);
266*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_IDLE_DEFERRED, active_limit_mb, 0xF00D, ASSERTION_STATE_IS_RELINQUISHED, "Test0");
267*f6217f89SApple OSS Distributions
268*f6217f89SApple OSS Distributions T_LOG("********Test1 clean: deferred now assertion[10]");
269*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_FOREGROUND, 0xFEED);
270*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_FOREGROUND, active_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test1");
271*f6217f89SApple OSS Distributions
272*f6217f89SApple OSS Distributions /* Test2 */
273*f6217f89SApple OSS Distributions T_LOG("********Test2 clean: assertion[10 -> 3]");
274*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_BACKGROUND, 0xFACE);
275*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_BACKGROUND, active_limit_mb, 0xFACE, ASSERTION_STATE_IS_SET, "Test2");
276*f6217f89SApple OSS Distributions
277*f6217f89SApple OSS Distributions /* Test3 */
278*f6217f89SApple OSS Distributions T_LOG("********Test3 clean: assertion[3 -> 0], but now deferred");
279*f6217f89SApple OSS Distributions relinquish_assertion_priority(mypid, 0xBEEF);
280*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_IDLE_DEFERRED, active_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test3");
281*f6217f89SApple OSS Distributions
282*f6217f89SApple OSS Distributions T_LOG("Avoid idle-deferred moving forward. Sleeping for %d s", IDLE_AGEOUT_S);
283*f6217f89SApple OSS Distributions sleep(IDLE_AGEOUT_S);
284*f6217f89SApple OSS Distributions
285*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_IDLE, inactive_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test3");
286*f6217f89SApple OSS Distributions
287*f6217f89SApple OSS Distributions /* Test4 */
288*f6217f89SApple OSS Distributions T_LOG("********Test4 clean: deferred now assertion[10]");
289*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_FOREGROUND, 0xFEED);
290*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_FOREGROUND, active_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test4");
291*f6217f89SApple OSS Distributions
292*f6217f89SApple OSS Distributions
293*f6217f89SApple OSS Distributions /* Test5 */
294*f6217f89SApple OSS Distributions T_LOG("********Test5 dirty: set dirty priority but assertion[10] prevails");
295*f6217f89SApple OSS Distributions proc_will_set_dirty(mypid); /* active priority is less than FG*/
296*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_FOREGROUND, active_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test5");
297*f6217f89SApple OSS Distributions
298*f6217f89SApple OSS Distributions /* Test6 */
299*f6217f89SApple OSS Distributions T_LOG("********Test6 dirty: assertion[10 -> 3] but dirty priority prevails");
300*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_BACKGROUND, 0xFEEB); /* active priority is > BG */
301*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_UI_SUPPORT, active_limit_mb, 0xFEEB, ASSERTION_STATE_IS_SET, "Test6");
302*f6217f89SApple OSS Distributions
303*f6217f89SApple OSS Distributions /* Test7 */
304*f6217f89SApple OSS Distributions T_LOG("********Test7 dirty: assertion[3 -> 0] but dirty prevails");
305*f6217f89SApple OSS Distributions relinquish_assertion_priority(mypid, 0xBEEF);
306*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_UI_SUPPORT, active_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test7");
307*f6217f89SApple OSS Distributions
308*f6217f89SApple OSS Distributions
309*f6217f89SApple OSS Distributions /* Test8 */
310*f6217f89SApple OSS Distributions T_LOG("********Test8 dirty: assertion[0 -> 10] overrides dirty");
311*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_FOREGROUND, 0xFEED);
312*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_FOREGROUND, active_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test8");
313*f6217f89SApple OSS Distributions
314*f6217f89SApple OSS Distributions /* Test9 */
315*f6217f89SApple OSS Distributions T_LOG("********Test9 dirty wants to go clean, but clean state is prevented as assertion[10] prevails");
316*f6217f89SApple OSS Distributions proc_will_set_clean(mypid);
317*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_FOREGROUND, active_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test9");
318*f6217f89SApple OSS Distributions
319*f6217f89SApple OSS Distributions /* Test10 */
320*f6217f89SApple OSS Distributions T_LOG("********Test10 dirty goes dirty and stays dirty, and assertion[10] prevails again");
321*f6217f89SApple OSS Distributions proc_will_set_dirty(mypid);
322*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_FOREGROUND, active_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test10");
323*f6217f89SApple OSS Distributions
324*f6217f89SApple OSS Distributions /* Test11 */
325*f6217f89SApple OSS Distributions T_LOG("********Test11 dirty: assertion[10 -> 3] but dirty prevails");
326*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_BACKGROUND, 0xFACE);
327*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_UI_SUPPORT, active_limit_mb, 0xFACE, ASSERTION_STATE_IS_SET, "Test11");
328*f6217f89SApple OSS Distributions
329*f6217f89SApple OSS Distributions /* Test12 */
330*f6217f89SApple OSS Distributions T_LOG("********Test12 dirty: assertion[3 -> 0] but dirty prevails");
331*f6217f89SApple OSS Distributions relinquish_assertion_priority(mypid, 0xBEEF);
332*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_UI_SUPPORT, active_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test12");
333*f6217f89SApple OSS Distributions
334*f6217f89SApple OSS Distributions
335*f6217f89SApple OSS Distributions /* Test13 */
336*f6217f89SApple OSS Distributions T_LOG("********Test13 dirty goes clean: both assertion[0] and clean");
337*f6217f89SApple OSS Distributions proc_will_set_clean(mypid);
338*f6217f89SApple OSS Distributions /* For sysproc aging policy the daemon should be at idle deferred and with an active memory limit */
339*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_IDLE_DEFERRED, active_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test13");
340*f6217f89SApple OSS Distributions }
341*f6217f89SApple OSS Distributions
342*f6217f89SApple OSS Distributions /*
343*f6217f89SApple OSS Distributions * Process is dirty tracking and does not opt into pressured exit.
344*f6217f89SApple OSS Distributions * This test lives above Foreground. Assertions will have no affect
345*f6217f89SApple OSS Distributions * except where the assertion priority bumps it above the requested priority.
346*f6217f89SApple OSS Distributions */
347*f6217f89SApple OSS Distributions static void
memorystatus_assertion_test_do_not_allow_idle_exit(void)348*f6217f89SApple OSS Distributions memorystatus_assertion_test_do_not_allow_idle_exit(void)
349*f6217f89SApple OSS Distributions {
350*f6217f89SApple OSS Distributions pid_t mypid = getpid();
351*f6217f89SApple OSS Distributions
352*f6217f89SApple OSS Distributions /* these values will remain fixed during testing */
353*f6217f89SApple OSS Distributions int active_limit_mb = 35; /* arbitrary */
354*f6217f89SApple OSS Distributions int inactive_limit_mb = 25; /* arbitrary */
355*f6217f89SApple OSS Distributions int requestedpriority = JETSAM_PRIORITY_AUDIO_AND_ACCESSORY;
356*f6217f89SApple OSS Distributions
357*f6217f89SApple OSS Distributions T_SETUPBEGIN;
358*f6217f89SApple OSS Distributions
359*f6217f89SApple OSS Distributions set_memlimits(mypid, active_limit_mb, inactive_limit_mb, true, true);
360*f6217f89SApple OSS Distributions set_priority(mypid, requestedpriority, 0, false);
361*f6217f89SApple OSS Distributions proc_track_dirty(mypid, (PROC_DIRTY_TRACK));
362*f6217f89SApple OSS Distributions proc_set_managed(mypid, true);
363*f6217f89SApple OSS Distributions
364*f6217f89SApple OSS Distributions proc_will_set_dirty(mypid);
365*f6217f89SApple OSS Distributions
366*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, active_limit_mb, 0x0, ASSERTION_STATE_IS_RELINQUISHED, "Dirty start");
367*f6217f89SApple OSS Distributions
368*f6217f89SApple OSS Distributions proc_will_set_clean(mypid);
369*f6217f89SApple OSS Distributions
370*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, inactive_limit_mb, 0x0, ASSERTION_STATE_IS_RELINQUISHED, "Clean transition");
371*f6217f89SApple OSS Distributions
372*f6217f89SApple OSS Distributions T_LOG("SETUP STATE COMPLETE");
373*f6217f89SApple OSS Distributions
374*f6217f89SApple OSS Distributions T_SETUPEND;
375*f6217f89SApple OSS Distributions
376*f6217f89SApple OSS Distributions /*
377*f6217f89SApple OSS Distributions * Relinquish assertion priority even though we don't hold it. No change in state expected.
378*f6217f89SApple OSS Distributions */
379*f6217f89SApple OSS Distributions
380*f6217f89SApple OSS Distributions
381*f6217f89SApple OSS Distributions /* Test0 */
382*f6217f89SApple OSS Distributions T_LOG("********Test0 clean: no state change on relinquish");
383*f6217f89SApple OSS Distributions relinquish_assertion_priority(mypid, 0xF00D);
384*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, inactive_limit_mb, 0xF00D, ASSERTION_STATE_IS_RELINQUISHED, "Test0");
385*f6217f89SApple OSS Distributions
386*f6217f89SApple OSS Distributions /* Test1 */
387*f6217f89SApple OSS Distributions T_LOG("********Test1 clean: assertion[0 -> 10] but inactive priority prevails");
388*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_FOREGROUND, 0xFEED);
389*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, inactive_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test1");
390*f6217f89SApple OSS Distributions
391*f6217f89SApple OSS Distributions /* Test2 */
392*f6217f89SApple OSS Distributions T_LOG("********Test2 clean: assertion[10 -> 3] but inactive priority prevails");
393*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_BACKGROUND, 0xFACE);
394*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, inactive_limit_mb, 0xFACE, ASSERTION_STATE_IS_SET, "Test2");
395*f6217f89SApple OSS Distributions
396*f6217f89SApple OSS Distributions /* Test3 */
397*f6217f89SApple OSS Distributions T_LOG("********Test3 clean: assertion[3 -> 0], but inactive priority prevails");
398*f6217f89SApple OSS Distributions relinquish_assertion_priority(mypid, 0xBEEF);
399*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, inactive_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test3");
400*f6217f89SApple OSS Distributions
401*f6217f89SApple OSS Distributions /* Test4 */
402*f6217f89SApple OSS Distributions T_LOG("********Test4 go dirty: assertion[0] has no affect, active priority prevails");
403*f6217f89SApple OSS Distributions proc_will_set_dirty(mypid);
404*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, active_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test4");
405*f6217f89SApple OSS Distributions
406*f6217f89SApple OSS Distributions /* Test5 */
407*f6217f89SApple OSS Distributions T_LOG("********Test5 dirty: assertion[0 -> 10] active priority prevails");
408*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_FOREGROUND, 0xFEED);
409*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, active_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test5");
410*f6217f89SApple OSS Distributions
411*f6217f89SApple OSS Distributions /* Test6 */
412*f6217f89SApple OSS Distributions T_LOG("********Test6 dirty: assertion[10 -> 3] active priority prevails");
413*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_BACKGROUND, 0xFACE);
414*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, active_limit_mb, 0xFACE, ASSERTION_STATE_IS_SET, "Test6");
415*f6217f89SApple OSS Distributions
416*f6217f89SApple OSS Distributions /* Test 7 */
417*f6217f89SApple OSS Distributions T_LOG("********Test7 dirty: assertion[3 -> 0], active priority prevails");
418*f6217f89SApple OSS Distributions relinquish_assertion_priority(mypid, 0xBEEF);
419*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, active_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test7");
420*f6217f89SApple OSS Distributions
421*f6217f89SApple OSS Distributions /* Test8 */
422*f6217f89SApple OSS Distributions T_LOG("********Test8 dirty: assertion[0 -> 19], dirty but now assertion[19] prevails");
423*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_CRITICAL, 0xFEED);
424*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_CRITICAL, active_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test8");
425*f6217f89SApple OSS Distributions
426*f6217f89SApple OSS Distributions
427*f6217f89SApple OSS Distributions /* Test9 */
428*f6217f89SApple OSS Distributions T_LOG("********Test9 go clean: inactive priority but assertion[19] prevails");
429*f6217f89SApple OSS Distributions proc_will_set_clean(mypid);
430*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_CRITICAL, inactive_limit_mb, 0xFEED, ASSERTION_STATE_IS_SET, "Test9");
431*f6217f89SApple OSS Distributions
432*f6217f89SApple OSS Distributions /* Test10 */
433*f6217f89SApple OSS Distributions T_LOG("********Test10 clean: assertion[19 -> 3] inactive limit prevails");
434*f6217f89SApple OSS Distributions set_assertion_priority(mypid, JETSAM_PRIORITY_BACKGROUND, 0xFACE);
435*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, inactive_limit_mb, 0xFACE, ASSERTION_STATE_IS_SET, "Test10");
436*f6217f89SApple OSS Distributions
437*f6217f89SApple OSS Distributions
438*f6217f89SApple OSS Distributions /* Test11 */
439*f6217f89SApple OSS Distributions T_LOG("********Test11 clean: assertion[3 -> 0] inactive priority still prevails");
440*f6217f89SApple OSS Distributions relinquish_assertion_priority(mypid, 0xBEEF);
441*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, inactive_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test11");
442*f6217f89SApple OSS Distributions
443*f6217f89SApple OSS Distributions /* Test12 */
444*f6217f89SApple OSS Distributions T_LOG("********Test12 dirty goes clean: both assertion[0] and clean");
445*f6217f89SApple OSS Distributions proc_will_set_clean(mypid);
446*f6217f89SApple OSS Distributions (void)check_properties(mypid, JETSAM_PRIORITY_AUDIO_AND_ACCESSORY, inactive_limit_mb, 0xBEEF, ASSERTION_STATE_IS_RELINQUISHED, "Test12");
447*f6217f89SApple OSS Distributions }
448*f6217f89SApple OSS Distributions
449*f6217f89SApple OSS Distributions T_DECL(assertion_test_bad_flags, "verify bad flag returns an error", T_META_TIMEOUT(30), T_META_ASROOT(true)) {
450*f6217f89SApple OSS Distributions int err;
451*f6217f89SApple OSS Distributions uint32_t flag = 0;
452*f6217f89SApple OSS Distributions
453*f6217f89SApple OSS Distributions memorystatus_priority_properties_t mjp = { 0 };
454*f6217f89SApple OSS Distributions
455*f6217f89SApple OSS Distributions mjp.priority = JETSAM_PRIORITY_FOREGROUND;
456*f6217f89SApple OSS Distributions mjp.user_data = 0;
457*f6217f89SApple OSS Distributions
458*f6217f89SApple OSS Distributions /*
459*f6217f89SApple OSS Distributions * init a bad flag
460*f6217f89SApple OSS Distributions */
461*f6217f89SApple OSS Distributions
462*f6217f89SApple OSS Distributions flag = 0xf;
463*f6217f89SApple OSS Distributions
464*f6217f89SApple OSS Distributions err = memorystatus_control(MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES, getpid(), flag, &mjp, sizeof(mjp));
465*f6217f89SApple OSS Distributions
466*f6217f89SApple OSS Distributions T_QUIET;
467*f6217f89SApple OSS Distributions T_ASSERT_POSIX_FAILURE(err, EINVAL, "MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES should fail with bad flags (err=%d)", err);
468*f6217f89SApple OSS Distributions }
469*f6217f89SApple OSS Distributions
470*f6217f89SApple OSS Distributions T_DECL(set_assertion_pri_unmanaged,
471*f6217f89SApple OSS Distributions "verify that an unmanaged process cannot have assertion-driven priority set")
472*f6217f89SApple OSS Distributions {
473*f6217f89SApple OSS Distributions int err;
474*f6217f89SApple OSS Distributions memorystatus_priority_properties_t mjp = {
475*f6217f89SApple OSS Distributions .priority = JETSAM_PRIORITY_FOREGROUND,
476*f6217f89SApple OSS Distributions .user_data = 0x0
477*f6217f89SApple OSS Distributions };
478*f6217f89SApple OSS Distributions err = memorystatus_control(MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES,
479*f6217f89SApple OSS Distributions getpid(), MEMORYSTATUS_SET_PRIORITY_ASSERTION, &mjp, sizeof(mjp));
480*f6217f89SApple OSS Distributions
481*f6217f89SApple OSS Distributions T_EXPECT_POSIX_FAILURE(err, EPERM,
482*f6217f89SApple OSS Distributions "Should not be able to set assertion-driven priority of unmanaged process.");
483*f6217f89SApple OSS Distributions }
484*f6217f89SApple OSS Distributions
485*f6217f89SApple OSS Distributions
486*f6217f89SApple OSS Distributions #if TARGET_OS_OSX
487*f6217f89SApple OSS Distributions /*
488*f6217f89SApple OSS Distributions * Idle band deferral, aka aging band/demotion, has been disabled on macOS till
489*f6217f89SApple OSS Distributions * we do the daemon hygiene work on macOS to make sure that processes don't change
490*f6217f89SApple OSS Distributions * their role after spawn e.g. apps opting into dirty-tracking/idle-exit.
491*f6217f89SApple OSS Distributions * The following set of tests rely on PROC_DIRTY_DEFER, aka aging bands, for the tests.
492*f6217f89SApple OSS Distributions */
493*f6217f89SApple OSS Distributions #else /* TARGET_OS_OSX */
494*f6217f89SApple OSS Distributions
495*f6217f89SApple OSS Distributions T_HELPER_DECL(idle_age_as_app_then_sysproc,
496*f6217f89SApple OSS Distributions "Launch as managed, begin idle aging, then enroll in ActivityTracking")
497*f6217f89SApple OSS Distributions {
498*f6217f89SApple OSS Distributions pid_t my_pid = getpid();
499*f6217f89SApple OSS Distributions int32_t priority;
500*f6217f89SApple OSS Distributions
501*f6217f89SApple OSS Distributions // Set self as managed and begin idle aging
502*f6217f89SApple OSS Distributions proc_set_managed(my_pid, true);
503*f6217f89SApple OSS Distributions set_priority(my_pid, JETSAM_PRIORITY_IDLE, 0, false);
504*f6217f89SApple OSS Distributions // process must have a fatal memlimit to enroll in dirtytracking while
505*f6217f89SApple OSS Distributions // managed
506*f6217f89SApple OSS Distributions set_memlimits(my_pid, 100, 100, true, true);
507*f6217f89SApple OSS Distributions
508*f6217f89SApple OSS Distributions get_priority_props(my_pid, FALSE, &priority, NULL, NULL, NULL);
509*f6217f89SApple OSS Distributions T_EXPECT_EQ(priority, JETSAM_PRIORITY_AGING_BAND2, "Process is placed in App aging band");
510*f6217f89SApple OSS Distributions
511*f6217f89SApple OSS Distributions // Enroll in dirty tracking
512*f6217f89SApple OSS Distributions proc_track_dirty(my_pid,
513*f6217f89SApple OSS Distributions (PROC_DIRTY_TRACK | PROC_DIRTY_ALLOW_IDLE_EXIT | PROC_DIRTY_DEFER));
514*f6217f89SApple OSS Distributions
515*f6217f89SApple OSS Distributions get_priority_props(my_pid, FALSE, &priority, NULL, NULL, NULL);
516*f6217f89SApple OSS Distributions T_EXPECT_EQ(priority, JETSAM_PRIORITY_AGING_BAND1, "Process is placed in SysProc aging band");
517*f6217f89SApple OSS Distributions
518*f6217f89SApple OSS Distributions T_LOG("Sleeping for %d sec...", IDLE_AGEOUT_S);
519*f6217f89SApple OSS Distributions sleep(IDLE_AGEOUT_S);
520*f6217f89SApple OSS Distributions
521*f6217f89SApple OSS Distributions get_priority_props(my_pid, FALSE, &priority, NULL, NULL, NULL);
522*f6217f89SApple OSS Distributions T_EXPECT_EQ(priority, JETSAM_PRIORITY_IDLE, "Process ages to IDLE");
523*f6217f89SApple OSS Distributions }
524*f6217f89SApple OSS Distributions
525*f6217f89SApple OSS Distributions T_DECL(idle_aging_app_to_sysproc,
526*f6217f89SApple OSS Distributions "Processes that transition from App -> SysProc while aging are deferred properly")
527*f6217f89SApple OSS Distributions {
528*f6217f89SApple OSS Distributions dt_helper_t helper = dt_child_helper("idle_age_as_app_then_sysproc");
529*f6217f89SApple OSS Distributions
530*f6217f89SApple OSS Distributions dt_run_helpers(&helper, 1, 90);
531*f6217f89SApple OSS Distributions }
532*f6217f89SApple OSS Distributions
533*f6217f89SApple OSS Distributions T_HELPER_DECL(idle_age_timeout_importance_boost,
534*f6217f89SApple OSS Distributions "Enroll in ActivityTracking, idle age with held assertion")
535*f6217f89SApple OSS Distributions {
536*f6217f89SApple OSS Distributions pid_t my_pid = getpid();
537*f6217f89SApple OSS Distributions int32_t priority, ret;
538*f6217f89SApple OSS Distributions
539*f6217f89SApple OSS Distributions // Set managed, enroll in dirty tracking, and pretend we have an importance assertion voucher
540*f6217f89SApple OSS Distributions proc_set_managed(my_pid, true);
541*f6217f89SApple OSS Distributions set_memlimits(my_pid, 100, 100, true, true);
542*f6217f89SApple OSS Distributions proc_track_dirty(my_pid,
543*f6217f89SApple OSS Distributions (PROC_DIRTY_TRACK | PROC_DIRTY_ALLOW_IDLE_EXIT | PROC_DIRTY_DEFER));
544*f6217f89SApple OSS Distributions ret = memorystatus_control(MEMORYSTATUS_CMD_SET_TESTING_PID, getpid(), MEMORYSTATUS_FLAGS_SET_IMP_TESTING_PID, NULL, 0);
545*f6217f89SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "MEMORYSTATUS_CMD_SET_TESTING_PID");
546*f6217f89SApple OSS Distributions
547*f6217f89SApple OSS Distributions get_priority_props(my_pid, FALSE, &priority, NULL, NULL, NULL);
548*f6217f89SApple OSS Distributions T_EXPECT_EQ(priority, JETSAM_PRIORITY_AGING_BAND1, "Process is placed in SysProc aging band");
549*f6217f89SApple OSS Distributions
550*f6217f89SApple OSS Distributions T_LOG("Sleeping for %d sec...", IDLE_AGEOUT_S);
551*f6217f89SApple OSS Distributions sleep(IDLE_AGEOUT_S);
552*f6217f89SApple OSS Distributions
553*f6217f89SApple OSS Distributions get_priority_props(my_pid, FALSE, &priority, NULL, NULL, NULL);
554*f6217f89SApple OSS Distributions T_EXPECT_EQ(priority, JETSAM_PRIORITY_AGING_BAND1_STUCK, "Process ages to JETSAM_PRIORITY_AGING_BAND1_STUCK");
555*f6217f89SApple OSS Distributions
556*f6217f89SApple OSS Distributions T_LOG("Sleeping for %d sec...", AGEOUT_STUCK_S);
557*f6217f89SApple OSS Distributions sleep(AGEOUT_STUCK_S);
558*f6217f89SApple OSS Distributions
559*f6217f89SApple OSS Distributions get_priority_props(my_pid, FALSE, &priority, NULL, NULL, NULL);
560*f6217f89SApple OSS Distributions T_EXPECT_EQ(priority, JETSAM_PRIORITY_IDLE, "Process ages to JETSAM_PRIORITY_IDLE");
561*f6217f89SApple OSS Distributions }
562*f6217f89SApple OSS Distributions
563*f6217f89SApple OSS Distributions T_DECL(idle_aging_leaked_importance_boost,
564*f6217f89SApple OSS Distributions "Idle aging with leaked importance boost")
565*f6217f89SApple OSS Distributions {
566*f6217f89SApple OSS Distributions dt_helper_t helper = dt_child_helper("idle_age_timeout_importance_boost");
567*f6217f89SApple OSS Distributions
568*f6217f89SApple OSS Distributions dt_run_helpers(&helper, 1, 80);
569*f6217f89SApple OSS Distributions }
570*f6217f89SApple OSS Distributions T_DECL(assertion_test_repetitive_non_dirty_tracking, "Scenario #1 - repetitive assertion priority on non-dirty-tracking process", T_META_TIMEOUT(60), T_META_ASROOT(true)) {
571*f6217f89SApple OSS Distributions /*
572*f6217f89SApple OSS Distributions * Verify back-to-back assertion calls set assertion state as expected.
573*f6217f89SApple OSS Distributions * false --> non-dirty-tracking process (like a typical app)
574*f6217f89SApple OSS Distributions * false --> clean/dirty does not apply here
575*f6217f89SApple OSS Distributions */
576*f6217f89SApple OSS Distributions
577*f6217f89SApple OSS Distributions memorystatus_assertion_test_repetitive("Scenario #1", false, false);
578*f6217f89SApple OSS Distributions }
579*f6217f89SApple OSS Distributions
580*f6217f89SApple OSS Distributions T_DECL(assertion_test_repetitive_dirty_tracking_clean, "Scenario #2 - repetitive assertion priority on clean dirty-tracking process", T_META_TIMEOUT(60), T_META_ASROOT(true)) {
581*f6217f89SApple OSS Distributions /*
582*f6217f89SApple OSS Distributions * Verify back-to-back assertion calls set assertion state as expected.
583*f6217f89SApple OSS Distributions * true --> dirty-tracking process (like a typical extension/widget)
584*f6217f89SApple OSS Distributions * true --> start clean / inactive
585*f6217f89SApple OSS Distributions * This will exercise idle-deferred paths.
586*f6217f89SApple OSS Distributions */
587*f6217f89SApple OSS Distributions memorystatus_assertion_test_repetitive("Scenario #2", true, true);
588*f6217f89SApple OSS Distributions }
589*f6217f89SApple OSS Distributions
590*f6217f89SApple OSS Distributions T_DECL(assertion_test_repetitive_dirty_tracking_dirty, "Scenario #3 - repetitive assertion priority on dirty dirty-tracking processes", T_META_TIMEOUT(60), T_META_ASROOT(true)) {
591*f6217f89SApple OSS Distributions /*
592*f6217f89SApple OSS Distributions * Verify back-to-back assertion calls set assertion state as expected.
593*f6217f89SApple OSS Distributions * true --> dirty-tracking process (like a typical extension/widget)
594*f6217f89SApple OSS Distributions * false --> start dirty / active state
595*f6217f89SApple OSS Distributions * This will exercise idle-deferred paths.
596*f6217f89SApple OSS Distributions */
597*f6217f89SApple OSS Distributions memorystatus_assertion_test_repetitive("Scenario #3", true, false);
598*f6217f89SApple OSS Distributions }
599*f6217f89SApple OSS Distributions
600*f6217f89SApple OSS Distributions
601*f6217f89SApple OSS Distributions T_DECL(assertion_test_allow_idle_exit, "set assertion priorities on process supporting idle exit", T_META_TIMEOUT(360), T_META_ASROOT(true)) {
602*f6217f89SApple OSS Distributions memorystatus_assertion_test_allow_idle_exit();
603*f6217f89SApple OSS Distributions }
604*f6217f89SApple OSS Distributions
605*f6217f89SApple OSS Distributions T_DECL(assertion_test_do_not_allow_idle_exit, "set assertion priorities on process no idle exit allowed", T_META_TIMEOUT(360), T_META_ASROOT(true)) {
606*f6217f89SApple OSS Distributions memorystatus_assertion_test_do_not_allow_idle_exit();
607*f6217f89SApple OSS Distributions }
608*f6217f89SApple OSS Distributions #endif /* TARGET_OS_OSX */
609*f6217f89SApple OSS Distributions
610*f6217f89SApple OSS Distributions T_DECL(daemon_memlimits,
611*f6217f89SApple OSS Distributions "test that daemons have their memlimits set correctly according to dirtiness",
612*f6217f89SApple OSS Distributions T_META_ENABLED(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR))
613*f6217f89SApple OSS Distributions {
614*f6217f89SApple OSS Distributions int ret;
615*f6217f89SApple OSS Distributions const uint32_t memlimit_active = 6; /* 6 MB */
616*f6217f89SApple OSS Distributions const uint32_t memlimit_inactive = 4; /* 4 MB */
617*f6217f89SApple OSS Distributions pid_t pid = getpid();
618*f6217f89SApple OSS Distributions
619*f6217f89SApple OSS Distributions set_priority(pid, JETSAM_PRIORITY_UI_SUPPORT, 0, false);
620*f6217f89SApple OSS Distributions set_memlimits(pid, memlimit_active, memlimit_inactive, true, true);
621*f6217f89SApple OSS Distributions
622*f6217f89SApple OSS Distributions ret = proc_track_dirty(pid, PROC_DIRTY_TRACK | PROC_DIRTY_ALLOW_IDLE_EXIT | PROC_DIRTY_DEFER);
623*f6217f89SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "proc_track_dirty()");
624*f6217f89SApple OSS Distributions
625*f6217f89SApple OSS Distributions check_properties(pid, JETSAM_PRIORITY_IDLE_DEFERRED, memlimit_active, 0x0,
626*f6217f89SApple OSS Distributions false, "jetsam_test_daemon_memlimit - #1 post-track-dirty");
627*f6217f89SApple OSS Distributions
628*f6217f89SApple OSS Distributions T_LOG("Sleeping for %d to allow idle-ageout.", IDLE_AGEOUT_S);
629*f6217f89SApple OSS Distributions sleep(IDLE_AGEOUT_S);
630*f6217f89SApple OSS Distributions
631*f6217f89SApple OSS Distributions check_properties(pid, JETSAM_PRIORITY_IDLE, memlimit_inactive, 0x0, false,
632*f6217f89SApple OSS Distributions "jetsam_test_daemon_memlimit - #4 post-sleep");
633*f6217f89SApple OSS Distributions
634*f6217f89SApple OSS Distributions proc_set_dirty(pid, true);
635*f6217f89SApple OSS Distributions
636*f6217f89SApple OSS Distributions check_properties(pid, JETSAM_PRIORITY_UI_SUPPORT, memlimit_active, 0x0,
637*f6217f89SApple OSS Distributions false, "jetsam_test_daemon_memlimit - #2 post-set-dirty");
638*f6217f89SApple OSS Distributions
639*f6217f89SApple OSS Distributions proc_set_dirty(pid, false);
640*f6217f89SApple OSS Distributions
641*f6217f89SApple OSS Distributions check_properties(pid, JETSAM_PRIORITY_IDLE_DEFERRED, memlimit_active, 0x0,
642*f6217f89SApple OSS Distributions false, "jetsam_test_daemon_memlimit - #3 post-clear-dirty");
643*f6217f89SApple OSS Distributions
644*f6217f89SApple OSS Distributions T_LOG("Sleeping for %d s to allow idle-ageout.", IDLE_AGEOUT_S);
645*f6217f89SApple OSS Distributions sleep(IDLE_AGEOUT_S);
646*f6217f89SApple OSS Distributions
647*f6217f89SApple OSS Distributions check_properties(pid, JETSAM_PRIORITY_IDLE, memlimit_inactive, 0x0, false,
648*f6217f89SApple OSS Distributions "jetsam_test_daemon_memlimit - #4 post-sleep");
649*f6217f89SApple OSS Distributions
650*f6217f89SApple OSS Distributions proc_set_dirty(pid, true);
651*f6217f89SApple OSS Distributions
652*f6217f89SApple OSS Distributions check_properties(pid, JETSAM_PRIORITY_UI_SUPPORT, memlimit_active, 0x0,
653*f6217f89SApple OSS Distributions false, "jetsam_test_daemon_memlimit - #5 post-set-dirty-2");
654*f6217f89SApple OSS Distributions
655*f6217f89SApple OSS Distributions proc_set_dirty(pid, false);
656*f6217f89SApple OSS Distributions
657*f6217f89SApple OSS Distributions check_properties(pid, JETSAM_PRIORITY_IDLE_DEFERRED, memlimit_active, 0x0, false,
658*f6217f89SApple OSS Distributions "jetsam_test_daemon_memlimit - #6 post-clear-dirty-2");
659*f6217f89SApple OSS Distributions }
660