0
|
1 // { dg-do run }
|
|
2 // { dg-require-effective-target tls_runtime }
|
|
3
|
|
4 #include <omp.h>
|
|
5 #include <assert.h>
|
|
6
|
|
7 #define N 10
|
|
8 #define THR 4
|
|
9
|
|
10 struct B
|
|
11 {
|
|
12 B();
|
|
13 B(const B &);
|
|
14 ~B();
|
|
15 B& operator=(const B &);
|
|
16 void doit();
|
|
17 };
|
|
18
|
|
19 static B *base;
|
|
20 static B *threadbase;
|
|
21 static unsigned cmask[THR];
|
|
22 static unsigned dmask[THR];
|
|
23
|
|
24 #pragma omp threadprivate(threadbase)
|
|
25
|
|
26 B::B()
|
|
27 {
|
|
28 assert (base == 0);
|
|
29 }
|
|
30
|
|
31 B::B(const B &b)
|
|
32 {
|
|
33 unsigned index = &b - base;
|
|
34 assert (index < N);
|
|
35 cmask[omp_get_thread_num()] |= 1u << index;
|
|
36 }
|
|
37
|
|
38 B::~B()
|
|
39 {
|
|
40 if (threadbase)
|
|
41 {
|
|
42 unsigned index = this - threadbase;
|
|
43 assert (index < N);
|
|
44 dmask[omp_get_thread_num()] |= 1u << index;
|
|
45 }
|
|
46 }
|
|
47
|
|
48 void foo()
|
|
49 {
|
|
50 B b[N];
|
|
51
|
|
52 base = b;
|
|
53
|
|
54 #pragma omp parallel firstprivate(b)
|
|
55 {
|
|
56 assert (omp_get_num_threads () == THR);
|
|
57 threadbase = b;
|
|
58 }
|
|
59
|
|
60 threadbase = 0;
|
|
61 }
|
|
62
|
|
63 int main()
|
|
64 {
|
|
65 omp_set_dynamic (0);
|
|
66 omp_set_num_threads (THR);
|
|
67 foo();
|
|
68
|
|
69 for (int i = 0; i < THR; ++i)
|
|
70 {
|
|
71 unsigned xmask = (1u << N) - 1;
|
|
72 assert (cmask[i] == xmask);
|
|
73 assert (dmask[i] == xmask);
|
|
74 }
|
|
75
|
|
76 return 0;
|
|
77 }
|