VTK
dox/Builds/VTK/release/doxygen/Common/Core/vtkSMPThreadLocal.h
Go to the documentation of this file.
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