1//
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions
4// are met:
5// * Redistributions of source code must retain the above copyright
6// notice, this list of conditions and the following disclaimer.
7// * Redistributions in binary form must reproduce the above copyright
8// notice, this list of conditions and the following disclaimer in the
9// documentation and/or other materials provided with the distribution.
10// * Neither the name of NVIDIA CORPORATION nor the names of its
11// contributors may be used to endorse or promote products derived
12// from this software without specific prior written permission.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
15// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
27// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
28// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
29
30
31#ifndef PXC_SCRATCHALLOCATOR_H
32#define PXC_SCRATCHALLOCATOR_H
33
34#include "foundation/PxAssert.h"
35#include "PxvConfig.h"
36#include "PsMutex.h"
37#include "PsArray.h"
38#include "PsAllocator.h"
39
40namespace physx
41{
42class PxcScratchAllocator
43{
44 PX_NOCOPY(PxcScratchAllocator)
45public:
46 PxcScratchAllocator() : mStack(PX_DEBUG_EXP("PxcScratchAllocator")), mStart(NULL), mSize(0)
47 {
48 mStack.reserve(capacity: 64);
49 mStack.pushBack(a: 0);
50 }
51
52 void setBlock(void* addr, PxU32 size)
53 {
54 // if the stack is not empty then some scratch memory was not freed on the previous frame. That's
55 // likely indicative of a problem, because when the scratch block is too small the memory will have
56 // come from the heap
57
58 PX_ASSERT(mStack.size()==1);
59 mStack.popBack();
60
61 mStart = reinterpret_cast<PxU8*>(addr);
62 mSize = size;
63 mStack.pushBack(a: mStart + size);
64 }
65
66 void* allocAll(PxU32& size)
67 {
68 Ps::Mutex::ScopedLock lock(mLock);
69 PX_ASSERT(mStack.size()>0);
70 size = PxU32(mStack.back()-mStart);
71
72 if(size==0)
73 return NULL;
74
75 mStack.pushBack(a: mStart);
76 return mStart;
77 }
78
79
80 void* alloc(PxU32 requestedSize, bool fallBackToHeap = false)
81 {
82 requestedSize = (requestedSize+15)&~15;
83
84 Ps::Mutex::ScopedLock lock(mLock);
85 PX_ASSERT(mStack.size()>=1);
86
87 PxU8* top = mStack.back();
88
89 if(top - mStart >= ptrdiff_t(requestedSize))
90 {
91 PxU8* addr = top - requestedSize;
92 mStack.pushBack(a: addr);
93 return addr;
94 }
95
96 if(!fallBackToHeap)
97 return NULL;
98
99 return PX_ALLOC(requestedSize, "Scratch Block Fallback");
100 }
101
102 void free(void* addr)
103 {
104 PX_ASSERT(addr!=NULL);
105 if(!isScratchAddr(addr))
106 {
107 PX_FREE(addr);
108 return;
109 }
110
111 Ps::Mutex::ScopedLock lock(mLock);
112 PX_ASSERT(mStack.size()>1);
113
114 PxU32 i=mStack.size()-1;
115 while(mStack[i]<addr)
116 i--;
117
118 PX_ASSERT(mStack[i]==addr);
119 mStack.remove(i);
120 }
121
122
123 bool isScratchAddr(void* addr) const
124 {
125 PxU8* a = reinterpret_cast<PxU8*>(addr);
126 return a>= mStart && a<mStart+mSize;
127 }
128
129private:
130 Ps::Mutex mLock;
131 Ps::Array<PxU8*> mStack;
132 PxU8* mStart;
133 PxU32 mSize;
134};
135
136}
137
138#endif
139

source code of qtquick3dphysics/src/3rdparty/PhysX/source/lowlevel/common/include/utils/PxcScratchAllocator.h