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 static B *base;
|
|
18 static B *threadbase;
|
|
19 #pragma omp threadprivate(threadbase)
|
|
20 };
|
|
21
|
|
22 B *B::base;
|
|
23 B *B::threadbase;
|
|
24 static unsigned cmask[THR];
|
|
25 static unsigned dmask[THR];
|
|
26
|
|
27 B::B()
|
|
28 {
|
|
29 assert (base == 0);
|
|
30 }
|
|
31
|
|
32 B::B(const B &b)
|
|
33 {
|
|
34 unsigned index = &b - base;
|
|
35 assert (index < N);
|
|
36 cmask[omp_get_thread_num()] |= 1u << index;
|
|
37 }
|
|
38
|
|
39 B::~B()
|
|
40 {
|
|
41 if (threadbase)
|
|
42 {
|
|
43 unsigned index = this - threadbase;
|
|
44 assert (index < N);
|
|
45 dmask[omp_get_thread_num()] |= 1u << index;
|
|
46 }
|
|
47 }
|
|
48
|
|
49 void foo()
|
|
50 {
|
|
51 B b[N];
|
|
52
|
|
53 B::base = b;
|
|
54
|
|
55 #pragma omp parallel firstprivate(b)
|
|
56 {
|
|
57 assert (omp_get_num_threads () == THR);
|
|
58 B::threadbase = b;
|
|
59 }
|
|
60
|
|
61 B::threadbase = 0;
|
|
62 }
|
|
63
|
|
64 int main()
|
|
65 {
|
|
66 omp_set_dynamic (0);
|
|
67 omp_set_num_threads (THR);
|
|
68 foo();
|
|
69
|
|
70 for (int i = 0; i < THR; ++i)
|
|
71 {
|
|
72 unsigned xmask = (1u << N) - 1;
|
|
73 assert (cmask[i] == xmask);
|
|
74 assert (dmask[i] == xmask);
|
|
75 }
|
|
76
|
|
77 return 0;
|
|
78 }
|