1 // RUN: %libomp-cxx-compile-and-run
2 
3 #include <omp.h>
4 
5 #include <algorithm>
6 #include <cassert>
7 #include <chrono>
8 #include <thread>
9 #include <vector>
10 
dummy_root()11 void dummy_root() {
12   // omp_get_max_threads() will do middle initialization
13   int nthreads = omp_get_max_threads();
14   std::this_thread::sleep_for(std::chrono::milliseconds(1000));
15 }
16 
main(int argc,char * argv[])17 int main(int argc, char *argv[]) {
18   const int N = std::min(std::max(std::max(32, 4 * omp_get_max_threads()),
19                                   4 * omp_get_num_procs()),
20                          std::numeric_limits<int>::max());
21 
22   std::vector<int> data(N);
23 
24   // Create a new thread to initialize the OpenMP RTL. The new thread will not
25   // be taken as the "initial thread".
26   std::thread root(dummy_root);
27 
28 #pragma omp parallel for num_threads(N)
29   for (unsigned i = 0; i < N; ++i) {
30     data[i] = i;
31   }
32 
33 #pragma omp parallel for num_threads(N + 1)
34   for (unsigned i = 0; i < N; ++i) {
35     data[i] += i;
36   }
37 
38   for (unsigned i = 0; i < N; ++i) {
39     assert(data[i] == 2 * i);
40   }
41 
42   root.join();
43 
44   return 0;
45 }
46