diff options
author | Evgenii Stepanov <eugenis@google.com> | 2021-05-05 11:56:52 -0700 |
---|---|---|
committer | Evgenii Stepanov <eugenis@google.com> | 2021-05-11 13:10:53 -0700 |
commit | a7757f6c22e45e84e56da79af67fe29dd1c224f5 (patch) | |
tree | 07cacd4f89581c03fbee53c606ae34185a6e0567 | |
parent | d092dd56aed8af64425446544ca7c9a0616d86ce (diff) | |
download | llvm-a7757f6c22e45e84e56da79af67fe29dd1c224f5.zip llvm-a7757f6c22e45e84e56da79af67fe29dd1c224f5.tar.gz llvm-a7757f6c22e45e84e56da79af67fe29dd1c224f5.tar.bz2 |
[hwasan] Stress test for thread creation.
This test has two modes - testing reused threads with multiple loops of
batch create/join, and testing new threads with a single loop of
create/join per fork.
The non-reuse variant catches the problem that was fixed in D101881 with
a high probability.
Differential Revision: https://reviews.llvm.org/D101936
-rw-r--r-- | compiler-rt/test/hwasan/TestCases/Linux/create-thread-stress.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/compiler-rt/test/hwasan/TestCases/Linux/create-thread-stress.cpp b/compiler-rt/test/hwasan/TestCases/Linux/create-thread-stress.cpp new file mode 100644 index 0000000..ac905a2 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/Linux/create-thread-stress.cpp @@ -0,0 +1,61 @@ +// Stress test for https://reviews.llvm.org/D101881 +// RUN: %clangxx_hwasan -DREUSE=0 %s -pthread -O2 -o %t && %run %t 2>&1 +// RUN: %clangxx_hwasan -DREUSE=1 %s -pthread -O2 -o %t_reuse && %run %t_reuse 2>&1 + +#include <thread> +#include <vector> + +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <stdio.h> + +constexpr int kTopThreads = 20; +constexpr int kChildThreads = 30; +constexpr int kChildIterations = REUSE ? 8 : 1; + +constexpr int kProcessIterations = 20; + +void Thread() { + for (int i = 0; i < kChildIterations; ++i) { + std::vector<std::thread> threads; + for (int i = 0; i < kChildThreads; ++i) + threads.emplace_back([]() {}); + for (auto &t : threads) + t.join(); + } +} + +void run() { + std::vector<std::thread> threads; + for (int i = 0; i < kTopThreads; ++i) + threads.emplace_back(Thread); + for (auto &t : threads) + t.join(); +} + +int main() { +#if REUSE + // Test thread reuse with multiple iterations of thread create / join in a single process. + run(); +#else + // Test new, non-reused thread creation by running a single iteration of create / join in a freshly started process. + for (int i = 0; i < kProcessIterations; ++i) { + int pid = fork(); + if (pid) { + int wstatus; + do { + waitpid(pid, &wstatus, 0); + } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus)); + if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) { + fprintf(stderr, "failed at iteration %d / %d\n", i, kProcessIterations); + return 1; + } + } else { + run(); + return 0; + } + } +#endif +} |