⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gmem.c

📁 彩信MMS的全部代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    
#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 + -