1 #include <darwintest.h>
2 #include <dispatch/dispatch.h>
3 #include <execinfo.h>
4 #include <pthread.h>
5 #include <ptrauth.h>
6 #include <mach/mach.h>
7 #include <stdalign.h>
8 #include <sys/mman.h>
9 #include <sys/sysctl.h>
10
11
12 static const off_t gb = 1024 * 1024 * 1024;
13
14 static void
get_release_type(char * release_type,size_t release_type_len)15 get_release_type(char *release_type, size_t release_type_len)
16 {
17 int ret;
18 T_ASSERT_POSIX_SUCCESS(ret = sysctlbyname("kern.osreleasetype", release_type, &release_type_len, NULL, 0), "sysctlbyname kern.osreleasetype");
19 }
20
21 static int64_t
get_hw_memsize(int64_t memsize)22 get_hw_memsize(int64_t memsize)
23 {
24 int ret;
25 size_t size = sizeof(memsize);
26 T_ASSERT_POSIX_SUCCESS(ret = sysctlbyname("hw.memsize", &memsize, &size, NULL, 0), "sysctlbyname hw.memsize");
27
28 return memsize;
29 }
30
31 T_DECL(big_map_test,
32 "Test that loads large blobs into memory up to 60 percent of gigs available.",
33 T_META_ASROOT(true),
34 T_META_CHECK_LEAKS(false))
35 {
36 int fd;
37 int64_t memsize = 0;
38 size_t release_type_len = 256;
39 char release_type[release_type_len];
40 const char required_release_type[] = "Darwin Cloud";
41
42 get_release_type(release_type, release_type_len);
43 if (strstr(release_type, required_release_type) == NULL) {
44 T_SKIP("Attempted to run on non psOS release type, skipping...");
45 }
46
47 memsize = get_hw_memsize(memsize);
48 float max_memory_gib = ((float)memsize / (float)gb) * .6;
49
50 if (max_memory_gib <= 11) {
51 T_SKIP("Not enough memory on device atleast (11GBs required), skipping...");
52 }
53
54 char file_path[] = "/tmp/bigfile.XXXXXX";
55 T_QUIET; T_ASSERT_POSIX_SUCCESS(fd = mkstemp(file_path), NULL);
56 for (int gigs = 1; gigs <= max_memory_gib; gigs++) {
57 size_t bytes = gigs * gb;
58
59 T_LOG("trying %zu bytes (%d GB)\n", bytes, gigs);
60
61 T_QUIET; T_ASSERT_POSIX_SUCCESS(ftruncate(fd, bytes), "ftruncate");
62
63 void *p = mmap(NULL, bytes, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
64
65 T_QUIET; T_ASSERT_NE(p, MAP_FAILED, "map");
66
67 T_QUIET; T_ASSERT_POSIX_SUCCESS(munmap(p, bytes), "munmap");
68 }
69 }
70