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