include/AK/Tools/Common/AkDynaBlkPool.h
説明を見る。00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _AKBLOCKPOOL_H
00029 #define _AKBLOCKPOOL_H
00030
00031 #include <AK/Tools/Common/AkObject.h>
00032 #include <AK/Tools/Common/AkAssert.h>
00033 #include <AK/Tools/Common/AkListBareLight.h>
00034
00035
00036
00037
00038
00039
00040 #ifdef _DEBUG
00041
00042 #define AK_DYNA_BLK_SCRUB_MEM
00043 #endif
00044
00045 #ifdef AK_DYNA_BLK_STATS
00046 #define STATS_ALLOC() Stats_Alloc()
00047 #define STATS_NEWCHUNK() Stats_NewChunk()
00048 #define STATS_FREE() Stats_Free()
00049 #define STATS_DELCHUNK() Stats_DelChunk()
00050 #else
00051 #define STATS_ALLOC()
00052 #define STATS_NEWCHUNK()
00053 #define STATS_FREE()
00054 #define STATS_DELCHUNK()
00055 #endif
00056
00057 #ifdef AK_DYNA_BLK_SCRUB_MEM
00058 #define SCRUB_NEW_CHUNK() memset(&memory, 0xCC, sizeof(T)*uPoolChunkSize)
00059 #define SCRUB_NEW_ALLOC(pItem) memset(pItem, 0xAA, sizeof(T))
00060 #define SCRUB_FREE_BLOCK(pObj) memset(pObj, 0xDD, sizeof(T))
00061 #else
00062 #define SCRUB_NEW_CHUNK()
00063 #define SCRUB_NEW_ALLOC(pItem)
00064 #define SCRUB_FREE_BLOCK(pObj)
00065 #endif
00066
00067 template < typename T, AkUInt32 uPoolChunkSize, class TAlloc = ArrayPoolDefault>
00068 class AkDynaBlkPool: public TAlloc
00069 {
00070 enum { kChunkMemoryBytes = sizeof(T)*uPoolChunkSize };
00071
00072 struct FreeBlock
00073 {
00074 FreeBlock* pNextItem;
00075 char padding[ sizeof(T) - sizeof(FreeBlock*) ];
00076 };
00077 typedef AkListBare< FreeBlock, AkListBareNextItem, AkCountPolicyWithCount, AkLastPolicyNoLast > tFreeList;
00078
00079 struct PoolChunk
00080 {
00081 PoolChunk() : pNextLightItem(NULL)
00082 {
00083 SCRUB_NEW_CHUNK();
00084 for( AkUInt32 i=0; i<uPoolChunkSize; ++i )
00085 {
00086 FreeBlock* pBlk = reinterpret_cast<FreeBlock*>( &memory ) + i;
00087 freeList.AddFirst(pBlk);
00088 }
00089 }
00090
00091 inline bool BelongsTo( FreeBlock* pMem ) const { return (AkUInt8*)pMem >= memory && (AkUInt8*)pMem < (memory+kChunkMemoryBytes); }
00092 inline bool AllFree() const { return freeList.Length() == uPoolChunkSize; }
00093 inline bool AllAllocd() const { return freeList.IsEmpty(); }
00094
00095 AkUInt8 memory[ kChunkMemoryBytes ];
00096 PoolChunk* pNextLightItem;
00097 tFreeList freeList;
00098 };
00099 typedef AkListBareLight< PoolChunk > tChunkList;
00100
00101 public:
00102
00103 T* New()
00104 {
00105 T* ptr = Alloc();
00106 if (ptr) AkPlacementNew(ptr) T;
00107 return ptr;
00108 }
00109
00110 template<typename A1>
00111 T* New(A1 a1)
00112 {
00113 T* ptr = Alloc();
00114 if (ptr) AkPlacementNew(ptr) T(a1);
00115 return ptr;
00116 }
00117
00118 template<typename A1, typename A2>
00119 T* New(A1 a1, A2 a2)
00120 {
00121 T* ptr = Alloc();
00122 if (ptr) AkPlacementNew(ptr) T(a1, a2);
00123 return ptr;
00124 }
00125
00126 template<typename A1, typename A2, typename A3>
00127 T* New(A1 a1, A2 a2, A3 a3)
00128 {
00129 T* ptr = Alloc();
00130 if (ptr) AkPlacementNew(ptr) T(a1, a2, a3);
00131 return ptr;
00132 }
00133
00134 template<typename A1, typename A2, typename A3, typename A4>
00135 T* New(A1 a1, A2 a2, A3 a3, A4 a4)
00136 {
00137 T* ptr = Alloc();
00138 if (ptr) AkPlacementNew(ptr) T(a1,a2,a3,a4);
00139 return ptr;
00140 }
00141
00142 void Delete(T* ptr)
00143 {
00144 ptr->~T();
00145 Free(ptr);
00146 }
00147
00148 private:
00149 T* Alloc()
00150 {
00151 FreeBlock* pItem = NULL;
00152 PoolChunk* pChunk = NULL;
00153
00154 pChunk = m_chunkList.First();
00155 while (pChunk != NULL && pChunk->AllAllocd())
00156 pChunk = pChunk->pNextLightItem;
00157
00158 if (pChunk == NULL)
00159 {
00160 pChunk = (PoolChunk *) TAlloc::Alloc( sizeof( PoolChunk ) );
00161 AkPlacementNew(pChunk) PoolChunk();
00162 STATS_NEWCHUNK();
00163 if (pChunk != NULL)
00164 m_chunkList.AddFirst(pChunk);
00165 }
00166
00167 if (pChunk != NULL)
00168 {
00169 pItem = pChunk->freeList.First();
00170 AKASSERT(pItem != NULL);
00171 pChunk->freeList.RemoveFirst();
00172 SCRUB_NEW_ALLOC(pItem);
00173 STATS_ALLOC();
00174 }
00175
00176 return reinterpret_cast<T*>(pItem);
00177 }
00178
00179 void Free( T* pObj )
00180 {
00181 SCRUB_FREE_BLOCK((void*)pObj);
00182
00183 FreeBlock* pItem = reinterpret_cast<FreeBlock*>(pObj);
00184
00185 PoolChunk* pPrevChunk = NULL;
00186 PoolChunk* pChunk = m_chunkList.First();
00187 while (pChunk != NULL && !pChunk->BelongsTo(pItem))
00188 {
00189 pPrevChunk = pChunk;
00190 pChunk = pChunk->pNextLightItem;
00191 }
00192
00193 AKASSERT(pChunk != NULL);
00194 pChunk->freeList.AddFirst(pItem);
00195 STATS_FREE();
00196
00197 if (pChunk->AllFree())
00198 {
00199 m_chunkList.RemoveItem(pChunk, pPrevChunk);
00200 pChunk->~PoolChunk();
00201 TAlloc::Free( pChunk );
00202 STATS_DELCHUNK();
00203 }
00204 }
00205
00206 tChunkList m_chunkList;
00207
00208 #ifdef AK_DYNA_BLK_STATS
00209 void Stats_Alloc()
00210 {
00211 uCurrentUsedBytes += sizeof(T);
00212 uPeakUsedBytes = AkMax(uCurrentUsedBytes, uPeakUsedBytes);
00213 }
00214 void Stats_NewChunk()
00215 {
00216 uCurrentAllocdBytes += sizeof(PoolChunk);
00217 uPeakAllocdBytes = AkMax(uCurrentAllocdBytes, uPeakAllocdBytes);
00218 }
00219 void Stats_Free()
00220 {
00221 uCurrentUsedBytes -= sizeof(T);
00222 }
00223 void Stats_DelChunk()
00224 {
00225 uCurrentAllocdBytes -= sizeof(PoolChunk);
00226 }
00227 public:
00228 AkUInt32 uPeakUsedBytes;
00229 AkUInt32 uPeakAllocdBytes;
00230 AkUInt32 uCurrentAllocdBytes;
00231 AkUInt32 uCurrentUsedBytes;
00232 #endif
00233 };
00234
00235
00236 #endif
あなたのプロジェクトについて教えてください。ご不明な点はありませんか。
プロジェクトを登録していただくことで、ご利用開始のサポートをいたします。
Wwiseからはじめよう