1 // Check that omp atomic is permitted and behaves when strictly nested within
2 // omp teams.  This is an extension to OpenMP 5.2 and is enabled by default.
3 
4 // RUN: %libomp-compile-and-run | FileCheck %s
5 
6 #include <omp.h>
7 #include <stdbool.h>
8 #include <stdio.h>
9 #include <string.h>
10 
11 // High parallelism increases our chances of detecting a lack of atomicity.
12 #define NUM_TEAMS_TRY 256
13 
main()14 int main() {
15   //      CHECK: update: num_teams=[[#NUM_TEAMS:]]{{$}}
16   // CHECK-NEXT: update: x=[[#NUM_TEAMS]]{{$}}
17   int x = 0;
18   int numTeams;
19   #pragma omp teams num_teams(NUM_TEAMS_TRY)
20   {
21     #pragma omp atomic update
22     ++x;
23     if (omp_get_team_num() == 0)
24       numTeams = omp_get_num_teams();
25   }
26   printf("update: num_teams=%d\n", numTeams);
27   printf("update: x=%d\n", x);
28 
29   // CHECK-NEXT: capture: x=[[#NUM_TEAMS]]{{$}}
30   // CHECK-NEXT: capture: xCapturedCount=[[#NUM_TEAMS]]{{$}}
31   bool xCaptured[numTeams];
32   memset(xCaptured, 0, sizeof xCaptured);
33   x = 0;
34   #pragma omp teams num_teams(NUM_TEAMS_TRY)
35   {
36     int v;
37     #pragma omp atomic capture
38     v = x++;
39     xCaptured[v] = true;
40   }
41   printf("capture: x=%d\n", x);
42   int xCapturedCount = 0;
43   for (int i = 0; i < numTeams; ++i) {
44     if (xCaptured[i])
45       ++xCapturedCount;
46   }
47   printf("capture: xCapturedCount=%d\n", xCapturedCount);
48   return 0;
49 }
50