1 | // RUN: %libomp-compile-and-run |
2 | #include <stdio.h> |
3 | #include "omp_testsuite.h" |
4 | |
5 | #define NUM_THREADS 10 |
6 | |
7 | /* |
8 | After hot teams were enabled by default, the library started using levels |
9 | kept in the team structure. The levels are broken in case foreign thread |
10 | exits and puts its team into the pool which is then re-used by another foreign |
11 | thread. The broken behavior observed is when printing the levels for each |
12 | new team, one gets 1, 2, 1, 2, 1, 2, etc. This makes the library believe that |
13 | every other team is nested which is incorrect. What is wanted is for the |
14 | levels to be 1, 1, 1, etc. |
15 | */ |
16 | |
17 | int a = 0; |
18 | int level; |
19 | |
20 | typedef struct thread_arg_t { |
21 | int iterations; |
22 | } thread_arg_t; |
23 | |
24 | void* thread_function(void* arg) { |
25 | int i; |
26 | thread_arg_t* targ = (thread_arg_t*)arg; |
27 | int iterations = targ->iterations; |
28 | #pragma omp parallel private(i) |
29 | { |
30 | // level should always be 1 |
31 | #pragma omp single |
32 | level = omp_get_level(); |
33 | |
34 | #pragma omp for |
35 | for(i = 0; i < iterations; i++) { |
36 | #pragma omp atomic |
37 | a++; |
38 | } |
39 | } |
40 | return NULL; |
41 | } |
42 | |
43 | int test_omp_team_reuse() |
44 | { |
45 | int i; |
46 | int success = 1; |
47 | pthread_t thread[NUM_THREADS]; |
48 | thread_arg_t thread_arg[NUM_THREADS]; |
49 | // launch NUM_THREADS threads, one at a time to perform thread_function() |
50 | for(i = 0; i < NUM_THREADS; i++) { |
51 | thread_arg[i].iterations = i + 1; |
52 | pthread_create(thread+i, NULL, thread_function, thread_arg+i); |
53 | pthread_join(*(thread+i), NULL); |
54 | // level read in thread_function()'s parallel region should be 1 |
55 | if(level != 1) { |
56 | fprintf(stderr, format: "error: for pthread %d level should be 1 but " |
57 | "instead equals %d\n" , i, level); |
58 | success = 0; |
59 | } |
60 | } |
61 | // make sure the for loop works |
62 | int known_sum = (NUM_THREADS * (NUM_THREADS+1)) / 2; |
63 | if(a != known_sum) { |
64 | fprintf(stderr, format: "a should be %d but instead equals %d\n" , known_sum, a); |
65 | success = 0; |
66 | } |
67 | return success; |
68 | } |
69 | |
70 | int main() |
71 | { |
72 | int i; |
73 | int num_failed=0; |
74 | |
75 | for(i = 0; i < REPETITIONS; i++) { |
76 | a = 0; |
77 | if(!test_omp_team_reuse()) { |
78 | num_failed++; |
79 | } |
80 | } |
81 | return num_failed; |
82 | } |
83 | |