Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / test / tsan / Darwin / libcxx-shared-ptr-stress.mm
blob5ce016ae7c48fd8ae544b6aa2b35feb103becd61
1 // RUN: %clangxx_tsan %s -o %t -framework Foundation
2 // RUN: %run %t 2>&1 | FileCheck %s
4 #import <Foundation/Foundation.h>
6 #import <atomic>
7 #import <cassert>
8 #import <cstdio>
9 #import <memory>
11 std::atomic<long> shared_call_counter(0);
12 std::atomic<long> weak_call_counter(0);
13 std::atomic<long> destructor_counter(0);
14 std::atomic<long> weak_destroyed_counter(0);
16 struct 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   }
33 int main(int argc, const char *argv[]) {
34   std::fprintf(stderr, "Hello world.\n");
36   dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
38   dispatch_group_t g = dispatch_group_create();
40   for (int i = 0; i < 1000; i++) {
41     std::shared_ptr<MyStruct> shared(new MyStruct());
42     std::weak_ptr<MyStruct> weak(shared);
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   }
63   dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
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());
70   std::fprintf(stderr, "Done.\n");
73 // CHECK: Hello world.
74 // CHECK: shared_call_counter = 1000000
75 // CHECK: destructor_counter = 1000
76 // CHECK: Done.
77 // CHECK-NOT: WARNING: ThreadSanitizer