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
31namespace vtk
32{
33namespace detail
34{
35namespace smp
36{
37
38template <typename T>
40{
41 typedef std::vector<T> TLS;
42 typedef typename TLS::iterator TLSIter;
44
45public:
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
73 class ItImpl : public vtkSMPThreadLocalImplAbstract<T>::ItImpl
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:
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
151private:
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
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.