xref: /llvm-project/compiler-rt/test/hwasan/TestCases/Linux/create-thread-stress.cpp (revision fab079275aac895d5f48b96006f62390a5e24664)
1 // Stress test for https://reviews.llvm.org/D101881
2 // RUN: %clangxx_hwasan -DREUSE=0 %s -pthread -O2 -o %t && %run %t 2>&1
3 // RUN: %clangxx_hwasan -DREUSE=1 %s -pthread -O2 -o %t_reuse && %run %t_reuse 2>&1
4 
5 #include <thread>
6 #include <vector>
7 
8 #include <sys/types.h>
9 #include <sys/wait.h>
10 #include <unistd.h>
11 
12 #include <stdio.h>
13 
14 constexpr int kTopThreads = 20;
15 constexpr int kChildThreads = 30;
16 constexpr int kChildIterations = REUSE ? 8 : 1;
17 
18 constexpr int kProcessIterations = 20;
19 
Thread()20 void Thread() {
21   for (int i = 0; i < kChildIterations; ++i) {
22     std::vector<std::thread> threads;
23     threads.reserve(kChildThreads);
24     for (int i = 0; i < kChildThreads; ++i)
25       threads.emplace_back([]() {});
26     for (auto &t : threads)
27       t.join();
28   }
29 }
30 
run()31 void run() {
32   std::vector<std::thread> threads;
33   threads.reserve(kTopThreads);
34   for (int i = 0; i < kTopThreads; ++i)
35     threads.emplace_back(Thread);
36   for (auto &t : threads)
37     t.join();
38 }
39 
main()40 int main() {
41 #if REUSE
42   // Test thread reuse with multiple iterations of thread create / join in a single process.
43   run();
44 #else
45   // Test new, non-reused thread creation by running a single iteration of create / join in a freshly started process.
46   for (int i = 0; i < kProcessIterations; ++i) {
47     int pid = fork();
48     if (pid) {
49       int wstatus;
50       do {
51         waitpid(pid, &wstatus, 0);
52       } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
53       if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) {
54         fprintf(stderr, "failed at iteration %d / %d\n", i, kProcessIterations);
55         return 1;
56       }
57     } else {
58       run();
59       return 0;
60     }
61   }
62 #endif
63 }
64