RavEngine
Loading...
Searching...
No Matches
SnXmlMemoryPool.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 SN_XML_MEMORY_POOL_H
30#define SN_XML_MEMORY_POOL_H
31
32#include "foundation/PxAssert.h"
33#include "foundation/PxArray.h"
34#include "PxProfileAllocatorWrapper.h"
35
36namespace physx {
37
38 using namespace physx::profile;
39
44 {
45 SMemPoolNode* mNextNode;
46 };
47
56 template<PxU8 TItemSize
57 , PxU8 TItemCount >
59 {
61
63 TPxU8PtrList mAllMemory;
64 SMemPoolNode* mFirstFreeNode;
65 public:
67 : mWrapper( inWrapper )
68 , mAllMemory( inWrapper )
69 , mFirstFreeNode( NULL )
70 {}
72 {
73 TPxU8PtrList::ConstIterator theEnd = mAllMemory.end();
74 for ( TPxU8PtrList::ConstIterator theIter = mAllMemory.begin();
75 theIter != theEnd;
76 ++theIter )
77 {
78 PxU8* thePtr = *theIter;
79 mWrapper.getAllocator().deallocate( thePtr );
80 }
81 mAllMemory.clear();
82 mFirstFreeNode = NULL;
83 }
84 //Using deallocated memory to hold the pointers to the next amount of memory.
85 PxU8* allocate()
86 {
87 if ( mFirstFreeNode )
88 {
89 PxU8* retval = reinterpret_cast<PxU8*>(mFirstFreeNode);
90 mFirstFreeNode = mFirstFreeNode->mNextNode;
91 return retval;
92 }
93 PxU32 itemSize = GetItemSize();
94 PxU32 itemCount = 1 << TItemCount;
95 //No free nodes, make some more.
96 PxU8* retval = reinterpret_cast<PxU8*>(mWrapper.getAllocator().allocate( itemCount * itemSize, "RepX fixed-size memory pool", __FILE__, __LINE__ ));
97 PxU8* dataPtr = retval + itemSize;
98 //Free extra chunks
99 for( PxU32 idx = 1; idx < itemCount; ++idx, dataPtr += itemSize )
100 deallocate( dataPtr );
101 mAllMemory.pushBack(retval);
102 return retval;
103 }
104 void deallocate( PxU8* inData )
105 {
106 SMemPoolNode* nodePtr = reinterpret_cast<SMemPoolNode*>(inData);
107 nodePtr->mNextNode = mFirstFreeNode;
108 mFirstFreeNode = nodePtr;
109 }
110 //We have to have at least a pointer's worth of memory
111 inline PxU32 GetItemSize() { return sizeof(SMemPoolNode) << TItemSize; }
112 };
113
114 typedef PxU32 TMemAllocSizeType;
115
117 {
118 TMemAllocSizeType mSize;
119 SVariableMemPoolNode* NextNode() { return static_cast< SVariableMemPoolNode* >( mNextNode ); }
120 };
121
130 {
134 TPxU8PtrList mAllMemory;
135 TFreeNodeMap mFreeNodeMap;
136 PxU32 mMinAllocationSize;
137
138 CVariableMemoryPool &operator=(const CVariableMemoryPool &);
139
140 public:
141 CVariableMemoryPool(PxProfileAllocatorWrapper& inWrapper, PxU32 inMinAllocationSize = 0x20 )
142 : mWrapper( inWrapper )
143 , mAllMemory( inWrapper )
144 , mFreeNodeMap( inWrapper)
145 , mMinAllocationSize( inMinAllocationSize )
146 {}
147
149 {
150 TPxU8PtrList::ConstIterator theEnd = mAllMemory.end();
151 for ( TPxU8PtrList::ConstIterator theIter = mAllMemory.begin();
152 theIter != theEnd;
153 ++theIter )
154 {
155 PxU8* thePtr = *theIter;
156 mWrapper.getAllocator().deallocate( thePtr );
157 }
158 mAllMemory.clear();
159 mFreeNodeMap.clear();
160 }
161 PxU8* MarkMem( PxU8* inMem, TMemAllocSizeType inSize )
162 {
163 PX_ASSERT( inSize >= sizeof( SVariableMemPoolNode ) );
164 SVariableMemPoolNode* theMem = reinterpret_cast<SVariableMemPoolNode*>( inMem );
165 theMem->mSize = inSize;
166 return reinterpret_cast< PxU8* >( theMem + 1 );
167 }
168 //Using deallocated memory to hold the pointers to the next amount of memory.
169 PxU8* allocate( PxU32 size )
170 {
171 //Ensure we can place the size of the memory at the start
172 //of the memory block.
173 //Kai: to reduce the size of hash map, the requested size is aligned to 128 bytes
174 PxU32 theRequestedSize = (size + sizeof(SVariableMemPoolNode) + 127) & ~127;
175
176 TFreeNodeMap::Entry* entry = const_cast<TFreeNodeMap::Entry*>( mFreeNodeMap.find( theRequestedSize ) );
177 if ( NULL != entry )
178 {
179 SVariableMemPoolNode* theNode = entry->second;
180 PX_ASSERT( NULL != theNode );
181 PX_ASSERT( theNode->mSize == theRequestedSize );
182 entry->second = theNode->NextNode();
183 if (entry->second == NULL)
184 mFreeNodeMap.erase( theRequestedSize );
185
186 return reinterpret_cast< PxU8* >( theNode + 1 );
187 }
188
189 if ( theRequestedSize < mMinAllocationSize )
190 theRequestedSize = mMinAllocationSize;
191
192 //No large enough free nodes, make some more.
193 PxU8* retval = reinterpret_cast<PxU8*>(mWrapper.getAllocator().allocate( size_t(theRequestedSize), "RepX variable sized memory pool", __FILE__, __LINE__ ));
194 //If we allocated it, we free it.
195 mAllMemory.pushBack( retval );
196 return MarkMem( retval, theRequestedSize );
197 }
198
199 //The size is stored at the beginning of the memory block.
200 void deallocate( PxU8* inData )
201 {
202 SVariableMemPoolNode* theData = reinterpret_cast< SVariableMemPoolNode* >( inData ) - 1;
203 TMemAllocSizeType theSize = theData->mSize;
204 AddFreeMem( reinterpret_cast< PxU8* >( theData ), theSize );
205 }
206
207 void CheckFreeListInvariant( SVariableMemPoolNode* inNode )
208 {
209 if ( inNode && inNode->mNextNode )
210 {
211 PX_ASSERT( inNode->mSize <= inNode->NextNode()->mSize );
212 }
213 }
214
215 void AddFreeMem( PxU8* inMemory, TMemAllocSizeType inSize )
216 {
217 PX_ASSERT( inSize >= sizeof( SVariableMemPoolNode ) );
218 SVariableMemPoolNode* theNewNode = reinterpret_cast< SVariableMemPoolNode* >( inMemory );
219 theNewNode->mNextNode = NULL;
220 theNewNode->mSize = inSize;
221 TFreeNodeMap::Entry* entry = const_cast<TFreeNodeMap::Entry*>( mFreeNodeMap.find( inSize ) );
222 if (NULL != entry)
223 {
224 theNewNode->mNextNode = entry->second;
225 entry->second = theNewNode;
226 }
227 else
228 {
229 mFreeNodeMap.insert( inSize, theNewNode );
230 }
231 }
232 };
233
246 {
247 CMemoryPoolManager &operator=(const CMemoryPoolManager &);
248
249 public:
251
252 //CMemoryPool<0,8> m0ItemPool;
253 //CMemoryPool<1,8> m1ItemPool;
254 //CMemoryPool<2,8> m2ItemPool;
255 //CMemoryPool<3,8> m3ItemPool;
256 //CMemoryPool<4,8> m4ItemPool;
257 //CMemoryPool<5,8> m5ItemPool;
258 //CMemoryPool<6,8> m6ItemPool;
259 //CMemoryPool<7,8> m7ItemPool;
260 //CMemoryPool<8,8> m8ItemPool;
261 CVariableMemoryPool mVariablePool;
263 : mWrapper( inAllocator )
264 //, m0ItemPool( mWrapper )
265 //, m1ItemPool( mWrapper )
266 //, m2ItemPool( mWrapper )
267 //, m3ItemPool( mWrapper )
268 //, m4ItemPool( mWrapper )
269 //, m5ItemPool( mWrapper )
270 //, m6ItemPool( mWrapper )
271 //, m7ItemPool( mWrapper )
272 //, m8ItemPool( mWrapper )
273 , mVariablePool( mWrapper )
274 {
275 }
276 PxProfileAllocatorWrapper& getWrapper() { return mWrapper; }
277 inline PxU8* allocate( PxU32 inSize )
278 {
279 /*
280 if ( inSize <= m0ItemPool.GetItemSize() )
281 return m0ItemPool.allocate();
282 if ( inSize <= m1ItemPool.GetItemSize() )
283 return m1ItemPool.allocate();
284 if ( inSize <= m2ItemPool.GetItemSize() )
285 return m2ItemPool.allocate();
286 if ( inSize <= m3ItemPool.GetItemSize() )
287 return m3ItemPool.allocate();
288 if ( inSize <= m4ItemPool.GetItemSize() )
289 return m4ItemPool.allocate();
290 if ( inSize <= m5ItemPool.GetItemSize() )
291 return m5ItemPool.allocate();
292 if ( inSize <= m6ItemPool.GetItemSize() )
293 return m6ItemPool.allocate();
294 if ( inSize <= m7ItemPool.GetItemSize() )
295 return m7ItemPool.allocate();
296 if ( inSize <= m8ItemPool.GetItemSize() )
297 return m8ItemPool.allocate();
298 */
299 return mVariablePool.allocate( inSize );
300 }
301 inline void deallocate( PxU8* inMemory )
302 {
303 if ( inMemory == NULL )
304 return;
305 /*
306 if ( inSize <= m0ItemPool.GetItemSize() )
307 m0ItemPool.deallocate(inMemory);
308 else if ( inSize <= m1ItemPool.GetItemSize() )
309 m1ItemPool.deallocate(inMemory);
310 else if ( inSize <= m2ItemPool.GetItemSize() )
311 m2ItemPool.deallocate(inMemory);
312 else if ( inSize <= m3ItemPool.GetItemSize() )
313 m3ItemPool.deallocate(inMemory);
314 else if ( inSize <= m4ItemPool.GetItemSize() )
315 m4ItemPool.deallocate(inMemory);
316 else if ( inSize <= m5ItemPool.GetItemSize() )
317 m5ItemPool.deallocate(inMemory);
318 else if ( inSize <= m6ItemPool.GetItemSize() )
319 m6ItemPool.deallocate(inMemory);
320 else if ( inSize <= m7ItemPool.GetItemSize() )
321 m7ItemPool.deallocate(inMemory);
322 else if ( inSize <= m8ItemPool.GetItemSize() )
323 m8ItemPool.deallocate(inMemory);
324 else
325 */
326 mVariablePool.deallocate(inMemory);
327 }
331 template<typename TObjectType>
332 inline TObjectType* allocate()
333 {
334 TObjectType* retval = reinterpret_cast<TObjectType*>( allocate( sizeof(TObjectType) ) );
335 new (retval)TObjectType();
336 return retval;
337 }
338
343 template<typename TObjectType>
344 inline void deallocate( TObjectType* inObject )
345 {
346 inObject->~TObjectType();
347 deallocate( reinterpret_cast<PxU8*>(inObject) );
348 }
349
353 template<typename TObjectType>
354 inline TObjectType* BatchAllocate(PxU32 inCount )
355 {
356 TObjectType* retval = reinterpret_cast<TObjectType*>( allocate( sizeof(TObjectType) * inCount ) );
357 return retval;
358 }
359
364 template<typename TObjectType>
365 inline void BatchDeallocate( TObjectType* inObject, PxU32 inCount )
366 {
367 PX_UNUSED(inCount);
368 deallocate( reinterpret_cast<PxU8*>(inObject) );
369 }
370 };
371}
372
373#endif
Definition SnXmlMemoryPool.h:246
void BatchDeallocate(TObjectType *inObject, PxU32 inCount)
Definition SnXmlMemoryPool.h:365
void deallocate(TObjectType *inObject)
Definition SnXmlMemoryPool.h:344
TObjectType * allocate()
Definition SnXmlMemoryPool.h:332
TObjectType * BatchAllocate(PxU32 inCount)
Definition SnXmlMemoryPool.h:354
Definition SnXmlMemoryPool.h:59
Definition SnXmlMemoryPool.h:130
Abstract base class for an application defined memory allocator that can be used by the Nv library.
Definition PxAllocatorCallback.h:53
virtual void deallocate(void *ptr)=0
Frees memory previously allocated by allocate().
virtual void * allocate(size_t size, const char *typeName, const char *filename, int line)=0
Allocates size bytes of memory, which must be 16-byte aligned.
PX_FORCE_INLINE ConstIterator end() const
Definition PxArray.h:192
PX_INLINE void clear()
Definition PxArray.h:250
PX_FORCE_INLINE ConstIterator begin() const
Definition PxArray.h:176
PX_FORCE_INLINE T & pushBack(const T &a)
Definition PxArray.h:296
Definition PxBasicTemplates.h:67
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
Definition SnXmlMemoryPool.h:44
Definition SnXmlMemoryPool.h:117
Helper struct to encapsulate the user allocator callback Useful for array and hash templates.
Definition PxProfileAllocatorWrapper.h:46
Helper struct to encapsulate the array.
Definition PxProfileAllocatorWrapper.h:152
Helper struct to encapsulate the array.
Definition PxProfileAllocatorWrapper.h:171