28 #ifndef _AKBLOCKPOOL_H
29 #define _AKBLOCKPOOL_H
31 #include <AK/Tools/Common/AkObject.h>
32 #include <AK/Tools/Common/AkAssert.h>
33 #include <AK/Tools/Common/AkListBareLight.h>
42 #define AK_DYNA_BLK_SCRUB_MEM
45 #ifdef AK_DYNA_BLK_STATS
46 #define STATS_ALLOC() Stats_Alloc()
47 #define STATS_NEWCHUNK() Stats_NewChunk()
48 #define STATS_FREE() Stats_Free()
49 #define STATS_DELCHUNK() Stats_DelChunk()
52 #define STATS_NEWCHUNK()
54 #define STATS_DELCHUNK()
57 #ifdef AK_DYNA_BLK_SCRUB_MEM
58 #define SCRUB_NEW_CHUNK() memset(&memory, 0xCC, sizeof(T)*uPoolChunkSize)
59 #define SCRUB_NEW_ALLOC(pItem) memset(pItem, 0xAA, sizeof(T))
60 #define SCRUB_FREE_BLOCK(pObj) memset(pObj, 0xDD, sizeof(T))
62 #define SCRUB_NEW_CHUNK()
63 #define SCRUB_NEW_ALLOC(pItem)
64 #define SCRUB_FREE_BLOCK(pObj)
67 template <
typename T, AkUInt32 uPoolChunkSize,
class TAlloc = ArrayPoolDefault>
70 enum { kChunkMemoryBytes =
sizeof(T)*uPoolChunkSize };
75 char padding[
sizeof(T) -
sizeof(FreeBlock*) ];
81 PoolChunk() : pNextLightItem(NULL)
84 for( AkUInt32 i=0; i<uPoolChunkSize; ++i )
86 FreeBlock* pBlk =
reinterpret_cast<FreeBlock*
>( &memory ) + i;
87 freeList.AddFirst(pBlk);
91 inline bool BelongsTo( FreeBlock* pMem )
const {
return (AkUInt8*)pMem >= memory && (AkUInt8*)pMem < (memory+kChunkMemoryBytes); }
92 inline bool AllFree()
const {
return freeList.Length() == uPoolChunkSize; }
93 inline bool AllAllocd()
const {
return freeList.IsEmpty(); }
95 AkUInt8 memory[ kChunkMemoryBytes ];
96 PoolChunk* pNextLightItem;
106 if (ptr) AkPlacementNew(ptr) T;
110 template<
typename A1>
114 if (ptr) AkPlacementNew(ptr) T(a1);
118 template<
typename A1,
typename A2>
122 if (ptr) AkPlacementNew(ptr) T(a1, a2);
126 template<
typename A1,
typename A2,
typename A3>
127 T*
New(A1 a1, A2 a2, A3 a3)
130 if (ptr) AkPlacementNew(ptr) T(a1, a2, a3);
134 template<
typename A1,
typename A2,
typename A3,
typename A4>
135 T*
New(A1 a1, A2 a2, A3 a3, A4 a4)
138 if (ptr) AkPlacementNew(ptr) T(a1,a2,a3,a4);
151 FreeBlock* pItem = NULL;
152 PoolChunk* pChunk = NULL;
154 pChunk = m_chunkList.
First();
155 while (pChunk != NULL && pChunk->AllAllocd())
156 pChunk = pChunk->pNextLightItem;
160 pChunk = (PoolChunk *) TAlloc::Alloc(
sizeof( PoolChunk ) );
161 AkPlacementNew(pChunk) PoolChunk();
169 pItem = pChunk->freeList.First();
170 AKASSERT(pItem != NULL);
171 pChunk->freeList.RemoveFirst();
172 SCRUB_NEW_ALLOC(pItem);
176 return reinterpret_cast<T*
>(pItem);
181 SCRUB_FREE_BLOCK((
void*)pObj);
183 FreeBlock* pItem =
reinterpret_cast<FreeBlock*
>(pObj);
185 PoolChunk* pPrevChunk = NULL;
186 PoolChunk* pChunk = m_chunkList.
First();
187 while (pChunk != NULL && !pChunk->BelongsTo(pItem))
190 pChunk = pChunk->pNextLightItem;
193 AKASSERT(pChunk != NULL);
194 pChunk->freeList.AddFirst(pItem);
197 if (pChunk->AllFree())
200 pChunk->~PoolChunk();
201 TAlloc::Free( pChunk );
206 tChunkList m_chunkList;
208 #ifdef AK_DYNA_BLK_STATS
211 uCurrentUsedBytes +=
sizeof(T);
212 uPeakUsedBytes = AkMax(uCurrentUsedBytes, uPeakUsedBytes);
214 void Stats_NewChunk()
216 uCurrentAllocdBytes +=
sizeof(PoolChunk);
217 uPeakAllocdBytes = AkMax(uCurrentAllocdBytes, uPeakAllocdBytes);
221 uCurrentUsedBytes -=
sizeof(T);
223 void Stats_DelChunk()
225 uCurrentAllocdBytes -=
sizeof(PoolChunk);
228 AkUInt32 uPeakUsedBytes;
229 AkUInt32 uPeakAllocdBytes;
230 AkUInt32 uCurrentAllocdBytes;
231 AkUInt32 uCurrentUsedBytes;