35 #define MEM_ID_ALLOC 0
36 #define MEM_ID_REALLOC 1
39 static void vMemStats(
APG_MEM_STATS* spStats,
apg_uint uiID, APG_MEM_CELL* spIn, APG_MEM_CELL* spOut);
40 static void vActivePush(APG_MEM_CTX* spCtx, APG_MEM_CELL* spCellIn);
41 static void vActivePop(APG_MEM_CTX* spCtx, APG_MEM_CELL* spCellIn);
57 void* vpReturn = NULL;
59 if(pfnAllocator && pfnDeAllocator){
60 spCtx = (APG_MEM_CTX*)pfnAllocator(
sizeof(APG_MEM_CTX));
62 memset((
void*)spCtx, 0,
sizeof(APG_MEM_CTX));
63 spCtx->pfnAllocator = pfnAllocator;
64 spCtx->pfnDeAllocator = pfnDeAllocator;
67 spCtx->vpValidate = (
void*)spCtx;
68 vpReturn = (
void*)spCtx;
99 APG_MEM_CTX* spCtx = (APG_MEM_CTX*)vpCtx;
100 if(spCtx->vpValidate == (
void*)spCtx){
103 memset(vpCtx, 0,
sizeof(APG_MEM_CTX));
104 pfnDeAllocator(vpCtx);
117 APG_MEM_CTX* spCtx = (APG_MEM_CTX*)vpCtx;
118 if(vpCtx && spCtx->vpValidate == vpCtx){uiRet =
APG_TRUE;}
131 void* vpReturn = NULL;
132 APG_MEM_CTX* spCtx = (APG_MEM_CTX*)vpCtx;
133 APG_MEM_CELL* spCell;
134 if(spCtx && spCtx->vpValidate == (
void*)spCtx){
135 spCell = (APG_MEM_CELL*)spCtx->pfnAllocator(uiBytes +
sizeof(APG_MEM_CELL));
137 spCell->uiSize = uiBytes;
140 vActivePush(spCtx, spCell);
141 vMemStats(&spCtx->sStats, MEM_ID_ALLOC, spCell, 0);
144 vpReturn = (
void*)(spCell + 1);
158 APG_MEM_CTX* spCtx = (APG_MEM_CTX*)vpCtx;
159 APG_MEM_CELL* spCell;
161 if(spCtx && spCtx->vpValidate == (
void*)spCtx){
162 spCell = (APG_MEM_CELL*)vpData;
166 vMemStats(&spCtx->sStats, MEM_ID_FREE, spCell, 0);
167 vActivePop(spCtx, spCell);
183 void* vpReturn = NULL;
184 APG_MEM_CTX* spCtx = (APG_MEM_CTX*)vpCtx;
185 APG_MEM_CELL* spOldCell;
186 APG_MEM_CELL* spNewCell;
191 if(vpData && uiBytes){
192 if(spCtx && spCtx->vpValidate == (
void*)spCtx){
193 spOldCell = (APG_MEM_CELL*)vpData;
197 spNewCell = (APG_MEM_CELL*)spCtx->pfnAllocator(uiBytes +
sizeof(APG_MEM_CELL));
199 spNewCell->spNext = spOldCell->spNext;
200 spNewCell->spPrev = spOldCell->spPrev;
201 spOldCell->spNext->spPrev = (
struct APG_MEM_CELL_STRUCT*)spNewCell;
202 spOldCell->spPrev->spNext = (
struct APG_MEM_CELL_STRUCT*)spNewCell;
203 spNewCell->uiSeq = spOldCell->uiSeq;
204 spNewCell->uiSize = uiBytes;
207 uiCopy =
min(uiBytes, spOldCell->uiSize);
208 vpDst = (
void*)(spNewCell + 1);
209 vpSrc = (
void*)(spOldCell + 1);
210 memcpy(vpDst, vpSrc, uiCopy);
213 vMemStats(&spCtx->sStats, MEM_ID_REALLOC, spOldCell, spNewCell);
215 spCtx->pfnDeAllocator((
void*)spOldCell);
216 vpReturn = (
void*)(spNewCell + 1);
231 APG_MEM_CTX* spCtx = (APG_MEM_CTX*)vpCtx;
232 APG_MEM_CELL* spLast;
234 if(spCtx && spCtx->vpValidate == (
void*)spCtx){
235 if(spCtx->spActiveList){
236 spLast = (APG_MEM_CELL*)spCtx->spActiveList->spPrev;
237 uiChk = spLast->uiSeq + 1;
251 APG_MEM_CTX* spCtx = (APG_MEM_CTX*)vpCtx;
252 APG_MEM_CELL* spLast;
253 if(spCtx && spCtx->vpValidate == (
void*)spCtx){
257 if(spCtx->spActiveList == NULL){
break;}
260 spLast = (APG_MEM_CELL*)spCtx->spActiveList->spPrev;
263 if(spLast->uiSeq < uiChk){
break;}
266 vMemStats(&spCtx->sStats, MEM_ID_FREE, spLast, 0);
267 vActivePop(spCtx, spLast);
289 APG_MEM_CTX* spMemCtx = (APG_MEM_CTX*)vpCtx;
292 memcpy((
void*)spStats, (
void*)&spMemCtx->sStats,
sizeof(
APG_MEM_STATS));
324 static void vMemStats(
APG_MEM_STATS* spStats,
apg_uint uiID, APG_MEM_CELL* spIn, APG_MEM_CELL* spOut){
329 spStats->
uiHeapBytes += spIn->uiSize +
sizeof(APG_MEM_CELL);
341 spStats->
uiHeapBytes += spOut->uiSize - spIn->uiSize;
347 spStats->
uiHeapBytes -= spIn->uiSize +
sizeof(APG_MEM_CELL);
368 static void vActivePush(APG_MEM_CTX* spCtx, APG_MEM_CELL* spCellIn){
369 struct APG_MEM_CELL_STRUCT* spLast;
370 struct APG_MEM_CELL_STRUCT* spFirst;
371 struct APG_MEM_CELL_STRUCT* spCell = (
struct APG_MEM_CELL_STRUCT*)spCellIn;
375 switch(spCtx->uiActiveCellCount){
377 spCtx->spActiveList = spCell;
378 spCell->spNext = spCell->spPrev = spCell;
382 spLast = spCtx->spActiveList;
383 spLast->spNext = spLast->spPrev = spCell;
384 spCell->spNext = spCell->spPrev = spLast;
385 spCell->uiSeq = spLast->uiSeq + 1;
388 spFirst = spCtx->spActiveList;
389 spLast = spFirst->spPrev;
390 spFirst->spPrev = spCell;
391 spLast->spNext = spCell;
392 spCell->spNext = spFirst;
393 spCell->spPrev = spLast;
394 spCell->uiSeq = spLast->uiSeq + 1;
398 ++spCtx->uiActiveCellCount;
416 static void vActivePop(APG_MEM_CTX* spCtx, APG_MEM_CELL* spCellIn){
417 struct APG_MEM_CELL_STRUCT* spPrev;
418 struct APG_MEM_CELL_STRUCT* spNext;
419 struct APG_MEM_CELL_STRUCT* spCell = (
struct APG_MEM_CELL_STRUCT*)spCellIn;
421 if(spCtx->spActiveList == spCell){
423 if(spCtx->uiActiveCellCount == 1){
424 spCtx->spActiveList = NULL;
425 }
else{spCtx->spActiveList = spCtx->spActiveList->spNext;}
429 spPrev = spCell->spPrev;
430 spNext = spCell->spNext;
431 spPrev->spNext = spCell->spNext;
432 spNext->spPrev = spCell->spPrev;
434 --spCtx->uiActiveCellCount;
437 spCtx->pfnDeAllocator((
void*)spCell);