15d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// RUN: %clangxx_asan -O0 %s -pthread -o %t && %run %t
25d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// RUN: %clangxx_asan -O2 %s -pthread -o %t && %run %t
35d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// REQUIRES: stable-runtime
4717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov
5717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov#include <assert.h>
6717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov#include <pthread.h>
75d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include <sanitizer/allocator_interface.h>
8717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov#include <stdio.h>
9717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov#include <stdlib.h>
10717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov
11717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonovconst size_t kLargeAlloc = 1UL << 20;
12717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov
13717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonovvoid* allocate(void *arg) {
14717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  volatile void *ptr = malloc(kLargeAlloc);
15717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  free((void*)ptr);
16717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  return 0;
17717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov}
18717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov
19717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonovvoid* check_stats(void *arg) {
205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  assert(__sanitizer_get_current_allocated_bytes() > 0);
21717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  return 0;
22717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov}
23717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov
24717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonovint main() {
255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  size_t used_mem = __sanitizer_get_current_allocated_bytes();
26717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  printf("Before: %zu\n", used_mem);
27717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  const int kNumIterations = 1000;
28717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  for (int iter = 0; iter < kNumIterations; iter++) {
29717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov    pthread_t thr[4];
30717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov    for (int j = 0; j < 4; j++) {
31717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov      assert(0 ==
32717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov             pthread_create(&thr[j], 0, (j < 2) ? allocate : check_stats, 0));
33717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov    }
34717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov    for (int j = 0; j < 4; j++)
35717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov      assert(0 == pthread_join(thr[j], 0));
365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    used_mem = __sanitizer_get_current_allocated_bytes();
37717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov    if (used_mem > kLargeAlloc) {
38717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov      printf("After iteration %d: %zu\n", iter, used_mem);
39717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov      return 1;
40717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov    }
41717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  }
42717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  printf("Success after %d iterations\n", kNumIterations);
43717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov  return 0;
44717ece58e18190c4aef50bd16254db1d74036395Alexey Samsonov}
45