brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.3 KiB · 5ce016a Raw
78 lines · plain
1// RUN: %clangxx_tsan %s -o %t -framework Foundation2// RUN: %run %t 2>&1 | FileCheck %s3 4#import <Foundation/Foundation.h>5 6#import <atomic>7#import <cassert>8#import <cstdio>9#import <memory>10 11std::atomic<long> shared_call_counter(0);12std::atomic<long> weak_call_counter(0);13std::atomic<long> destructor_counter(0);14std::atomic<long> weak_destroyed_counter(0);15 16struct MyStruct {17  std::atomic<long> self_counter;18  MyStruct() : self_counter(0) { }19  virtual void shared_call() {20    std::atomic_fetch_add_explicit(&self_counter, 1, std::memory_order_relaxed);21    std::atomic_fetch_add_explicit(&shared_call_counter, 1, std::memory_order_relaxed);22  }23  virtual void weak_call() {24    std::atomic_fetch_add_explicit(&weak_call_counter, 1, std::memory_order_relaxed);25  }26  virtual ~MyStruct() {27    long n = self_counter;28    assert(n == 1000);29    std::atomic_fetch_add_explicit(&destructor_counter, 1, std::memory_order_relaxed);30  }31};32 33int main(int argc, const char *argv[]) {34  std::fprintf(stderr, "Hello world.\n");35 36  dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);37 38  dispatch_group_t g = dispatch_group_create();39 40  for (int i = 0; i < 1000; i++) {41    std::shared_ptr<MyStruct> shared(new MyStruct());42    std::weak_ptr<MyStruct> weak(shared);43 44    dispatch_group_async(g, q, ^{45      for (int j = 0; j < 1000; j++) {46        std::shared_ptr<MyStruct> shared_copy(shared);47        shared_copy->shared_call();48      }49    });50    dispatch_group_async(g, q, ^{51      for (int j = 0; j < 1000; j++) {52        std::shared_ptr<MyStruct> weak_copy = weak.lock();53        if (weak_copy) {54          weak_copy->weak_call();55        } else {56          std::atomic_fetch_add_explicit(&weak_destroyed_counter, 1, std::memory_order_relaxed);57          break;58        }59      }60    });61  }62 63  dispatch_group_wait(g, DISPATCH_TIME_FOREVER);64 65  std::fprintf(stderr, "shared_call_counter = %ld\n", shared_call_counter.load());66  std::fprintf(stderr, "weak_call_counter = %ld\n", weak_call_counter.load());67  std::fprintf(stderr, "destructor_counter = %ld\n", destructor_counter.load());68  std::fprintf(stderr, "weak_destroyed_counter = %ld\n", weak_destroyed_counter.load());69 70  std::fprintf(stderr, "Done.\n");71}72 73// CHECK: Hello world.74// CHECK: shared_call_counter = 100000075// CHECK: destructor_counter = 100076// CHECK: Done.77// CHECK-NOT: WARNING: ThreadSanitizer78