VTK  9.4.20241218
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
19namespace vtk
20{
21namespace detail
22{
23namespace smp
24{
25VTK_ABI_NAMESPACE_BEGIN
26
27template <typename T>
29{
30 typedef std::vector<T> TLS;
31 typedef typename TLS::iterator TLSIter;
33
34public:
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
62 class ItImpl : public vtkSMPThreadLocalImplAbstract<T>::ItImpl
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
140private:
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
162VTK_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.