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