brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · c7a5534 Raw
99 lines · cpp
1// RUN: %clangxx %s -o %t2// RUN: env %tool_options=allocator_release_to_os_interval_ms=-1 %run %t3 4// Temporarily disable test5// UNSUPPORTED: tsan6// UNSUPPORTED: target={{(powerpc64|loongarch64).*}}7 8// Not needed, no allocator.9// UNSUPPORTED: ubsan10 11// FIXME: This mode uses 32bit allocator without purge.12// UNSUPPORTED: hwasan-aliasing13 14// Page size is hardcoded below, but test still fails even if not hardcoded.15// REQUIRES: page-size-409616 17#include <algorithm>18#include <assert.h>19#include <fcntl.h>20#include <random>21#include <stdint.h>22#include <stdio.h>23#include <stdlib.h>24#include <string.h>25#include <sys/mman.h>26#include <sys/stat.h>27#include <sys/types.h>28#include <unistd.h>29 30#include <sanitizer/allocator_interface.h>31 32const size_t kPageSize = 4096;33 34void sync_rss() {35  char *page =36      (char *)mmap((void *)&sync_rss, kPageSize, PROT_READ | PROT_WRITE,37                   MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);38  // Linux kernel updates RSS counters after a set number of page faults.39  for (int i = 0; i < 10000; ++i) {40    page[0] = 42;41    madvise(page, kPageSize, MADV_DONTNEED);42  }43  munmap(page, kPageSize);44}45 46size_t current_rss() {47  sync_rss();48  int statm_fd = open("/proc/self/statm", O_RDONLY);49  assert(statm_fd >= 0);50 51  char buf[100];52  assert(read(statm_fd, &buf, sizeof(buf)) > 0);53  size_t size, rss;54  assert(sscanf(buf, "%zu %zu", &size, &rss) == 2);55 56  close(statm_fd);57  return rss;58}59 60size_t MallocReleaseStress() {61  const size_t kNumChunks = 10000;62  const size_t kAllocSize = 100;63  const size_t kNumIter = 100;64  uintptr_t *chunks[kNumChunks] = {0};65  std::mt19937 r;66 67  for (size_t iter = 0; iter < kNumIter; iter++) {68    std::shuffle(chunks, chunks + kNumChunks, r);69    size_t to_replace = rand() % kNumChunks;70    for (size_t i = 0; i < kNumChunks; i++) {71      if (chunks[i])72        assert(chunks[i][0] == (uintptr_t)chunks[i]);73      if (i < to_replace) {74        delete[] chunks[i];75        chunks[i] = new uintptr_t[kAllocSize];76        chunks[i][0] = (uintptr_t)chunks[i];77      }78    }79  }80  fprintf(stderr, "before delete: %zu\n", current_rss());81  for (auto p : chunks)82    delete[] p;83  return kNumChunks * kAllocSize * sizeof(uintptr_t);84}85 86int main(int argc, char **argv) {87  // 32bit asan allocator is unsupported.88  if (sizeof(void *) < 8)89    return 0;90  auto a = current_rss();91  auto total = MallocReleaseStress() >> 10;92  auto b = current_rss();93  __sanitizer_purge_allocator();94  auto c = current_rss();95  fprintf(stderr, "a:%zu b:%zu c:%zu total:%zu\n", a, b, c, total);96  assert(a + total / 8 < b);97  assert(c + total / 8 < b);98}99