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
14static int sum0=0;
15static int myvalue = 0;
16
17#pragma omp threadprivate(sum0)
18#pragma omp threadprivate(myvalue)
19
20int 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
91int 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

source code of openmp/runtime/test/threadprivate/omp_threadprivate.c