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 | |
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, format: " 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: size*sizeof(int)); |
57 | } |
58 | }/* end parallel*/ |
59 | |
60 | srand(seed: 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, format: " myvalue = %d, data[rank]= %d\n" , |
83 | myvalue, data[rank]); |
84 | } |
85 | } |
86 | } |
87 | free (ptr: data); |
88 | return (known_sum == sum) && !num_failed; |
89 | } /* end of check_threadprivate*/ |
90 | |
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 | |