2 * Copyright (c) 2015-2018 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <darwintest.h>
27 #include <sys/types.h>
28 #include <sys/sysctl.h>
29 #include <mach/mach.h>
30 #include <sys/utsname.h>
31 #include <TargetConditionals.h>
33 #define WIRED_MEM_THRESHOLD_PERCENTAGE 30
35 T_DECL(wired_mem_bench
,
36 "report the amount of wired memory consumed by the booted OS; guard against egregious or unexpected regressions",
37 T_META_CHECK_LEAKS(false),
39 T_META_REQUIRES_REBOOT(true)) // Help reduce noise by asking for a clean boot
42 vm_statistics64_data_t stat
;
44 vm_size_t page_size
= 0;
45 unsigned int count
= HOST_VM_INFO64_COUNT
;
48 struct utsname uname_vers
;
51 ret
= uname(&uname_vers
);
53 T_ASSERT_POSIX_SUCCESS(ret
, "uname()");
55 if (strnstr(uname_vers
.version
, "KASAN", sizeof(uname_vers
.version
)) != NULL
) {
56 T_SKIP("wired memory metrics are not meaningful on KASAN kernels.");
59 ret
= host_statistics64(mach_host_self(), HOST_VM_INFO64
, (host_info64_t
)&stat
, &count
);
61 T_ASSERT_MACH_SUCCESS(ret
, "wired memory query via host_statistics64()");
63 size_t s
= sizeof(memsize
);
64 ret
= sysctlbyname("hw.memsize", &memsize
, &s
, NULL
, 0);
66 T_ASSERT_POSIX_SUCCESS(ret
, "sysctlbyname(\"hw.memsize\")");
69 T_EXPECT_NE(memsize
, 0ULL, "hw.memsize sysctl failed to provide device DRAM size");
71 ret
= host_page_size(mach_host_self(), &page_size
);
73 T_ASSERT_MACH_SUCCESS(ret
, "page size query via host_page_size()");
77 T_PERF("wired_memory", (double)(stat
.wire_count
* (mach_vm_size_t
)vm_kernel_page_size
>> 10), "kB",
78 "Wired memory at boot");
80 T_LOG("\nwired memory: %llu kB (%llu MB)\n", stat
.wire_count
* (mach_vm_size_t
)vm_kernel_page_size
>> 10,
81 stat
.wire_count
* (mach_vm_size_t
)vm_kernel_page_size
>> 20);
83 #if TARGET_OS_IOS || TARGET_OS_OSX
84 // zprint is not mastered onto other platforms.
86 if ((r
= system("zprint")) != 0) {
87 T_FAIL("couldn't run zprint: %d", r
);
91 * Poor-man's wired memory regression test: validate that wired memory consumes
92 * no more than some outrageously high fixed percentage of total device memory.
94 wired_mem_pct
= (int)((stat
.wire_count
* page_size
* 100ULL) / memsize
);
95 T_PERF("wired_memory_percentage", wired_mem_pct
, "%", "Wired memory as percentage of device DRAM size");
97 T_ASSERT_LT(wired_mem_pct
, WIRED_MEM_THRESHOLD_PERCENTAGE
,
98 "Wired memory percentage is below allowable threshold (%llu bytes / %u pages / %llu total device memory)",
99 (uint64_t)stat
.wire_count
* page_size
, stat
.wire_count
, memsize
);