00001 // { dg-do run } 00002 // { dg-require-effective-target tls_runtime } 00003 00004 #include <omp.h> 00005 #include <assert.h> 00006 00007 #define N 10 00008 #define THR 4 00009 00010 struct B 00011 { 00012 B(); 00013 B(const B &); 00014 ~B(); 00015 B& operator=(const B &); 00016 void doit(); 00017 static B *base; 00018 static B *threadbase; 00019 #pragma omp threadprivate(threadbase) 00020 }; 00021 00022 B *B::base; 00023 B *B::threadbase; 00024 static unsigned cmask[THR]; 00025 static unsigned dmask[THR]; 00026 00027 B::B() 00028 { 00029 assert (base == 0); 00030 } 00031 00032 B::B(const B &b) 00033 { 00034 unsigned index = &b - base; 00035 assert (index < N); 00036 cmask[omp_get_thread_num()] |= 1u << index; 00037 } 00038 00039 B::~B() 00040 { 00041 if (threadbase) 00042 { 00043 unsigned index = this - threadbase; 00044 assert (index < N); 00045 dmask[omp_get_thread_num()] |= 1u << index; 00046 } 00047 } 00048 00049 void foo() 00050 { 00051 B b[N]; 00052 00053 B::base = b; 00054 00055 #pragma omp parallel firstprivate(b) 00056 { 00057 assert (omp_get_num_threads () == THR); 00058 B::threadbase = b; 00059 } 00060 00061 B::threadbase = 0; 00062 } 00063 00064 int main() 00065 { 00066 omp_set_dynamic (0); 00067 omp_set_num_threads (THR); 00068 foo(); 00069 00070 for (int i = 0; i < THR; ++i) 00071 { 00072 unsigned xmask = (1u << N) - 1; 00073 assert (cmask[i] == xmask); 00074 assert (dmask[i] == xmask); 00075 } 00076 00077 return 0; 00078 }