版本
menu

Wwise SDK 2024.1.6
AkDynaBlkPool.h
浏览该文件的文档.
1 /*******************************************************************************
2 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
3 released in source code form as part of the SDK installer package.
4 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Copyright (c) 2025 Audiokinetic Inc.
25 *******************************************************************************/
26 
27 #ifndef _AKBLOCKPOOL_H
28 #define _AKBLOCKPOOL_H
29 
33 
34 //
35 // AkDynaBlkPool - A dynamic block pool allocator which will grow (and shrink) in size in contiguous chunks of 'uPoolChunkSize' objects.
36 // - Fragmentation in the pool will prevent it from shrinking, but in many use cases this is acceptable.
37 //
38 
39 #ifdef _DEBUG
40 //#define AK_DYNA_BLK_STATS
41 #define AK_DYNA_BLK_SCRUB_MEM
42 #endif
43 
44 #ifdef AK_DYNA_BLK_STATS
45 #define STATS_ALLOC() Stats_Alloc()
46 #define STATS_NEWCHUNK() Stats_NewChunk()
47 #define STATS_FREE() Stats_Free()
48 #define STATS_DELCHUNK() Stats_DelChunk()
49 #else
50 #define STATS_ALLOC()
51 #define STATS_NEWCHUNK()
52 #define STATS_FREE()
53 #define STATS_DELCHUNK()
54 #endif
55 
56 #ifdef AK_DYNA_BLK_SCRUB_MEM
57 #define SCRUB_NEW_CHUNK() memset(&memory, 0xCC, sizeof(T)*uPoolChunkSize)
58 #define SCRUB_NEW_ALLOC(pItem) memset(pItem, 0xAA, sizeof(T))
59 #define SCRUB_FREE_BLOCK(pObj) memset(pObj, 0xDD, sizeof(T))
60 #else
61 #define SCRUB_NEW_CHUNK()
62 #define SCRUB_NEW_ALLOC(pItem)
63 #define SCRUB_FREE_BLOCK(pObj)
64 #endif
65 
66 template < typename T, AkUInt32 uPoolChunkSize, class TAlloc = ArrayPoolDefault>
67 class AkDynaBlkPool: public TAlloc
68 {
69  enum { kChunkMemoryBytes = sizeof(T)*uPoolChunkSize };
70 
71  struct FreeBlock
72  {
73  FreeBlock* pNextItem;
74  char padding[ sizeof(T) - sizeof(FreeBlock*) ];
75  };
77 
78  struct PoolChunk
79  {
80  PoolChunk() : pNextLightItem(NULL)
81  {
83  for( AkUInt32 i=0; i<uPoolChunkSize; ++i )
84  {
85  FreeBlock* pBlk = reinterpret_cast<FreeBlock*>( &memory ) + i;
86  freeList.AddFirst(pBlk);
87  }
88  }
89 
90  inline bool BelongsTo( FreeBlock* pMem ) const { return (AkUInt8*)pMem >= memory && (AkUInt8*)pMem < (memory+kChunkMemoryBytes); }
91  inline bool AllFree() const { return freeList.Length() == uPoolChunkSize; }
92  inline bool AllAllocd() const { return freeList.IsEmpty(); }
93 
94  AkUInt8 memory[ kChunkMemoryBytes ];
95  PoolChunk* pNextLightItem;
96  tFreeList freeList;
97  };
99 
100 public:
102  {
103  AKASSERT(m_chunkList.IsEmpty());
104  }
105 
106  T* New()
107  {
108  T* ptr = Alloc();
109  if (ptr) AkPlacementNew(ptr) T;
110  return ptr;
111  }
112 
113  template<typename A1>
114  T* New(A1 a1)
115  {
116  T* ptr = Alloc();
117  if (ptr) AkPlacementNew(ptr) T(a1);
118  return ptr;
119  }
120 
121  template<typename A1, typename A2>
122  T* New(A1 a1, A2 a2)
123  {
124  T* ptr = Alloc();
125  if (ptr) AkPlacementNew(ptr) T(a1, a2);
126  return ptr;
127  }
128 
129  template<typename A1, typename A2, typename A3>
130  T* New(A1 a1, A2 a2, A3 a3)
131  {
132  T* ptr = Alloc();
133  if (ptr) AkPlacementNew(ptr) T(a1, a2, a3);
134  return ptr;
135  }
136 
137  template<typename A1, typename A2, typename A3, typename A4>
138  T* New(A1 a1, A2 a2, A3 a3, A4 a4)
139  {
140  T* ptr = Alloc();
141  if (ptr) AkPlacementNew(ptr) T(a1,a2,a3,a4);
142  return ptr;
143  }
144 
145  void Delete(T* ptr)
146  {
147  ptr->~T();
148  Free(ptr);
149  }
150 
152  {
153  m_chunkList.Transfer(in_src.m_chunkList);
154 
155 #ifdef AK_DYNA_BLK_STATS
156  uPeakUsedBytes = in_src.uPeakUsedBytes;
157  uPeakAllocdBytes = in_src.uPeakAllocdBytes;
158  uCurrentAllocdBytes = in_src.uCurrentAllocdBytes;
159  uCurrentUsedBytes = in_src.uCurrentUsedBytes;
160 
161  in_src.uPeakUsedBytes = 0;
162  in_src.uPeakAllocdBytes = 0;
163  in_src.uCurrentAllocdBytes = 0;
164  in_src.uCurrentUsedBytes = 0;
165 #endif
166  }
167 
168 private:
169  T* Alloc()
170  {
171  FreeBlock* pItem = NULL;
172  PoolChunk* pChunk = NULL;
173 
174  pChunk = m_chunkList.First();
175  while (pChunk != NULL && pChunk->AllAllocd())
176  pChunk = pChunk->pNextLightItem;
177 
178  if (pChunk == NULL)
179  {
180  pChunk = (PoolChunk *) TAlloc::Alloc( sizeof( PoolChunk ) );
181  AkPlacementNew(pChunk) PoolChunk();
182  STATS_NEWCHUNK();
183  if (pChunk != NULL)
184  m_chunkList.AddFirst(pChunk);
185  }
186 
187  if (pChunk != NULL)
188  {
189  pItem = pChunk->freeList.First();
190  AKASSERT(pItem != NULL);
191  pChunk->freeList.RemoveFirst();
192  SCRUB_NEW_ALLOC(pItem);
193  STATS_ALLOC();
194  }
195 
196  return reinterpret_cast<T*>(pItem);
197  }
198 
199  void Free( T* pObj )
200  {
201  SCRUB_FREE_BLOCK((void*)pObj);
202 
203  FreeBlock* pItem = reinterpret_cast<FreeBlock*>(pObj);
204 
205  PoolChunk* pPrevChunk = NULL;
206  PoolChunk* pChunk = m_chunkList.First();
207  while (pChunk != NULL && !pChunk->BelongsTo(pItem))
208  {
209  pPrevChunk = pChunk;
210  pChunk = pChunk->pNextLightItem;
211  }
212 
213  AKASSERT(pChunk != NULL);
214  pChunk->freeList.AddFirst(pItem);
215  STATS_FREE();
216 
217  if (pChunk->AllFree())
218  {
219  m_chunkList.RemoveItem(pChunk, pPrevChunk);
220  pChunk->~PoolChunk();
221  TAlloc::Free( pChunk );
222  STATS_DELCHUNK();
223  }
224  }
225 
226  tChunkList m_chunkList;
227 
228 #ifdef AK_DYNA_BLK_STATS
229  void Stats_Alloc()
230  {
231  uCurrentUsedBytes += sizeof(T);
232  uPeakUsedBytes = AkMax(uCurrentUsedBytes, uPeakUsedBytes);
233  }
234  void Stats_NewChunk()
235  {
236  uCurrentAllocdBytes += sizeof(PoolChunk);
237  uPeakAllocdBytes = AkMax(uCurrentAllocdBytes, uPeakAllocdBytes);
238  }
239  void Stats_Free()
240  {
241  uCurrentUsedBytes -= sizeof(T);
242  }
243  void Stats_DelChunk()
244  {
245  uCurrentAllocdBytes -= sizeof(PoolChunk);
246  }
247 public:
248  AkUInt32 uPeakUsedBytes;
249  AkUInt32 uPeakAllocdBytes;
250  AkUInt32 uCurrentAllocdBytes;
251  AkUInt32 uCurrentUsedBytes;
252 #endif
253 };
254 
255 
256 #endif
AkForceInline T * First()
Get first element.
Definition: AkListBare.h:390
#define SCRUB_FREE_BLOCK(pObj)
Definition: AkDynaBlkPool.h:63
#define STATS_DELCHUNK()
Definition: AkDynaBlkPool.h:53
#define AkMax(x1, x2)
#define AkPlacementNew(_memory)
AKSOUNDENGINE_API void Free(AkMemPoolId in_poolId, void *in_pMemAddress)
#define SCRUB_NEW_CHUNK()
Definition: AkDynaBlkPool.h:61
uint8_t AkUInt8
Unsigned 8-bit integer
#define STATS_ALLOC()
Definition: AkDynaBlkPool.h:50
AkForceInline bool IsEmpty() const
Empty condition.
Definition: AkListBare.h:396
#define NULL
Definition: AkTypes.h:46
void AddFirst(T *in_pItem)
Add element at the beginning of list.
Definition: AkListBare.h:308
#define STATS_NEWCHUNK()
Definition: AkDynaBlkPool.h:51
#define AKASSERT(Condition)
Definition: AkAssert.h:67
void Delete(T *ptr)
T * New(A1 a1)
void RemoveItem(T *in_pItem, T *in_pPrevItem)
Remove an element.
Definition: AkListBare.h:402
T * New(A1 a1, A2 a2, A3 a3, A4 a4)
T * New(A1 a1, A2 a2, A3 a3)
#define SCRUB_NEW_ALLOC(pItem)
Definition: AkDynaBlkPool.h:62
uint32_t AkUInt32
Unsigned 32-bit integer
void Transfer(AkDynaBlkPool< T, uPoolChunkSize, TAlloc > &in_src)
#define STATS_FREE()
Definition: AkDynaBlkPool.h:52
void Transfer(AkListBare< T, U_NEXTITEM, COUNT_POLICY, LAST_POLICY > &in_src)
Definition: AkListBare.h:437
T * New(A1 a1, A2 a2)

此页面对您是否有帮助?

需要技术支持?

仍有疑问?或者问题?需要更多信息?欢迎联系我们,我们可以提供帮助!

查看我们的“技术支持”页面

介绍一下自己的项目。我们会竭力为您提供帮助。

来注册自己的项目,我们帮您快速入门,不带任何附加条件!

开始 Wwise 之旅