xref: /llvm-project/openmp/runtime/test/threadprivate/omp_threadprivate.c (revision 4c6a098ad52fc2844f7733bc051cd7a729500f04)
1 // RUN: %libomp-compile-and-run
2 /*
3  * Threadprivate is tested in 2 ways:
4  * 1. The global variable declared as threadprivate should have
5  *  local copy for each thread. Otherwise race condition and
6  *  wrong result.
7  * 2. If the value of local copy is retained for the two adjacent
8  *  parallel regions
9  */
10 #include "omp_testsuite.h"
11 #include <stdlib.h>
12 #include <stdio.h>
13 
14 static int sum0=0;
15 static int myvalue = 0;
16 
17 #pragma omp threadprivate(sum0)
18 #pragma omp threadprivate(myvalue)
19 
test_omp_threadprivate()20 int test_omp_threadprivate()
21 {
22   int sum = 0;
23   int known_sum;
24   int i;
25   int iter;
26   int *data;
27   int size;
28   int num_failed = 0;
29   int my_random;
30   omp_set_dynamic(0);
31 
32   #pragma omp parallel private(i)
33   {
34     sum0 = 0;
35     #pragma omp for
36     for (i = 1; i <= LOOPCOUNT; i++) {
37       sum0 = sum0 + i;
38     } /*end of for*/
39     #pragma omp critical
40     {
41       sum = sum + sum0;
42     } /*end of critical */
43   } /* end of parallel */
44   known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
45   if (known_sum != sum ) {
46     fprintf (stderr, " known_sum = %d, sum = %d\n", known_sum, sum);
47   }
48 
49   /* the next parallel region is just used to get the number of threads*/
50   omp_set_dynamic(0);
51   #pragma omp parallel
52   {
53     #pragma omp master
54     {
55       size=omp_get_num_threads();
56       data=(int*) malloc(size*sizeof(int));
57     }
58   }/* end parallel*/
59 
60   srand(45);
61   for (iter = 0; iter < 100; iter++) {
62     my_random = rand(); /* random number generator is
63                  called inside serial region*/
64 
65     /* the first parallel region is used to initialize myvalue
66        and the array with my_random+rank */
67     #pragma omp parallel
68     {
69       int rank;
70       rank = omp_get_thread_num ();
71       myvalue = data[rank] = my_random + rank;
72     }
73 
74     /* the second parallel region verifies that the
75        value of "myvalue" is retained */
76     #pragma omp parallel reduction(+:num_failed)
77     {
78       int rank;
79       rank = omp_get_thread_num ();
80       num_failed = num_failed + (myvalue != data[rank]);
81       if(myvalue != data[rank]) {
82         fprintf (stderr, " myvalue = %d, data[rank]= %d\n",
83           myvalue, data[rank]);
84       }
85     }
86   }
87   free (data);
88   return (known_sum == sum) && !num_failed;
89 } /* end of check_threadprivate*/
90 
main()91 int main()
92 {
93   int i;
94   int num_failed=0;
95 
96   for(i = 0; i < REPETITIONS; i++) {
97     if(!test_omp_threadprivate()) {
98       num_failed++;
99     }
100   }
101   return num_failed;
102 }
103