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& operator=(const B &); 00013 }; 00014 00015 static B *base; 00016 static B *threadbase; 00017 static int singlethread; 00018 #pragma omp threadprivate(threadbase) 00019 00020 static unsigned cmask[THR]; 00021 00022 B& B::operator= (const B &b) 00023 { 00024 unsigned sindex = &b - base; 00025 unsigned tindex = this - threadbase; 00026 assert(sindex < N); 00027 assert(sindex == tindex); 00028 cmask[omp_get_thread_num ()] |= 1u << tindex; 00029 return *this; 00030 } 00031 00032 void foo() 00033 { 00034 #pragma omp parallel 00035 { 00036 B b[N]; 00037 threadbase = b; 00038 #pragma omp single copyprivate(b) 00039 { 00040 assert(omp_get_num_threads () == THR); 00041 singlethread = omp_get_thread_num (); 00042 base = b; 00043 } 00044 } 00045 } 00046 00047 int main() 00048 { 00049 omp_set_dynamic (0); 00050 omp_set_num_threads (THR); 00051 foo(); 00052 00053 for (int i = 0; i < THR; ++i) 00054 if (i == singlethread) 00055 assert(cmask[singlethread] == 0); 00056 else 00057 assert(cmask[i] == (1u << N) - 1); 00058 00059 return 0; 00060 }