1// { dg-do run }
2
3#include <omp.h>
4#include <assert.h>
5
6struct B
7{
8  static int icount;
9  static int dcount;
10  static int ccount;
11  static B *e_inner;
12  static B *e_outer;
13
14  B();
15  B(int);
16  B(const B &);
17  ~B();
18  B& operator=(const B &);
19  void doit();
20};
21
22int B::icount;
23int B::dcount;
24int B::ccount;
25B * B::e_inner;
26B * B::e_outer;
27
28B::B()
29{
30  #pragma omp atomic
31    icount++;
32}
33
34B::B(int)
35{
36  e_outer = this;
37}
38
39B::~B()
40{
41  #pragma omp atomic
42    dcount++;
43}
44
45B& B::operator= (const B &b)
46{
47  assert (&b == e_inner);
48  assert (this == e_outer);
49  #pragma omp atomic
50    ccount++;
51  return *this;
52}
53
54void B::doit()
55{
56  #pragma omp critical
57    {
58      assert (e_inner == 0);
59      e_inner = this;
60    }
61}
62
63static int nthreads;
64
65void foo()
66{
67  B b(0);
68
69  #pragma omp parallel sections lastprivate(b)
70    {
71    #pragma omp section
72      nthreads = omp_get_num_threads ();
73    #pragma omp section
74      b.doit ();
75    }
76}
77
78int main()
79{
80  omp_set_dynamic (0);
81  omp_set_num_threads (4);
82  foo();
83
84  assert (B::ccount == 1);
85  assert (B::icount == nthreads);
86  assert (B::dcount == nthreads+1);
87
88  return 0;
89}
90