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