VTK
vtkSMPThreadLocal.h
Go to the documentation of this file.
1  /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkSMPThreadLocal.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
41 #ifndef vtkSMPThreadLocal_h
42 #define vtkSMPThreadLocal_h
43 
44 #include "vtkSystemIncludes.h"
45 
46 #include <vector>
47 
48 template <typename T>
50 {
51  typedef std::vector<T> TLS;
52  typedef typename TLS::iterator TLSIter;
53 public:
55 
56  vtkSMPThreadLocal() : NumInitialized(0)
57  {
58  this->Initialize();
59  }
61 
63 
66  explicit vtkSMPThreadLocal(const T& exemplar)
67  : NumInitialized(0), Exemplar(exemplar)
68  {
69  this->Initialize();
70  }
72 
74 
81  T& Local()
82  {
83  int tid = this->GetThreadID();
84  if (!this->Initialized[tid])
85  {
86  this->Internal[tid] = this->Exemplar;
87  this->Initialized[tid] = true;
88  ++this->NumInitialized;
89  }
90  return this->Internal[tid];
91  }
93 
95 
96  size_t size() const
97  {
98  return this->NumInitialized;
99  }
101 
103 
108  class iterator
109  {
110  public:
112  {
113  this->InitIter++;
114  this->Iter++;
116 
117  // Make sure to skip uninitialized
118  // entries.
119  while(this->InitIter != this->EndIter)
120  {
121  if (*this->InitIter)
122  {
123  break;
124  }
125  this->InitIter++;
126  this->Iter++;
127  }
128  return *this;
129  }
130 
132  {
133  iterator copy = *this;
134  ++(*this);
135  return copy;
136  }
137 
138  bool operator==(const iterator& other)
139  {
140  return this->Iter == other.Iter;
141  }
142 
143  bool operator!=(const iterator& other)
144  {
145  return this->Iter != other.Iter;
146  }
147 
149  {
150  return *this->Iter;
151  }
152 
154  {
155  return &*this->Iter;
156  }
157 
158  private:
159  friend class vtkSMPThreadLocal<T>;
160  std::vector<bool>::iterator InitIter;
161  std::vector<bool>::iterator EndIter;
162  TLSIter Iter;
163  };
164 
166 
168  iterator begin()
169  {
170  TLSIter iter = this->Internal.begin();
171  std::vector<bool>::iterator iter2 =
172  this->Initialized.begin();
173  std::vector<bool>::iterator enditer =
174  this->Initialized.end();
175  // fast forward to first initialized
176  // value
177  while(iter2 != enditer)
178  {
179  if (*iter2)
180  {
181  break;
182  }
183  iter2++;
184  iter++;
185  }
186  iterator retVal;
187  retVal.InitIter = iter2;
188  retVal.EndIter = enditer;
189  retVal.Iter = iter;
190  return retVal;
191  };
193 
195 
197  iterator end()
198  {
199  iterator retVal;
200  retVal.InitIter = this->Initialized.end();
201  retVal.EndIter = this->Initialized.end();
202  retVal.Iter = this->Internal.end();
203  return retVal;
204  }
206 
207 private:
208  TLS Internal;
209  std::vector<bool> Initialized;
210  size_t NumInitialized;
211  T Exemplar;
212 
213  void Initialize()
214  {
215  this->Internal.resize(this->GetNumberOfThreads());
216  this->Initialized.resize(this->GetNumberOfThreads());
217  std::fill(this->Initialized.begin(),
218  this->Initialized.end(),
219  false);
220  }
221 
222  inline int GetNumberOfThreads()
223  {
224  return 1;
225  }
226 
227  inline int GetThreadID()
228  {
229  return 0;
230  }
231 
232  // disable copying
234  void operator=(const vtkSMPThreadLocal&);
235 };
236 #endif
237 // VTK-HeaderTest-Exclude: vtkSMPThreadLocal.h
vtkSMPThreadLocal(const T &exemplar)
bool operator!=(const iterator &other)
bool operator==(const iterator &other)
A simple thread local implementation for sequential operations.
size_t size() const