1 // RUN: %clangxx %s -o %t
2 // RUN: env %tool_options=allocator_release_to_os_interval_ms=-1 %run %t
4 // Temporarily disable test
6 // UNSUPPORTED: target={{(powerpc64|loongarch64).*}}
8 // Not needed, no allocator.
11 // FIXME: This mode uses 32bit allocator without purge.
12 // UNSUPPORTED: hwasan-aliasing
24 #include <sys/types.h>
27 #include <sanitizer/allocator_interface.h>
29 const size_t kPageSize
= 4096;
33 (char *)mmap((void *)&sync_rss
, kPageSize
, PROT_READ
| PROT_WRITE
,
34 MAP_PRIVATE
| MAP_ANONYMOUS
, 0, 0);
35 // Linux kernel updates RSS counters after a set number of page faults.
36 for (int i
= 0; i
< 10000; ++i
) {
38 madvise(page
, kPageSize
, MADV_DONTNEED
);
40 munmap(page
, kPageSize
);
43 size_t current_rss() {
45 int statm_fd
= open("/proc/self/statm", O_RDONLY
);
46 assert(statm_fd
>= 0);
49 assert(read(statm_fd
, &buf
, sizeof(buf
)) > 0);
51 assert(sscanf(buf
, "%zu %zu", &size
, &rss
) == 2);
57 size_t MallocReleaseStress() {
58 const size_t kNumChunks
= 10000;
59 const size_t kAllocSize
= 100;
60 const size_t kNumIter
= 100;
61 uintptr_t *chunks
[kNumChunks
] = {0};
64 for (size_t iter
= 0; iter
< kNumIter
; iter
++) {
65 std::shuffle(chunks
, chunks
+ kNumChunks
, r
);
66 size_t to_replace
= rand() % kNumChunks
;
67 for (size_t i
= 0; i
< kNumChunks
; i
++) {
69 assert(chunks
[i
][0] == (uintptr_t)chunks
[i
]);
72 chunks
[i
] = new uintptr_t[kAllocSize
];
73 chunks
[i
][0] = (uintptr_t)chunks
[i
];
77 fprintf(stderr
, "before delete: %zu\n", current_rss());
80 return kNumChunks
* kAllocSize
* sizeof(uintptr_t);
83 int main(int argc
, char **argv
) {
84 // 32bit asan allocator is unsupported.
85 if (sizeof(void *) < 8)
87 auto a
= current_rss();
88 auto total
= MallocReleaseStress() >> 10;
89 auto b
= current_rss();
90 __sanitizer_purge_allocator();
91 auto c
= current_rss();
92 fprintf(stderr
, "a:%zu b:%zu c:%zu total:%zu\n", a
, b
, c
, total
);
93 assert(a
+ total
/ 8 < b
);
94 assert(c
+ total
/ 8 < b
);