Main Page Class List Class Members

NvBlastTkEventQueue.h
Go to the documentation of this file.
1 // This code contains NVIDIA Confidential Information and is disclosed to you
2 // under a form of NVIDIA software license agreement provided separately to you.
3 //
4 // Notice
5 // NVIDIA Corporation and its licensors retain all intellectual property and
6 // proprietary rights in and to this software and related documentation and
7 // any modifications thereto. Any use, reproduction, disclosure, or
8 // distribution of this software and related documentation without an express
9 // license agreement from NVIDIA Corporation is strictly prohibited.
10 //
11 // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
12 // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
13 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
14 // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
15 //
16 // Information and code furnished is believed to be accurate and reliable.
17 // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
18 // information or for any infringement of patents or other rights of third parties that may
19 // result from its use. No license is granted by implication or otherwise under any patent
20 // or patent rights of NVIDIA Corporation. Details are subject to change without notice.
21 // This code supersedes and replaces all information previously supplied.
22 // NVIDIA Corporation products are not authorized for use as critical
23 // components in life support devices or systems without express written approval of
24 // NVIDIA Corporation.
25 //
26 // Copyright (c) 2016-2020 NVIDIA Corporation. All rights reserved.
27
28
29 #ifndef NVBLASTTKEVENTQUEUE_H
30 #define NVBLASTTKEVENTQUEUE_H
31
32 #include <algorithm>
33 #include <vector>
34
35 #include <mutex>
36 #include <atomic>
37
38 #include "NvBlastTkFrameworkImpl.h"
39 #include "NvBlastAssert.h"
40
41
42 namespace Nv {
43 namespace Blast {
44
61 class TkEventQueue
62 {
63 public:
64 TkEventQueue() : m_currentEvent(0), m_poolCapacity(0), m_pool(nullptr), m_allowAllocs(true) {}
65
70 operator const Array<TkEvent>::type&()
71 {
72 NVBLAST_ASSERT(m_allowAllocs);
73 NVBLAST_ASSERT(m_currentEvent == m_events.size());
74 return m_events;
75 }
76
84 void protect(bool enable)
85 {
86 // During parallel use, m_events.size() and m_currentEvent are allowed to diverge.
87 // This is fine because resizeUninitialized does not alter the stored data.
88 NVBLAST_ASSERT(m_currentEvent <= m_events.capacity());
89 m_events.resizeUninitialized(m_currentEvent);
90 m_allowAllocs = !enable;
91 }
92
97 void reset()
98 {
99 m_events.clear();
100 m_currentEvent = 0;
101 for (void* mem : m_memory)
102 {
103 NVBLAST_FREE(mem);
104 }
105 m_memory.clear();
106 m_currentData = 0;
107 m_allowAllocs = true;
108 m_poolCapacity = 0;
109 m_pool = nullptr;
110 }
111
115 template<class T>
116 void addEvent(T* payload)
117 {
118 uint32_t index = m_currentEvent.fetch_add(1);
119
120 // Should not allocate in protected state.
121 NVBLAST_ASSERT(m_allowAllocs || m_currentEvent <= m_events.capacity());
122
123 m_events.resizeUninitialized(m_currentEvent);
124
125 // During parallel use, m_events.size() and m_currentEvent are allowed to diverge.
126 // Consistency is restored in protect().
127 NVBLAST_ASSERT(!m_allowAllocs || m_currentEvent == m_events.size());
128
129 TkEvent& evt = m_events[index];
130 evt.type = TkEvent::Type(T::EVENT_TYPE);
131 evt.payload = payload;
132 }
133
137 template<typename T>
138 T* allocData()
139 {
140 uint32_t index = m_currentData.fetch_add(sizeof(T));
141 if (m_currentData <= m_poolCapacity)
142 {
143 return reinterpret_cast<T*>(&m_pool[index]);
144 }
145 else
146 {
147 // Could do larger block allocation here.
148 reserveData(sizeof(T));
149 // Account for the requested size.
150 m_currentData = sizeof(T);
151 return reinterpret_cast<T*>(&m_pool[0]);
152 }
153 }
154
160 void reserveData(size_t size)
161 {
162 NVBLAST_ASSERT(m_allowAllocs);
163 m_pool = reinterpret_cast<uint8_t*>(allocDataBySize(size));
164 m_poolCapacity = size;
165 m_currentData = 0;
166 }
167
171 void reserveEvents(uint32_t n)
172 {
173 NVBLAST_ASSERT(m_allowAllocs);
174 m_events.reserve(m_events.size() + n);
175 }
176
180 void addListener(TkEventListener& l)
181 {
182 m_listeners.pushBack(&l);
183 }
184
188 void removeListener(TkEventListener& l)
189 {
190 m_listeners.findAndReplaceWithLast(&l);
191 }
192
197 void dispatch()
198 {
199 dispatch(*this);
200 reset();
201 }
202
206 void dispatch(const Array<TkEvent>::type& events) const
207 {
208 if (events.size())
209 {
210 for (TkEventListener* l : m_listeners)
211 {
212 BLAST_PROFILE_SCOPE_M("TkEventQueue::dispatch");
213 l->receive(events.begin(), events.size());
214 }
215 }
216 }
217
218 private:
222 void* allocDataBySize(size_t size)
223 {
224 void* memory = nullptr;
225 if (size > 0)
226 {
227 memory = NVBLAST_ALLOC_NAMED(size, "TkEventQueue Data");
228 m_memory.pushBack(memory);
229 }
230 return memory;
231 }
232
233
234 Array<TkEvent>::type m_events;
235 Array<void*>::type m_memory;
236 std::atomic<uint32_t> m_currentEvent;
237 std::atomic<uint32_t> m_currentData;
238 size_t m_poolCapacity;
239 uint8_t* m_pool;
240 bool m_allowAllocs;
241 InlineArray<TkEventListener*,4>::type m_listeners;
242 };
243
244 } // namespace Blast
245 } // namespace Nv
246
247
248 #endif // ifndef NVBLASTTKEVENTQUEUE_H
Nv::Blast::TkEventQueue::addListener
void addListener(TkEventListener &l)
Definition: NvBlastTkEventQueue.h:180
Nv::Blast::InlineArray::type
physx::shdfnd::InlineArray< T, N, Allocator > type
Definition: NvBlastArray.h:60
Nv::Blast::TkEventQueue::reserveData
void reserveData(size_t size)
Definition: NvBlastTkEventQueue.h:160
Nv::Blast::TkEvent
Definition: NvBlastTkEvent.h:65
Nv::Blast::Array::type
physx::shdfnd::Array< T, Allocator > type
Definition: NvBlastArray.h:48
Nv::Blast::TkEventQueue::dispatch
void dispatch(const Array< TkEvent >::type &events) const
Definition: NvBlastTkEventQueue.h:206
BLAST_PROFILE_SCOPE_M
#define BLAST_PROFILE_SCOPE_M(name)
Definition: NvBlastProfilerInternal.h:86
NVBLAST_ASSERT
#define NVBLAST_ASSERT(exp)
Definition: NvBlastAssert.h:37
Nv::Blast::TkEvent::Type
Type
Definition: NvBlastTkEvent.h:68
Nv::Blast::TkEventQueue::protect
void protect(bool enable)
Definition: NvBlastTkEventQueue.h:84
Nv::Blast::TkEventListener
Definition: NvBlastTkEvent.h:168
Nv::Blast::TkEventQueue::addEvent
void addEvent(T *payload)
Definition: NvBlastTkEventQueue.h:116
Nv::Blast::TkEventQueue
Definition: NvBlastTkEventQueue.h:61
NVBLAST_FREE
#define NVBLAST_FREE(_mem)
Definition: NvBlastGlobals.h:222
Nv::Blast::TkEventQueue::TkEventQueue
TkEventQueue()
Definition: NvBlastTkEventQueue.h:64
NVBLAST_ALLOC_NAMED
#define NVBLAST_ALLOC_NAMED(_size, _name)
Definition: NvBlastGlobals.h:221
NvBlastTkFrameworkImpl.h
Nv::Blast::TkEventQueue::allocData
T * allocData()
Definition: NvBlastTkEventQueue.h:138
Nv
Definition: NvBlastArray.h:37
NvBlastAssert.h
Nv::Blast::TkEventQueue::reserveEvents
void reserveEvents(uint32_t n)
Definition: NvBlastTkEventQueue.h:171
Nv::Blast::TkEventQueue::dispatch
void dispatch()
Definition: NvBlastTkEventQueue.h:197
Nv::Blast::TkEventQueue::removeListener
void removeListener(TkEventListener &l)
Definition: NvBlastTkEventQueue.h:188
Nv::Blast::TkEventQueue::reset
void reset()
Definition: NvBlastTkEventQueue.h:97