1*d47f5488SAndrey Churbanov // RUN: %libomp-compile-and-run
2*d47f5488SAndrey Churbanov
3*d47f5488SAndrey Churbanov // https://bugs.llvm.org/show_bug.cgi?id=26540 requested
4*d47f5488SAndrey Churbanov // stack size to be propagated from master to workers.
5*d47f5488SAndrey Churbanov // Library implements propagation of not too big stack
6*d47f5488SAndrey Churbanov // for Linux x86_64 platform (skipped Windows for now).
7*d47f5488SAndrey Churbanov //
8*d47f5488SAndrey Churbanov // The test checks that workers can use more than 4MB
9*d47f5488SAndrey Churbanov // of stack (4MB - was historical default for
10*d47f5488SAndrey Churbanov // stack size of worker thread in runtime library).
11*d47f5488SAndrey Churbanov
12*d47f5488SAndrey Churbanov #include <stdio.h>
13*d47f5488SAndrey Churbanov #include <omp.h>
14*d47f5488SAndrey Churbanov #if !defined(_WIN32)
15*d47f5488SAndrey Churbanov #include <sys/resource.h> // getrlimit
16*d47f5488SAndrey Churbanov #endif
17*d47f5488SAndrey Churbanov
18*d47f5488SAndrey Churbanov #define STK 4800000
19*d47f5488SAndrey Churbanov
foo(int n,int th)20*d47f5488SAndrey Churbanov double foo(int n, int th)
21*d47f5488SAndrey Churbanov {
22*d47f5488SAndrey Churbanov double arr[n];
23*d47f5488SAndrey Churbanov int i;
24*d47f5488SAndrey Churbanov double res = 0.0;
25*d47f5488SAndrey Churbanov for (i = 0; i < n; ++i) {
26*d47f5488SAndrey Churbanov arr[i] = (double)i / (n + 2);
27*d47f5488SAndrey Churbanov }
28*d47f5488SAndrey Churbanov for (i = 0; i < n; ++i) {
29*d47f5488SAndrey Churbanov res += arr[i] / n;
30*d47f5488SAndrey Churbanov }
31*d47f5488SAndrey Churbanov return res;
32*d47f5488SAndrey Churbanov }
33*d47f5488SAndrey Churbanov
main(int argc,char * argv[])34*d47f5488SAndrey Churbanov int main(int argc, char *argv[])
35*d47f5488SAndrey Churbanov {
36*d47f5488SAndrey Churbanov #if defined(_WIN32)
37*d47f5488SAndrey Churbanov // don't test Windows
38*d47f5488SAndrey Churbanov printf("stack propagation not implemented, skipping test...\n");
39*d47f5488SAndrey Churbanov return 0;
40*d47f5488SAndrey Churbanov #else
41*d47f5488SAndrey Churbanov int status;
42*d47f5488SAndrey Churbanov double val = 0.0;
43*d47f5488SAndrey Churbanov int m = STK / 8; // > 4800000 bytes per thread
44*d47f5488SAndrey Churbanov // read stack size of calling thread, save it as default
45*d47f5488SAndrey Churbanov struct rlimit rlim;
46*d47f5488SAndrey Churbanov status = getrlimit(RLIMIT_STACK, &rlim);
47*d47f5488SAndrey Churbanov if (sizeof(void *) > 4 && // do not test 32-bit systems,
48*d47f5488SAndrey Churbanov status == 0 && rlim.rlim_cur > STK) { // or small initial stack size
49*d47f5488SAndrey Churbanov #pragma omp parallel reduction(+:val)
50*d47f5488SAndrey Churbanov {
51*d47f5488SAndrey Churbanov val += foo(m, omp_get_thread_num());
52*d47f5488SAndrey Churbanov }
53*d47f5488SAndrey Churbanov } else {
54*d47f5488SAndrey Churbanov printf("too small stack size limit (needs about 8MB), skipping test...\n");
55*d47f5488SAndrey Churbanov return 0;
56*d47f5488SAndrey Churbanov }
57*d47f5488SAndrey Churbanov if (val > 0.1) {
58*d47f5488SAndrey Churbanov printf("passed\n");
59*d47f5488SAndrey Churbanov return 0;
60*d47f5488SAndrey Churbanov } else {
61*d47f5488SAndrey Churbanov printf("failed, val = %f\n", val);
62*d47f5488SAndrey Churbanov return 1;
63*d47f5488SAndrey Churbanov }
64*d47f5488SAndrey Churbanov #endif // _WIN32
65*d47f5488SAndrey Churbanov }
66