VTK  9.3.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  // XXX(c++14): use std::make_unique
119  auto retVal = std::unique_ptr<ItImpl>(new ItImpl());
120  retVal->InitIter = iter2;
121  retVal->EndIter = enditer;
122  retVal->Iter = iter;
123  // XXX(c++14): remove std::move and cast variable
124  std::unique_ptr<ItImplAbstract> abstractIt(std::move(retVal));
125  return abstractIt;
126  };
127 
128  std::unique_ptr<ItImplAbstract> end() override
129  {
130  // XXX(c++14): use std::make_unique
131  auto retVal = std::unique_ptr<ItImpl>(new ItImpl());
132  retVal->InitIter = this->Initialized.end();
133  retVal->EndIter = this->Initialized.end();
134  retVal->Iter = this->Internal.end();
135  // XXX(c++14): remove std::move and cast variable
136  std::unique_ptr<ItImplAbstract> abstractIt(std::move(retVal));
137  return abstractIt;
138  }
139 
140 private:
141  TLS Internal;
142  std::vector<bool> Initialized;
143  size_t NumInitialized;
144  T Exemplar;
145 
146  void Initialize()
147  {
148  this->Internal.resize(this->GetNumberOfThreads());
149  this->Initialized.resize(this->GetNumberOfThreads());
150  std::fill(this->Initialized.begin(), this->Initialized.end(), false);
151  }
152 
153  inline int GetNumberOfThreads() { return 1; }
154 
155  inline int GetThreadID() { return 0; }
156 
157  // disable copying
158  vtkSMPThreadLocalImpl(const vtkSMPThreadLocalImpl&) = delete;
159  void operator=(const vtkSMPThreadLocalImpl&) = delete;
160 };
161 
162 VTK_ABI_NAMESPACE_END
163 } // namespace smp
164 } // namespace detail
165 } // namespace vtk
166 
167 #endif
168 /* VTK-HeaderTest-Exclude: vtkSMPThreadLocalImpl.h */
virtual std::unique_ptr< ItImpl > begin()=0
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.