VTK
|
00001 /*========================================================================= 00002 00003 Program: Visualization Toolkit 00004 Module: vtkSMPThreadLocal.h 00005 00006 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 00007 All rights reserved. 00008 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 00009 00010 This software is distributed WITHOUT ANY WARRANTY; without even 00011 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00012 PURPOSE. See the above copyright notice for more information. 00013 00014 =========================================================================*/ 00041 #ifndef __vtkSMPThreadLocal_h 00042 #define __vtkSMPThreadLocal_h 00043 00044 #include "vtkSystemIncludes.h" 00045 #include <vector> 00046 00047 template <typename T> 00048 class vtkSMPThreadLocal 00049 { 00050 typedef std::vector<T> TLS; 00051 typedef typename TLS::iterator TLSIter; 00052 public: 00054 00055 vtkSMPThreadLocal() 00056 { 00057 this->Initialize(); 00058 } 00060 00062 00065 vtkSMPThreadLocal(const T& exemplar) : Exemplar(exemplar) 00066 { 00067 this->Initialize(); 00068 } 00070 00072 00079 T& Local() 00080 { 00081 int tid = this->GetThreadID(); 00082 if (!this->Initialized[tid]) 00083 { 00084 this->Internal[tid] = this->Exemplar; 00085 this->Initialized[tid] = true; 00086 } 00087 return this->Internal[tid]; 00088 } 00090 00092 00097 class iterator 00098 { 00099 public: 00100 iterator& operator++() 00101 { 00102 this->InitIter++; 00103 this->Iter++; 00105 00106 // Make sure to skip uninitialized 00107 // entries. 00108 while(this->InitIter != this->EndIter) 00109 { 00110 if (*this->InitIter) 00111 { 00112 break; 00113 } 00114 this->InitIter++; 00115 this->Iter++; 00116 } 00117 return *this; 00118 } 00119 00120 bool operator!=(const iterator& other) 00121 { 00122 return this->Iter != other.Iter; 00123 } 00124 00125 T& operator*() 00126 { 00127 return *this->Iter; 00128 } 00129 00130 private: 00131 friend class vtkSMPThreadLocal<T>; 00132 std::vector<bool>::iterator InitIter; 00133 std::vector<bool>::iterator EndIter; 00134 TLSIter Iter; 00135 }; 00136 00138 00140 iterator begin() 00141 { 00142 TLSIter iter = this->Internal.begin(); 00143 std::vector<bool>::iterator iter2 = 00144 this->Initialized.begin(); 00145 std::vector<bool>::iterator enditer = 00146 this->Initialized.end(); 00147 // fast forward to first initialized 00148 // value 00149 while(iter2 != enditer) 00150 { 00151 if (*iter2) 00152 { 00153 break; 00154 } 00155 iter2++; 00156 iter++; 00157 } 00158 iterator retVal; 00159 retVal.InitIter = iter2; 00160 retVal.EndIter = enditer; 00161 retVal.Iter = iter; 00162 return retVal; 00163 }; 00165 00167 00169 iterator end() 00170 { 00171 iterator retVal; 00172 retVal.InitIter = this->Initialized.end(); 00173 retVal.EndIter = this->Initialized.end(); 00174 retVal.Iter = this->Internal.end(); 00175 return retVal; 00176 } 00178 00179 private: 00180 TLS Internal; 00181 std::vector<bool> Initialized; 00182 T Exemplar; 00183 00184 void Initialize() 00185 { 00186 this->Internal.resize(this->GetNumberOfThreads()); 00187 this->Initialized.resize(this->GetNumberOfThreads()); 00188 std::fill(this->Initialized.begin(), 00189 this->Initialized.end(), 00190 false); 00191 } 00192 00193 inline int GetNumberOfThreads() 00194 { 00195 return 1; 00196 } 00197 00198 inline int GetThreadID() 00199 { 00200 return 0; 00201 } 00202 }; 00203 #endif 00204 // VTK-HeaderTest-Exclude: vtkSMPThreadLocal.h