VTK  9.4.20241223
vtkSMPThreadLocalBackend.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
4// Thread Specific Storage is implemented as a Hash Table, with the Thread Id
5// as the key and a Pointer to the data as the value. The Hash Table implements
6// Open Addressing with Linear Probing. A fixed-size array (HashTableArray) is
7// used as the hash table. The size of this array is allocated to be large
8// enough to store thread specific data for all the threads with a Load Factor
9// of 0.5. In case the number of threads changes dynamically and the current
10// array is not able to accommodate more entries, a new array is allocated that
11// is twice the size of the current array. To avoid rehashing and blocking the
12// threads, a rehash is not performed immediately. Instead, a linked list of
13// hash table arrays is maintained with the current array at the root and older
14// arrays along the list. All lookups are sequentially performed along the
15// linked list. If the root array does not have an entry, it is created for
16// faster lookup next time. The ThreadSpecific::GetStorage() function is thread
17// safe and only blocks when a new array needs to be allocated, which should be
18// rare.
19
20#ifndef OpenMPvtkSMPThreadLocalBackend_h
21#define OpenMPvtkSMPThreadLocalBackend_h
22
23#include "vtkCommonCoreModule.h" // For export macro
24#include "vtkSystemIncludes.h"
25
26#include <atomic>
27#include <omp.h>
28
29namespace vtk
30{
31namespace detail
32{
33namespace smp
34{
35namespace OpenMP
36{
37VTK_ABI_NAMESPACE_BEGIN
38
39typedef void* ThreadIdType;
40typedef vtkTypeUInt32 HashType;
41typedef void* StoragePointerType;
42
43struct Slot
44{
45 std::atomic<ThreadIdType> ThreadId;
46 omp_lock_t ModifyLock;
48
51
52private:
53 // not copyable
54 Slot(const Slot&);
55 void operator=(const Slot&);
56};
57
59{
60 size_t Size, SizeLg;
61 std::atomic<size_t> NumberOfEntries;
64
65 explicit HashTableArray(size_t sizeLg);
67
68private:
69 // disallow copying
71 void operator=(const HashTableArray&);
72};
73
74class VTKCOMMONCORE_EXPORT ThreadSpecific final
75{
76public:
77 explicit ThreadSpecific(unsigned numThreads);
79
81 size_t Size() const;
82
83private:
84 std::atomic<HashTableArray*> Root;
85 std::atomic<size_t> Count;
86
88};
89
90inline size_t ThreadSpecific::Size() const
91{
92 return this->Count;
93}
94
96{
97public:
99 : ThreadSpecificStorage(nullptr)
100 , CurrentArray(nullptr)
101 , CurrentSlot(0)
102 {
103 }
104
106 {
107 this->ThreadSpecificStorage = &threadSpecifc;
108 }
109
111 {
112 this->CurrentArray = this->ThreadSpecificStorage->Root;
113 this->CurrentSlot = 0;
114 if (!this->CurrentArray->Slots->Storage)
115 {
116 this->Forward();
117 }
118 }
119
120 void SetToEnd()
121 {
122 this->CurrentArray = nullptr;
123 this->CurrentSlot = 0;
124 }
125
126 bool GetInitialized() const { return this->ThreadSpecificStorage != nullptr; }
127
128 bool GetAtEnd() const { return this->CurrentArray == nullptr; }
129
130 void Forward()
131 {
132 for (;;)
133 {
134 if (++this->CurrentSlot >= this->CurrentArray->Size)
135 {
136 this->CurrentArray = this->CurrentArray->Prev;
137 this->CurrentSlot = 0;
138 if (!this->CurrentArray)
139 {
140 break;
141 }
142 }
143 Slot* slot = this->CurrentArray->Slots + this->CurrentSlot;
144 if (slot->Storage)
145 {
146 break;
147 }
148 }
149 }
150
152 {
153 Slot* slot = this->CurrentArray->Slots + this->CurrentSlot;
154 return slot->Storage;
155 }
156
158 {
159 return (this->ThreadSpecificStorage == it.ThreadSpecificStorage) &&
160 (this->CurrentArray == it.CurrentArray) && (this->CurrentSlot == it.CurrentSlot);
161 }
162
163private:
164 ThreadSpecific* ThreadSpecificStorage;
165 HashTableArray* CurrentArray;
166 size_t CurrentSlot;
167};
168
169VTK_ABI_NAMESPACE_END
170} // OpenMP;
171} // namespace smp
172} // namespace detail
173} // namespace vtk
174
175#endif
176/* VTK-HeaderTest-Exclude: vtkSMPThreadLocalBackend.h */
bool operator==(const ThreadSpecificStorageIterator &it) const
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
std::atomic< ThreadIdType > ThreadId