1 | // RUN: %clangxx_tsan %s -o %t |
2 | // RUN: %run %t 2>&1 | FileCheck %s |
3 | |
4 | // bench.h needs pthread barriers which are not available on OS X |
5 | // UNSUPPORTED: darwin |
6 | |
7 | #include "bench.h" |
8 | |
9 | void *nop_thread(void *arg) { |
10 | pthread_setname_np(target_thread: pthread_self(), name: "nop_thread" ); |
11 | return nullptr; |
12 | } |
13 | |
14 | void thread(int tid) { |
15 | for (int i = 0; i < bench_niter; i++) { |
16 | pthread_t th; |
17 | pthread_create(newthread: &th, attr: nullptr, start_routine: nop_thread, arg: nullptr); |
18 | pthread_join(th: th, thread_return: nullptr); |
19 | } |
20 | } |
21 | |
22 | void bench() { |
23 | // Benchmark thread creation/joining in presence of a large number |
24 | // of threads (both alive and already joined). |
25 | printf(format: "starting transient threads...\n" ); |
26 | for (int i = 0; i < 200; i++) { |
27 | const int kBatch = 100; |
28 | pthread_t th[kBatch]; |
29 | for (int j = 0; j < kBatch; j++) |
30 | pthread_create(newthread: &th[j], attr: nullptr, start_routine: nop_thread, arg: nullptr); |
31 | for (int j = 0; j < kBatch; j++) |
32 | pthread_join(th: th[j], thread_return: nullptr); |
33 | } |
34 | printf(format: "starting persistent threads...\n" ); |
35 | const int kLiveThreads = 2000; |
36 | pthread_t th[kLiveThreads]; |
37 | for (int j = 0; j < kLiveThreads; j++) |
38 | pthread_create(newthread: &th[j], attr: nullptr, start_routine: nop_thread, arg: nullptr); |
39 | printf(format: "starting benchmark threads...\n" ); |
40 | start_thread_group(nth: bench_nthread, f: thread); |
41 | for (int j = 0; j < kLiveThreads; j++) |
42 | pthread_join(th: th[j], thread_return: nullptr); |
43 | } |
44 | |
45 | // CHECK: DONE |
46 | |