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 =========================================================================*/ 00044 #ifndef vtkSMPThreadLocal_h 00045 #define vtkSMPThreadLocal_h 00046 00047 #include "vtkSystemIncludes.h" 00048 00049 #include <vector> 00050 00051 template <typename T> 00052 class vtkSMPThreadLocal 00053 { 00054 typedef std::vector<T> TLS; 00055 typedef typename TLS::iterator TLSIter; 00056 public: 00058 00059 vtkSMPThreadLocal() : NumInitialized(0) 00060 { 00061 this->Initialize(); 00062 } 00064 00066 00069 vtkSMPThreadLocal(const T& exemplar) : NumInitialized(0), Exemplar(exemplar) 00070 { 00071 this->Initialize(); 00072 } 00074 00076 00083 T& Local() 00084 { 00085 int tid = this->GetThreadID(); 00086 if (!this->Initialized[tid]) 00087 { 00088 this->Internal[tid] = this->Exemplar; 00089 this->Initialized[tid] = true; 00090 ++this->NumInitialized; 00091 } 00092 return this->Internal[tid]; 00093 } 00095 00097 00098 size_t size() const 00099 { 00100 return this->NumInitialized; 00101 } 00103 00105 00110 class iterator 00111 { 00112 public: 00113 iterator& operator++() 00114 { 00115 this->InitIter++; 00116 this->Iter++; 00118 00119 // Make sure to skip uninitialized 00120 // entries. 00121 while(this->InitIter != this->EndIter) 00122 { 00123 if (*this->InitIter) 00124 { 00125 break; 00126 } 00127 this->InitIter++; 00128 this->Iter++; 00129 } 00130 return *this; 00131 } 00132 00133 iterator operator++(int) 00134 { 00135 iterator copy = *this; 00136 ++(*this); 00137 return copy; 00138 } 00139 00140 bool operator==(const iterator& other) 00141 { 00142 return this->Iter == other.Iter; 00143 } 00144 00145 bool operator!=(const iterator& other) 00146 { 00147 return this->Iter != other.Iter; 00148 } 00149 00150 T& operator*() 00151 { 00152 return *this->Iter; 00153 } 00154 00155 T* operator->() 00156 { 00157 return &*this->Iter; 00158 } 00159 00160 private: 00161 friend class vtkSMPThreadLocal<T>; 00162 std::vector<bool>::iterator InitIter; 00163 std::vector<bool>::iterator EndIter; 00164 TLSIter Iter; 00165 }; 00166 00168 00170 iterator begin() 00171 { 00172 TLSIter iter = this->Internal.begin(); 00173 std::vector<bool>::iterator iter2 = 00174 this->Initialized.begin(); 00175 std::vector<bool>::iterator enditer = 00176 this->Initialized.end(); 00177 // fast forward to first initialized 00178 // value 00179 while(iter2 != enditer) 00180 { 00181 if (*iter2) 00182 { 00183 break; 00184 } 00185 iter2++; 00186 iter++; 00187 } 00188 iterator retVal; 00189 retVal.InitIter = iter2; 00190 retVal.EndIter = enditer; 00191 retVal.Iter = iter; 00192 return retVal; 00193 }; 00195 00197 00199 iterator end() 00200 { 00201 iterator retVal; 00202 retVal.InitIter = this->Initialized.end(); 00203 retVal.EndIter = this->Initialized.end(); 00204 retVal.Iter = this->Internal.end(); 00205 return retVal; 00206 } 00208 00209 private: 00210 TLS Internal; 00211 std::vector<bool> Initialized; 00212 size_t NumInitialized; 00213 T Exemplar; 00214 00215 void Initialize() 00216 { 00217 this->Internal.resize(this->GetNumberOfThreads()); 00218 this->Initialized.resize(this->GetNumberOfThreads()); 00219 std::fill(this->Initialized.begin(), 00220 this->Initialized.end(), 00221 false); 00222 } 00223 00224 inline int GetNumberOfThreads() 00225 { 00226 return 1; 00227 } 00228 00229 inline int GetThreadID() 00230 { 00231 return 0; 00232 } 00233 }; 00234 #endif 00235 // VTK-HeaderTest-Exclude: vtkSMPThreadLocal.h