📄 gmem.c
字号:
#if CMN_LOG_INTERNAL & CMN_LOG_MEMORY
memClients[id].stat.lastAlloc = sz;
memClients[id].stat.bytesAllocated += memClients[id].stat.lastAlloc;
memClients[id].stat.lastReq = size;
memClients[id].stat.bytesRequested += memClients[id].stat.lastReq;
memClients[id].stat.currentlyAllocated += memClients[id].stat.lastAlloc;
if (memClients[id].stat.currentlyAllocated > memClients[id].stat.maxAllocated)
{
memClients[id].stat.maxAllocated = memClients[id].stat.currentlyAllocated;
}
++memClients[id].stat.numAlloc;
memClients[id].stat.traverseCount += tmp_traverse_count;
memClients[id].stat.maxFreeListLength =
MEM_MAX( memClients[id].stat.maxFreeListLength, tmp_traverse_count);
checkAllocatedChunk( id, p);
#endif
return chunk2mem(p);
}
MemPtr gMemGcMalloc(CmnClientId id, MemSize size)
{
MemChunk *p = 0;
MemChunk *ptmp;
SIZE_L nb;
SIZE_L sz = 250000;
SIZE_L remsize;
short i;
#if CMN_LOG_INTERNAL & CMN_LOG_MEMORY
int tmp_traverse_count = 0;
#endif
nb = request2size(size);
for (i = listIdx(nb); i < NUM_FREE_LISTS; i++)
{
MemChunk *freelist = memClients[id].freelists[i];
for (ptmp = forward(freelist); ptmp != freelist;
ptmp = forward(ptmp))
{
SIZE_L tmpsz = chunksize(ptmp);
#if CMN_LOG_INTERNAL & CMN_LOG_MEMORY
tmp_traverse_count++;
#endif
if (tmpsz == nb)
{
p = ptmp;
sz = tmpsz;
goto found;
}
else if (tmpsz > nb)
{
if (tmpsz < sz)
{
p = ptmp;
sz = tmpsz;
}
}
}
if (p != 0)
{
goto found;
}
}
return 0;
found:
remove_from_list(p);
remsize = sz - nb;
if (remsize >= MINCHUNKSIZE)
{
MemChunk *q;
MemChunk *next;
MemChunk *list;
sz = nb;
q = (MemChunk *)((Ptr)p + sz);
set_hd2(q, remsize >> 1);
set_hd1(q, nb >> 1);
next = nextchunk(q);
set_prevsize(next, remsize);
list = memClients[id].freelists[listIdx(remsize)];
add_to_list( list, q);
}
set_hd2(p, (sz >> 1) | 0x01);
set_gcbit(p);
#if CMN_LOG_INTERNAL & CMN_LOG_MEMORY
memClients[id].stat.lastAlloc = sz;
memClients[id].stat.bytesAllocated += memClients[id].stat.lastAlloc;
memClients[id].stat.lastReq = size;
memClients[id].stat.bytesRequested += memClients[id].stat.lastReq;
memClients[id].stat.currentlyAllocated += memClients[id].stat.lastAlloc;
if (memClients[id].stat.currentlyAllocated > memClients[id].stat.maxAllocated)
{
memClients[id].stat.maxAllocated = memClients[id].stat.currentlyAllocated;
}
++memClients[id].stat.numAlloc;
memClients[id].stat.traverseCount += tmp_traverse_count;
memClients[id].stat.maxFreeListLength =
MEM_MAX( memClients[id].stat.maxFreeListLength, tmp_traverse_count);
checkAllocatedChunk( id, p);
#endif
return chunk2mem(p);
}
static void gMemFreeChunk(CmnClientId id, MemPtr mem)
{
MemChunk *p;
SIZE_L sz;
MemChunk *next;
MemChunk *prev;
MemChunk *list;
if (mem == 0)
{
return;
}
p = mem2chunk(mem);
#if CMN_LOG_INTERNAL & CMN_LOG_MEMORY
checkAllocatedChunk( id, p);
#endif
if (chunk_isfree(p))
{
return;
}
sz = chunksize(p);
prev = prevchunk(p);
next = nextchunk(p);
#if CMN_LOG_INTERNAL & CMN_LOG_MEMORY
memClients[id].stat.lastAlloc = -(int)sz;
memClients[id].stat.lastReq = memClients[id].stat.lastAlloc;
memClients[id].stat.currentlyAllocated -= sz;
++memClients[id].stat.numFree;
#endif
if (chunk_isfree(prev))
{
sz += chunksize(prev);
p = prev;
remove_from_list(prev);
}
if (chunk_isfree(next))
{
sz += chunksize(next);
remove_from_list(next);
}
set_hd2(p, sz >> 1);
clear_gcbit(p);
next = nextchunk(p);
set_prevsize(next, sz);
list = memClients[id].freelists[ listIdx(sz) ];
add_to_list( list, p);
}
void gMemGc(CmnClientId id)
{
MemChunk *p;
MemChunk *l;
for (p = memClients[id].first; p != memClients[id].last; p = nextchunk(p))
{
if (chunk_inuse(p) && chunk_has_gcbit(p))
{
SIZE_L sz;
MemChunk *next;
MemChunk *prev;
sz = chunksize(p);
prev = prevchunk(p);
next = nextchunk(p);
#if CMN_LOG_INTERNAL & CMN_LOG_MEMORY
checkAllocatedChunk( id, p);
memClients[id].stat.lastAlloc = -(int)sz;
memClients[id].stat.lastReq = memClients[id].stat.lastAlloc;
memClients[id].stat.currentlyAllocated -= sz;
++memClients[id].stat.numFree;
#endif
if (chunk_isfree(prev))
{
sz += chunksize(prev);
remove_from_list(prev);
p = prev;
}
if (chunk_isfree(next))
{
sz += chunksize(next);
remove_from_list(next);
}
set_hd2(p, sz >> 1);
clear_gcbit(p);
next = nextchunk(p);
set_prevsize(next, sz);
l = memClients[id].freelists[ listIdx(sz) ];
add_to_list (l, p);
}
}
}
MemSize gMemSize(MemPtr mem)
{
MemChunk *p = mem2chunk(mem);
return chunksize(p);
}
#if CMN_LOG_INTERNAL & CMN_LOG_MEMORY
#include <assert.h>
static void checkAllocatedChunk(CmnClientId id, MemChunk *p)
{
MemChunk *nextp;
MemChunk *prevp;
assert(chunk_inuse(p));
assert((Ptr)p >= memClients[id].base);
assert(p <= memClients[id].last);
assert(((SIZE_L)p & MALLOC_ALIGN_MASK) == 0);
assert(chunksize(p) >= MINCHUNKSIZE);
nextp = nextchunk(p);
assert((Ptr)nextp >= memClients[id].base);
assert(nextp <= memClients[id].last);
assert(((SIZE_L)nextp & MALLOC_ALIGN_MASK) == 0);
assert(chunksize(nextp) >= MINCHUNKSIZE);
assert(chunksize(p) == prevsize(nextp));
if (chunk_isfree(nextp))
{
MemChunk *q;
q = forward(nextp);
assert((Ptr)q >= memClients[id].base);
assert(q <= memClients[id].last);
q = back(nextp);
assert((Ptr)q >= memClients[id].base);
assert(q <= memClients[id].last);
}
if (p > memClients[id].first)
{
prevp = prevchunk(p);
assert((Ptr)prevp >= memClients[id].base);
assert(prevp <= memClients[id].last);
assert(((SIZE_L)prevp & MALLOC_ALIGN_MASK) == 0);
assert(chunksize(prevp) >= MINCHUNKSIZE);
assert(chunksize(prevp) == prevsize(p));
if (chunk_isfree(prevp))
{
MemChunk *q;
q = forward(prevp);
assert((Ptr)q >= memClients[id].base);
assert(q <= memClients[id].last);
q = back(prevp);
assert((Ptr)q >= memClients[id].base);
assert(q <= memClients[id].last);
}
}
}
MallocStats *gMemGetStats(CmnClientId id)
{
return &memClients[id].stat;
}
short gMemGetFragmentation(CmnClientId id)
{
MemChunk *p;
SIZE_L largestsize = 0;
SIZE_L totalfreesize = 0;
SIZE_L sz;
for (p = memClients[id].first; p != memClients[id].last; p = nextchunk(p))
{
if (chunk_isfree(p))
{
sz = chunksize(p);
totalfreesize += sz;
largestsize = MEM_MAX( largestsize, sz);
}
}
if (totalfreesize == 0)
return 100;
return (short)((largestsize * 100) / totalfreesize);
}
void gMemPrintAlloc(CmnClientId id, FILE *logfile)
{
MemChunk *p;
fprintf(logfile, "Allocated chunks for client %d\n", id);
fprintf(logfile, "=============================\n");
for (p = memClients[id].first; p != memClients[id].last; p = nextchunk(p))
{
if (!chunk_isfree(p))
{
fprintf(logfile, "id: %d\tsize: %d\n", 0, chunksize(p));
}
}
}
void gMemPrintBriefStats(CmnClientId id, FILE *logfile)
{
short i;
MemChunk *p;
SIZE_L listcount = 0;
SIZE_L chunkcount = 0;
for (i = 0; i < NUM_FREE_LISTS; i++)
{
for (p = forward(memClients[id].freelists[i]);
p != memClients[id].freelists[i]; p = forward(p))
{
listcount++;
}
}
for (p = memClients[id].first; p != memClients[id].last; p = nextchunk(p))
{
chunkcount++;
}
if (memClients[id].stat.lastReq < 0)
{
memClients[id].stat.lastReq = 0;
}
fprintf(logfile, "%6d%6d%6d%6d%6lu%6lu\n",
memClients[id].stat.lastReq,
memClients[id].stat.lastAlloc,
memClients[id].stat.currentlyAllocated,
memClients[id].stat.traverseCount, listcount, chunkcount);
}
void gMemPrintChunks(CmnClientId id, FILE *logfile)
{
MemChunk *p = memClients[id].first;
fprintf(logfile, "\n***************\n");
for (;;)
{
fprintf(logfile, "-------------------\n");
fprintf(logfile, "address: 0x%x\n", (unsigned int)p);
fprintf(logfile, "prev size: %d\n", prevsize(p));
fprintf(logfile, "size: %d\n", chunksize(p));
fprintf(logfile, "gc: %d, inuse: %d\n", chunk_has_gcbit(p),
chunk_inuse(p));
if (chunk_isfree(p) || (p == (MemChunk *)memClients[id].base))
{
fprintf(logfile, "fwd: 0x%x\n", (unsigned int)forward(p));
fprintf(logfile, "bck: 0x%x\n", (unsigned int)back(p));
}
if (p == memClients[id].last)
{
break;
}
p = nextchunk(p);
}
fprintf(logfile, "***************\n\n");
}
void gMemPrintClients(FILE *logfile)
{
fprintf(logfile, "\n");
}
void gMemPrintFreeList(CmnClientId id, FILE *logfile)
{
MemChunk *p;
SIZE_L sz;
short i;
fprintf(logfile, "Free list: ");
for (i = 0; i < NUM_FREE_LISTS; i++)
{
for (p = forward(memClients[id].freelists[i]);
p != memClients[id].freelists[i]; p = forward(p))
{
sz = chunksize(p);
fprintf(logfile, " %lu", sz);
}
}
fprintf(logfile, "\n");
}
void gMemPrintFragmentationStats(CmnClientId id, FILE *logfile)
{
MemChunk *p;
SIZE_L largestsize = 0;
SIZE_L totalfreesize = 0;
SIZE_L sz;
for (p = memClients[id].first; p != memClients[id].last; p = nextchunk(p))
{
if (chunk_isfree(p))
{
sz = chunksize(p);
totalfreesize += sz;
largestsize = MEM_MAX( largestsize, sz);
}
}
fprintf(logfile, "Fragmentation statistics, client %u\n", id);
fprintf(logfile, "==================================\n");
fprintf(logfile, "Total free size: %lu\nLargest chunk: %lu (%lu%%)\n",
totalfreesize, largestsize,
totalfreesize == 0 ? 0 : (largestsize * 100) / totalfreesize);
}
static void gMemPrintUsage(CmnClientId id, const char *filename, int lineno)
{
static FILE *file = NULL;
if (file == NULL)
{
file = fopen("MemoryUsage.log", "w+");
}
if (file == NULL)
{
CMN_LOG_I(("ERROR: Memory handling couldn't open log file. File locked or disk full?\n"));
return;
}
fprintf( file, "%d\t%s\t%d\n",
memClients[id].stat.currentlyAllocated, filename, lineno);
fflush(file);
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -