VTK  9.1.0
vtkSMPThreadLocalImpl.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkSMPThreadLocalImpl.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 =========================================================================*/
15 // .NAME vtkSMPThreadLocal - A simple thread local implementation for sequential operations.
16 // .SECTION Description
17 //
18 // Note that this particular implementation is designed to work in sequential
19 // mode and supports only 1 thread.
20 
21 #ifndef SequentialvtkSMPThreadLocalImpl_h
22 #define SequentialvtkSMPThreadLocalImpl_h
23 
25 #include "vtkSystemIncludes.h"
26 
27 #include <iterator>
28 #include <utility> // For std::move
29 #include <vector>
30 
31 namespace vtk
32 {
33 namespace detail
34 {
35 namespace smp
36 {
37 
38 template <typename T>
40 {
41  typedef std::vector<T> TLS;
42  typedef typename TLS::iterator TLSIter;
44 
45 public:
47  : NumInitialized(0)
48  {
49  this->Initialize();
50  }
51 
52  explicit vtkSMPThreadLocalImpl(const T& exemplar)
53  : NumInitialized(0)
54  , Exemplar(exemplar)
55  {
56  this->Initialize();
57  }
58 
59  T& Local() override
60  {
61  int tid = this->GetThreadID();
62  if (!this->Initialized[tid])
63  {
64  this->Internal[tid] = this->Exemplar;
65  this->Initialized[tid] = true;
66  ++this->NumInitialized;
67  }
68  return this->Internal[tid];
69  }
70 
71  size_t size() const override { return this->NumInitialized; }
72 
74  {
75  public:
76  void Increment() override
77  {
78  this->InitIter++;
79  this->Iter++;
80 
81  // Make sure to skip uninitialized
82  // entries.
83  while (this->InitIter != this->EndIter)
84  {
85  if (*this->InitIter)
86  {
87  break;
88  }
89  this->InitIter++;
90  this->Iter++;
91  }
92  }
93 
94  bool Compare(ItImplAbstract* other) override
95  {
96  return this->Iter == static_cast<ItImpl*>(other)->Iter;
97  }
98 
99  T& GetContent() override { return *this->Iter; }
100 
101  T* GetContentPtr() override { return &*this->Iter; }
102 
103  protected:
104  virtual ItImpl* CloneImpl() const override { return new ItImpl(*this); };
105 
106  private:
107  friend class vtkSMPThreadLocalImpl<BackendType::Sequential, T>;
108  std::vector<bool>::iterator InitIter;
109  std::vector<bool>::iterator EndIter;
110  TLSIter Iter;
111  };
112 
113  std::unique_ptr<ItImplAbstract> begin() override
114  {
115  TLSIter iter = this->Internal.begin();
116  std::vector<bool>::iterator iter2 = this->Initialized.begin();
117  std::vector<bool>::iterator enditer = this->Initialized.end();
118  // fast forward to first initialized
119  // value
120  while (iter2 != enditer)
121  {
122  if (*iter2)
123  {
124  break;
125  }
126  iter2++;
127  iter++;
128  }
129  // XXX(c++14): use std::make_unique
130  auto retVal = std::unique_ptr<ItImpl>(new ItImpl());
131  retVal->InitIter = iter2;
132  retVal->EndIter = enditer;
133  retVal->Iter = iter;
134  // XXX(c++14): remove std::move and cast variable
135  std::unique_ptr<ItImplAbstract> abstractIt(std::move(retVal));
136  return abstractIt;
137  };
138 
139  std::unique_ptr<ItImplAbstract> end() override
140  {
141  // XXX(c++14): use std::make_unique
142  auto retVal = std::unique_ptr<ItImpl>(new ItImpl());
143  retVal->InitIter = this->Initialized.end();
144  retVal->EndIter = this->Initialized.end();
145  retVal->Iter = this->Internal.end();
146  // XXX(c++14): remove std::move and cast variable
147  std::unique_ptr<ItImplAbstract> abstractIt(std::move(retVal));
148  return abstractIt;
149  }
150 
151 private:
152  TLS Internal;
153  std::vector<bool> Initialized;
154  size_t NumInitialized;
155  T Exemplar;
156 
157  void Initialize()
158  {
159  this->Internal.resize(this->GetNumberOfThreads());
160  this->Initialized.resize(this->GetNumberOfThreads());
161  std::fill(this->Initialized.begin(), this->Initialized.end(), false);
162  }
163 
164  inline int GetNumberOfThreads() { return 1; }
165 
166  inline int GetThreadID() { return 0; }
167 
168  // disable copying
169  vtkSMPThreadLocalImpl(const vtkSMPThreadLocalImpl&) = delete;
170  void operator=(const vtkSMPThreadLocalImpl&) = delete;
171 };
172 
173 } // namespace smp
174 } // namespace detail
175 } // namespace vtk
176 
177 #endif
virtual std::unique_ptr< ItImpl > begin()=0
@ vector
Definition: vtkX3D.h:243
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.