| // { dg-do run } |
| // { dg-require-effective-target tls_runtime } |
| |
| #include <omp.h> |
| #include <assert.h> |
| |
| #define N 10 |
| #define THR 4 |
| |
| struct B |
| { |
| B(); |
| B(const B &); |
| ~B(); |
| B& operator=(const B &); |
| void doit(); |
| static B *base; |
| static B *threadbase; |
| #pragma omp threadprivate(threadbase) |
| }; |
| |
| B *B::base; |
| B *B::threadbase; |
| static unsigned cmask[THR]; |
| static unsigned dmask[THR]; |
| |
| B::B() |
| { |
| assert (base == 0); |
| } |
| |
| B::B(const B &b) |
| { |
| unsigned index = &b - base; |
| assert (index < N); |
| cmask[omp_get_thread_num()] |= 1u << index; |
| } |
| |
| B::~B() |
| { |
| if (threadbase) |
| { |
| unsigned index = this - threadbase; |
| assert (index < N); |
| dmask[omp_get_thread_num()] |= 1u << index; |
| } |
| } |
| |
| void foo() |
| { |
| B b[N]; |
| |
| B::base = b; |
| |
| #pragma omp parallel firstprivate(b) |
| { |
| assert (omp_get_num_threads () == THR); |
| B::threadbase = b; |
| } |
| |
| B::threadbase = 0; |
| } |
| |
| int main() |
| { |
| omp_set_dynamic (0); |
| omp_set_num_threads (THR); |
| foo(); |
| |
| for (int i = 0; i < THR; ++i) |
| { |
| unsigned xmask = (1u << N) - 1; |
| assert (cmask[i] == xmask); |
| assert (dmask[i] == xmask); |
| } |
| |
| return 0; |
| } |