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 }; 00018 00019 static B *base; 00020 static B *threadbase; 00021 static unsigned cmask[THR]; 00022 static unsigned dmask[THR]; 00023 00024 #pragma omp threadprivate(threadbase) 00025 00026 B::B() 00027 { 00028 assert (base == 0); 00029 } 00030 00031 B::B(const B &b) 00032 { 00033 unsigned index = &b - base; 00034 assert (index < N); 00035 cmask[omp_get_thread_num()] |= 1u << index; 00036 } 00037 00038 B::~B() 00039 { 00040 if (threadbase) 00041 { 00042 unsigned index = this - threadbase; 00043 assert (index < N); 00044 dmask[omp_get_thread_num()] |= 1u << index; 00045 } 00046 } 00047 00048 void foo() 00049 { 00050 B b[N]; 00051 00052 base = b; 00053 00054 #pragma omp parallel firstprivate(b) 00055 { 00056 assert (omp_get_num_threads () == THR); 00057 threadbase = b; 00058 } 00059 00060 threadbase = 0; 00061 } 00062 00063 int main() 00064 { 00065 omp_set_dynamic (0); 00066 omp_set_num_threads (THR); 00067 foo(); 00068 00069 for (int i = 0; i < THR; ++i) 00070 { 00071 unsigned xmask = (1u << N) - 1; 00072 assert (cmask[i] == xmask); 00073 assert (dmask[i] == xmask); 00074 } 00075 00076 return 0; 00077 }