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