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
17int a = 0;
18int level;
19
20typedef struct thread_arg_t {
21 int iterations;
22} thread_arg_t;
23
24void* 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
43int 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
70int 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

source code of openmp/runtime/test/misc_bugs/omp_foreign_thread_team_reuse.c