RavEngine
Loading...
Searching...
No Matches
PxProfileMemoryEvents.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef PX_PROFILE_MEMORY_EVENTS_H
30#define PX_PROFILE_MEMORY_EVENTS_H
31
32#include "PxProfileEvents.h"
33
34//Memory events define their own event stream
35
36namespace physx { namespace profile {
38 {
39 enum Enum
40 {
41 Unknown = 0,
42 StringTableEvent, //introduce a new mapping of const char* -> integer
46 };
47 };
48
49 template<unsigned numBits, typename TDataType>
50 inline unsigned char convertToNBits( TDataType inType )
51 {
52 uint8_t conversion = static_cast<uint8_t>( inType );
53 PX_ASSERT( conversion < (1 << numBits) );
54 return conversion;
55 }
56
57 template<typename TDataType>
58 inline unsigned char convertToTwoBits( TDataType inType )
59 {
60 return convertToNBits<2>( inType );
61 }
62
63 template<typename TDataType>
64 inline unsigned char convertToFourBits( TDataType inType )
65 {
66 return convertToNBits<4>( inType );
67 }
68
69 inline EventStreamCompressionFlags::Enum fromNumber( uint8_t inNum ) { return static_cast<EventStreamCompressionFlags::Enum>( inNum ); }
70
71 template<unsigned lhs, unsigned rhs>
72 inline void compileCheckSize()
73 {
74 PX_COMPILE_TIME_ASSERT( lhs <= rhs );
75 }
76
77 //Used for predictable bit fields.
78 template<typename TDataType
79 , uint8_t TNumBits
80 , uint8_t TOffset
81 , typename TInputType>
83 {
84 //Create a mask that masks out the orginal value shift into place
85 static TDataType createOffsetMask() { return TDataType(createMask() << TOffset); }
86 //Create a mask of TNumBits number of tis
87 static TDataType createMask() { return static_cast<TDataType>((1 << TNumBits) - 1); }
88 void setValue( TDataType& inCurrent, TInputType inData )
89 {
90 PX_ASSERT( inData < ( 1 << TNumBits ) );
91
92 //Create a mask to remove the current value.
93 TDataType theMask = TDataType(~(createOffsetMask()));
94 //Clear out current value.
95 inCurrent = TDataType(inCurrent & theMask);
96 //Create the new value.
97 TDataType theAddition = static_cast<TDataType>( inData << TOffset );
98 //or it into the existing value.
99 inCurrent = TDataType(inCurrent | theAddition);
100 }
101
102 TInputType getValue( TDataType inCurrent )
103 {
104 return static_cast<TInputType>( ( inCurrent >> TOffset ) & createMask() );
105 }
106 };
107
108
110 {
111 uint16_t mValue;
112
119
120 //That leaves size as the only thing not compressed usually.
121
122 MemoryEventHeader( MemoryEventTypes::Enum inType = MemoryEventTypes::Unknown )
123 : mValue( 0 )
124 {
125 uint8_t defaultCompression( convertToTwoBits( EventStreamCompressionFlags::U64 ) );
126 TTypeBitmask().setValue( mValue, convertToFourBits( inType ) );
127 TAddrCompressBitmask().setValue( mValue, defaultCompression );
128 TTypeCompressBitmask().setValue( mValue, defaultCompression );
129 TFnameCompressBitmask().setValue( mValue, defaultCompression );
130 TSizeCompressBitmask().setValue( mValue, defaultCompression );
131 TLineCompressBitmask().setValue( mValue, defaultCompression );
132 }
133
134 MemoryEventTypes::Enum getType() const { return static_cast<MemoryEventTypes::Enum>( TTypeBitmask().getValue( mValue ) ); }
135
136#define DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( name ) \
137 void set##name( EventStreamCompressionFlags::Enum inEnum ) { T##name##Bitmask().setValue( mValue, convertToTwoBits( inEnum ) ); } \
138 EventStreamCompressionFlags::Enum get##name() const { return fromNumber( T##name##Bitmask().getValue( mValue ) ); }
139
140 DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( AddrCompress )
141 DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( TypeCompress )
142 DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( FnameCompress )
143 DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( SizeCompress )
144 DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( LineCompress )
145
146#undef DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR
147
148 bool operator==( const MemoryEventHeader& inOther ) const
149 {
150 return mValue == inOther.mValue;
151 }
152 template<typename TStreamType>
153 void streamify( TStreamType& inStream )
154 {
155 inStream.streamify( "Header", mValue );
156 }
157 };
158
159 //Declaration of type level getMemoryEventType function that maps enumeration event types to datatypes
160 template<typename TDataType>
161 inline MemoryEventTypes::Enum getMemoryEventType() { PX_ASSERT( false ); return MemoryEventTypes::Unknown; }
162
163 inline bool safeStrEq( const char* lhs, const char* rhs )
164 {
165 if ( lhs == rhs )
166 return true;
167 //If they aren't equal, and one of them is null,
168 //then they can't be equal.
169 //This is assuming that the null char* is not equal to
170 //the empty "" char*.
171 if ( !lhs || !rhs )
172 return false;
173
174 return ::strcmp( lhs, rhs ) == 0;
175 }
176
178 {
179 const char* mString;
180 uint32_t mHandle;
181
182 void init( const char* inStr = "", uint32_t inHdl = 0 )
183 {
184 mString = inStr;
185 mHandle = inHdl;
186 }
187
188 void init( const StringTableEvent& inData )
189 {
190 mString = inData.mString;
191 mHandle = inData.mHandle;
192 }
193
194 bool operator==( const StringTableEvent& inOther ) const
195 {
196 return mHandle == inOther.mHandle
197 && safeStrEq( mString, inOther.mString );
198 }
199
200 void setup( MemoryEventHeader& ) const {}
201
202 template<typename TStreamType>
203 void streamify( TStreamType& inStream, const MemoryEventHeader& )
204 {
205 inStream.streamify( "String", mString );
206 inStream.streamify( "Handle", mHandle );
207 }
208 };
209 template<> inline MemoryEventTypes::Enum getMemoryEventType<StringTableEvent>() { return MemoryEventTypes::StringTableEvent; }
210
212 {
213 uint64_t mAddress;
214 void init( uint64_t addr )
215 {
216 mAddress = addr;
217 }
218
219 void init( const MemoryEventData& inData)
220 {
221 mAddress = inData.mAddress;
222 }
223
224 bool operator==( const MemoryEventData& inOther ) const
225 {
226 return mAddress == inOther.mAddress;
227 }
228
229 void setup( MemoryEventHeader& inHeader ) const
230 {
231 inHeader.setAddrCompress( findCompressionValue( mAddress ) );
232 }
233
234 template<typename TStreamType>
235 void streamify( TStreamType& inStream, const MemoryEventHeader& inHeader )
236 {
237 inStream.streamify( "Address", mAddress, inHeader.getAddrCompress() );
238 }
239 };
240
242 {
243 uint32_t mSize;
244 uint32_t mType;
245 uint32_t mFile;
246 uint32_t mLine;
247 void init( size_t size = 0, uint32_t type = 0, uint32_t file = 0, uint32_t line = 0, uint64_t addr = 0 )
248 {
249 MemoryEventData::init( addr );
250 mSize = static_cast<uint32_t>( size );
251 mType = type;
252 mFile = file;
253 mLine = line;
254 }
255
256 void init( const AllocationEvent& inData )
257 {
258 MemoryEventData::init( inData );
259 mSize = inData.mSize;
260 mType = inData.mType;
261 mFile = inData.mFile;
262 mLine = inData.mLine;
263 }
264
265 bool operator==( const AllocationEvent& inOther ) const
266 {
267 return MemoryEventData::operator==( inOther )
268 && mSize == inOther.mSize
269 && mType == inOther.mType
270 && mFile == inOther.mFile
271 && mLine == inOther.mLine;
272 }
273
274 void setup( MemoryEventHeader& inHeader ) const
275 {
276 inHeader.setTypeCompress( findCompressionValue( mType ) );
277 inHeader.setFnameCompress( findCompressionValue( mFile ) );
278 inHeader.setSizeCompress( findCompressionValue( mSize ) );
279 inHeader.setLineCompress( findCompressionValue( mLine ) );
280 MemoryEventData::setup( inHeader );
281 }
282
283 template<typename TStreamType>
284 void streamify( TStreamType& inStream, const MemoryEventHeader& inHeader )
285 {
286 inStream.streamify( "Size", mSize, inHeader.getSizeCompress() );
287 inStream.streamify( "Type", mType, inHeader.getTypeCompress() );
288 inStream.streamify( "File", mFile, inHeader.getFnameCompress() );
289 inStream.streamify( "Line", mLine, inHeader.getLineCompress() );
290 MemoryEventData::streamify( inStream, inHeader );
291 }
292 };
293 template<> inline MemoryEventTypes::Enum getMemoryEventType<AllocationEvent>() { return MemoryEventTypes::AllocationEvent; }
294
295
297 {
298 size_t mSize;
299 const char* mType;
300 const char* mFile;
301 uint32_t mLine;
302 void init( size_t size, const char* type, const char* file, uint32_t line, uint64_t addr )
303 {
304 MemoryEventData::init( addr );
305 mSize = size;
306 mType = type;
307 mFile = file;
308 mLine = line;
309 }
310
311 void init( const FullAllocationEvent& inData )
312 {
313 MemoryEventData::init( inData );
314 mSize = inData.mSize;
315 mType = inData.mType;
316 mFile = inData.mFile;
317 mLine = inData.mLine;
318 }
319
320 bool operator==( const FullAllocationEvent& inOther ) const
321 {
322 return MemoryEventData::operator==( inOther )
323 && mSize == inOther.mSize
324 && safeStrEq( mType, inOther.mType )
325 && safeStrEq( mFile, inOther.mFile )
326 && mLine == inOther.mLine;
327 }
328
329 void setup( MemoryEventHeader& ) const {}
330 };
331
332 template<> inline MemoryEventTypes::Enum getMemoryEventType<FullAllocationEvent>() { return MemoryEventTypes::FullAllocationEvent; }
333
335 {
336 void init( uint64_t addr = 0 ) { MemoryEventData::init( addr ); }
337 void init( const DeallocationEvent& inData ) { MemoryEventData::init( inData ); }
338 };
339
340 template<> inline MemoryEventTypes::Enum getMemoryEventType<DeallocationEvent>() { return MemoryEventTypes::DeallocationEvent; }
341
343 {
344 public:
345 typedef PX_PROFILE_UNION_5(StringTableEvent, AllocationEvent, DeallocationEvent, FullAllocationEvent, uint8_t) EventData;
346
347 private:
348 MemoryEventHeader mHeader;
349 EventData mData;
350 public:
351
352 MemoryEvent() {}
353 MemoryEvent( MemoryEventHeader inHeader, const EventData& inData = EventData() )
354 : mHeader( inHeader )
355 , mData( inData )
356 {
357 }
358
359 template<typename TDataType>
360 MemoryEvent( const TDataType& inType )
361 : mHeader( getMemoryEventType<TDataType>() )
362 , mData( inType )
363 {
364 //set the appropriate compression bits.
365 inType.setup( mHeader );
366 }
367 const MemoryEventHeader& getHeader() const { return mHeader; }
368 const EventData& getData() const { return mData; }
369
370 template<typename TDataType>
371 const TDataType& getValue() const { PX_ASSERT( mHeader.getType() == getMemoryEventType<TDataType>() ); return mData.toType<TDataType>(); }
372
373 template<typename TDataType>
374 TDataType& getValue() { PX_ASSERT( mHeader.getType() == getMemoryEventType<TDataType>() ); return mData.toType<TDataType>(); }
375
376 template<typename TRetVal, typename TOperator>
377 inline TRetVal visit( TOperator inOp ) const;
378
379 bool operator==( const MemoryEvent& inOther ) const
380 {
381 if ( !(mHeader == inOther.mHeader ) ) return false;
382 if ( mHeader.getType() )
383 return inOther.visit<bool>( EventDataEqualOperator<EventData>( mData ) );
384 return true;
385 }
386 };
387
388 template<typename TRetVal, typename TOperator>
389 inline TRetVal visit( MemoryEventTypes::Enum inEventType, const MemoryEvent::EventData& inData, TOperator inOperator )
390 {
391 switch( inEventType )
392 {
393 case MemoryEventTypes::StringTableEvent: return inOperator( inData.toType( Type2Type<StringTableEvent>() ) );
394 case MemoryEventTypes::AllocationEvent: return inOperator( inData.toType( Type2Type<AllocationEvent>() ) );
395 case MemoryEventTypes::DeallocationEvent: return inOperator( inData.toType( Type2Type<DeallocationEvent>() ) );
396 case MemoryEventTypes::FullAllocationEvent: return inOperator( inData.toType( Type2Type<FullAllocationEvent>() ) );
397 case MemoryEventTypes::Unknown: return inOperator( static_cast<uint8_t>( inEventType ) );
398 }
399 return TRetVal();
400 }
401
402 template<typename TRetVal, typename TOperator>
403 inline TRetVal MemoryEvent::visit( TOperator inOp ) const
404 {
405 return physx::profile::visit<TRetVal>( mHeader.getType(), mData, inOp );
406 }
407}}
408
409#endif
410
Definition PxProfileMemoryEvents.h:343
#define PX_COMPILE_TIME_ASSERT(exp)
Definition PxPreprocessor.h:428
uint8 uint8_t
Definition fwd.hpp:103
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
Definition PxProfileMemoryEvents.h:242
Definition PxProfileMemoryEvents.h:83
Definition PxProfileMemoryEvents.h:335
Definition PxProfileEvents.h:619
Definition PxProfileMemoryEvents.h:297
Definition PxProfileMemoryEvents.h:212
Definition PxProfileMemoryEvents.h:110
Definition PxProfileMemoryEvents.h:38
Definition PxProfileMemoryEvents.h:178
Definition PxProfileEvents.h:50