VTK  9.7.1
vtkSMPThreadLocalImpl.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 // .NAME vtkSMPThreadLocal - A simple thread local implementation for sequential operations.
4 // .SECTION Description
5 //
6 // Note that this particular implementation is designed to work in sequential
7 // mode and supports only 1 thread.
8 
9 #ifndef SequentialvtkSMPThreadLocalImpl_h
10 #define SequentialvtkSMPThreadLocalImpl_h
11 
13 #include "vtkSystemIncludes.h"
14 
15 #include <iterator>
16 #include <utility> // For std::move
17 #include <vector>
18 
19 namespace vtk
20 {
21 namespace detail
22 {
23 namespace smp
24 {
25 VTK_ABI_NAMESPACE_BEGIN
26 
27 template <typename T>
29 {
30  typedef std::vector<T> TLS;
31  typedef typename TLS::iterator TLSIter;
33 
34 public:
36  : NumInitialized(0)
37  {
38  this->Initialize();
39  }
40 
41  explicit vtkSMPThreadLocalImpl(const T& exemplar)
42  : NumInitialized(0)
43  , Exemplar(exemplar)
44  {
45  this->Initialize();
46  }
47 
48  T& Local() override
49  {
50  int tid = this->GetThreadID();
51  if (!this->Initialized[tid])
52  {
53  this->Internal[tid] = this->Exemplar;
54  this->Initialized[tid] = true;
55  ++this->NumInitialized;
56  }
57  return this->Internal[tid];
58  }
59 
60  size_t size() const override { return this->NumInitialized; }
61 
63  {
64  public:
65  void Increment() override
66  {
67  this->InitIter++;
68  this->Iter++;
69 
70  // Make sure to skip uninitialized
71  // entries.
72  while (this->InitIter != this->EndIter)
73  {
74  if (*this->InitIter)
75  {
76  break;
77  }
78  this->InitIter++;
79  this->Iter++;
80  }
81  }
82 
83  bool Compare(ItImplAbstract* other) override
84  {
85  return this->Iter == static_cast<ItImpl*>(other)->Iter;
86  }
87 
88  T& GetContent() override { return *this->Iter; }
89 
90  T* GetContentPtr() override { return &*this->Iter; }
91 
92  protected:
93  ItImpl* CloneImpl() const override { return new ItImpl(*this); }
94 
95  private:
97  std::vector<bool>::iterator InitIter;
98  std::vector<bool>::iterator EndIter;
99  TLSIter Iter;
100  };
101 
102  std::unique_ptr<ItImplAbstract> begin() override
103  {
104  TLSIter iter = this->Internal.begin();
105  std::vector<bool>::iterator iter2 = this->Initialized.begin();
106  std::vector<bool>::iterator enditer = this->Initialized.end();
107  // fast forward to first initialized
108  // value
109  while (iter2 != enditer)
110  {
111  if (*iter2)
112  {
113  break;
114  }
115  iter2++;
116  iter++;
117  }
118  auto retVal = std::make_unique<ItImpl>();
119  retVal->InitIter = iter2;
120  retVal->EndIter = enditer;
121  retVal->Iter = iter;
122  return retVal;
123  }
124 
125  std::unique_ptr<ItImplAbstract> end() override
126  {
127  auto retVal = std::make_unique<ItImpl>();
128  retVal->InitIter = this->Initialized.end();
129  retVal->EndIter = this->Initialized.end();
130  retVal->Iter = this->Internal.end();
131  return retVal;
132  }
133 
134 private:
135  TLS Internal;
136  std::vector<bool> Initialized;
137  size_t NumInitialized;
138  T Exemplar;
139 
140  void Initialize()
141  {
142  this->Internal.resize(this->GetNumberOfThreads());
143  this->Initialized.resize(this->GetNumberOfThreads());
144  std::fill(this->Initialized.begin(), this->Initialized.end(), false);
145  }
146 
147  int GetNumberOfThreads() { return 1; }
148 
149  int GetThreadID() { return 0; }
150 
151  // disable copying
152  vtkSMPThreadLocalImpl(const vtkSMPThreadLocalImpl&) = delete;
153  void operator=(const vtkSMPThreadLocalImpl&) = delete;
154 };
155 
156 VTK_ABI_NAMESPACE_END
157 } // namespace smp
158 } // namespace detail
159 } // namespace vtk
160 
161 #endif
162 /* VTK-HeaderTest-Exclude: vtkSMPThreadLocalImpl.h */
virtual std::unique_ptr< ItImpl > begin()=0
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.