VTK  9.4.20241118
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 vtkSMPThreadLocalImpl - A thread local storage implementation using
4// platform specific facilities.
5
6#ifndef OpenMPvtkSMPThreadLocalImpl_h
7#define OpenMPvtkSMPThreadLocalImpl_h
8
11#include "SMP/OpenMP/vtkSMPToolsImpl.txx"
12
13#include <iterator>
14#include <utility> // For std::move
15
16namespace vtk
17{
18namespace detail
19{
20namespace smp
21{
22VTK_ABI_NAMESPACE_BEGIN
23
24template <typename T>
26{
28
29public:
31 : Backend(GetNumberOfThreadsOpenMP())
32 {
33 }
34
35 explicit vtkSMPThreadLocalImpl(const T& exemplar)
36 : Backend(GetNumberOfThreadsOpenMP())
37 , Exemplar(exemplar)
38 {
39 }
40
42 {
44 it.SetThreadSpecificStorage(Backend);
45 for (it.SetToBegin(); !it.GetAtEnd(); it.Forward())
46 {
47 delete reinterpret_cast<T*>(it.GetStorage());
48 }
49 }
50
51 T& Local() override
52 {
53 OpenMP::StoragePointerType& ptr = this->Backend.GetStorage();
54 T* local = reinterpret_cast<T*>(ptr);
55 if (!ptr)
56 {
57 ptr = local = new T(this->Exemplar);
58 }
59 return *local;
60 }
61
62 size_t size() const override { return this->Backend.Size(); }
63
64 class ItImpl : public vtkSMPThreadLocalImplAbstract<T>::ItImpl
65 {
66 public:
67 void Increment() override { this->Impl.Forward(); }
68
69 bool Compare(ItImplAbstract* other) override
70 {
71 return this->Impl == static_cast<ItImpl*>(other)->Impl;
72 }
73
74 T& GetContent() override { return *reinterpret_cast<T*>(this->Impl.GetStorage()); }
75
76 T* GetContentPtr() override { return reinterpret_cast<T*>(this->Impl.GetStorage()); }
77
78 protected:
79 ItImpl* CloneImpl() const override { return new ItImpl(*this); };
80
81 private:
83
85 };
86
87 std::unique_ptr<ItImplAbstract> begin() override
88 {
89 // XXX(c++14): use std::make_unique
90 auto it = std::unique_ptr<ItImpl>(new ItImpl());
91 it->Impl.SetThreadSpecificStorage(this->Backend);
92 it->Impl.SetToBegin();
93 // XXX(c++14): remove std::move and cast variable
94 std::unique_ptr<ItImplAbstract> abstractIt(std::move(it));
95 return abstractIt;
96 }
97
98 std::unique_ptr<ItImplAbstract> end() override
99 {
100 // XXX(c++14): use std::make_unique
101 auto it = std::unique_ptr<ItImpl>(new ItImpl());
102 it->Impl.SetThreadSpecificStorage(this->Backend);
103 it->Impl.SetToEnd();
104 // XXX(c++14): remove std::move and cast variable
105 std::unique_ptr<ItImplAbstract> abstractIt(std::move(it));
106 return abstractIt;
107 }
108
109private:
111 T Exemplar;
112
113 // disable copying
115 void operator=(const vtkSMPThreadLocalImpl&) = delete;
116};
117
118VTK_ABI_NAMESPACE_END
119} // namespace smp
120} // namespace detail
121} // namespace vtk
122
123#endif
124/* VTK-HeaderTest-Exclude: vtkSMPThreadLocalImpl.h */
virtual std::unique_ptr< ItImpl > begin()=0
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.