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

📄 mem.c

📁 本软件是TI公司免费提供的网络开发包 现在好象很难找到,有黑心的公司把它改一改,就卖价5000元,对网络开发和网络驱动开发有参考价值
💻 C
字号:
/*
 *  Copyright 2006 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *
 *  @(#) TCP/IP_Network_Developers_Kit 1.91.00.08 08-22-2006 (ndk-a08)
 */
//----------------------------------------------------------------------
// OS Demonstration Software
//----------------------------------------------------------------------
// File: mem.c
//
// Block Oriented Memory Manager
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//----------------------------------------------------------------------
#include <netmain.h>
#include <_oskern.h>

//-------------------------------------------------
// Raw Memory Configuration
//

// Total MAX Memory Allocation
#define RAW_PAGE_SIZE           3072
#define RAW_PAGE_COUNT          16

//-------------------------------------------------
// Memory Block Structures
//

// Memory Block
typedef struct {
                uint            Flags;
#define MBF_BUSY        0x8000
#define MBF_INDEXMASK   0x03FF
                UINT8           bData[1];
               } MEMORYBLOCK;

// P.I.T. Entry
typedef struct {
                UINT8           *pPageStart;
                uint            PageSize;
                uint            BlockSize;
                uint            BlockSizeIdx;
                uint            BlocksPerPage;
                uint            AllocCount;
                uint            IdxFreeCheck;
               } PITENTRY;

// P.I.T.
#pragma DATA_SECTION(pit, ".far:NDK_MMBUFFER");
PITENTRY pit[RAW_PAGE_COUNT];
#pragma DATA_SECTION(pitBuffer, ".far:NDK_MMBUFFER");
UINT8    pitBuffer[RAW_PAGE_SIZE*RAW_PAGE_COUNT];

// P.I.T. Info
uint   PITCount = 0;
uint   PITUsed  = 0;
uint   PITHigh  = 0;

//-------------------------------------------------
// Memory Bucket Information
//

#define MEMORY_ID_COUNT         7
#define SMALLEST                48
#define LARGEST                 (RAW_PAGE_SIZE)

// Memory Slot Tracking
#pragma DATA_SECTION(Id2Size, ".far:NDK_MMBUFFER");
uint Id2Size[]  = { SMALLEST, 96, 128, 256, 512, 1536, LARGEST };

// High Water Mark Tracking
int BlockMax[ MEMORY_ID_COUNT ];
int BlockCount[ MEMORY_ID_COUNT ];
int PageMax[ MEMORY_ID_COUNT ];
int PageCount[ MEMORY_ID_COUNT ];

static UINT32  mmCalls     = 0;
static UINT32  mmFrees     = 0;
static UINT32  mmFails     = 0;
static UINT32  mmBulkCalls = 0;
static UINT32  mmBulkFails = 0;
static UINT32  mmBulkFrees = 0;

//-------------------------------------------------
// Code Start
//

// Initialize the Memory System
int _mmInit()
{
    uint w;

    // Init PIT
    PITCount = RAW_PAGE_COUNT;
    PITCount = PITHigh = PITUsed = 0;
    for(w=0; w<RAW_PAGE_COUNT; w++)
    {
        pit[w].PageSize   = RAW_PAGE_SIZE;
        pit[w].pPageStart = pitBuffer + (RAW_PAGE_SIZE*w);
        pit[w].BlockSize  = 0;
        PITCount++;
    }

    // Init Block Statistics
    for(w=0; w<MEMORY_ID_COUNT; w++)
    {
        BlockMax[w]   = 0;
        BlockCount[w] = 0;
        PageMax[w]    = 0;
        PageCount[w]  = 0;
    }

    return(1);
}

// Initialize a new Page, subdividing into blocks
static void mmInitPage( uint PitIdx, uint SizeIdx )
{
    uint         w;
    uint         Inc;
    UINT8*        pb;

    // Init the PIT Entry
    pit[PitIdx].BlockSize     = Id2Size[SizeIdx];
    pit[PitIdx].BlockSizeIdx  = SizeIdx;
    pit[PitIdx].BlocksPerPage = pit[PitIdx].PageSize / Id2Size[SizeIdx];
    pit[PitIdx].AllocCount    = 0;
    pit[PitIdx].IdxFreeCheck  = 0;

    // Init the Memory Blocks in the New Page
    pb   = pit[PitIdx].pPageStart;
    Inc  = pit[PitIdx].BlockSize;
    for( w=0; w<pit[PitIdx].BlocksPerPage; w++ )
    {
        ((MEMORYBLOCK *)pb)->Flags = PitIdx;
        pb += Inc;
    }

    // Bump used count
    PITUsed++;
    if( PITUsed > PITHigh )
        PITHigh = PITUsed;

    // Maintian Page Block Statistics
    w = pit[PitIdx].BlockSizeIdx;
    PageCount[ w ]++;
    if( PageCount[ w ] > PageMax[ w ] )
        PageMax[ w ] = PageCount[ w ];
}

// Uninit an sub-divided Page
static void mmUnInitPage( uint PitIdx )
{
    // Init the PIT Entry
    pit[PitIdx].BlockSize = 0;

    // Dec used count
    PITUsed--;

    // Maintian Page Block
    PageCount[ pit[PitIdx].BlockSizeIdx ]--;
}

// Allocate Memory
void *mmAlloc( uint Size )
{
    uint UseSizeIdx,UseSize;
    uint PitIdx, PitFree, tmp1, tmp2;
    MEMORYBLOCK* pmb;
    uint CritState;

    // Get index to bucket size, including memory block rsvd uint
    UseSize = Size+sizeof(uint);

    // Verify size request at boundary conditions first
    if( UseSize <= SMALLEST )
        UseSizeIdx = 0;
    else if( UseSize > LARGEST )
        return(0);
    else
    {
        UseSizeIdx = MEMORY_ID_COUNT/2;
        if( Id2Size[UseSizeIdx] >= UseSize )
        {
            while( Id2Size[UseSizeIdx-1] >= UseSize )
                UseSizeIdx--;
        }
        else
        {
            while( Id2Size[UseSizeIdx] < UseSize )
                UseSizeIdx++;
        }
    }

    CritState = OEMSysCritOn();

    mmCalls++;

    // Look for a PIT already using this size
    PitIdx  = 0;                        // Index
    tmp1    = 0;                        // Number of PITs examined
    PitFree = PITCount;                 // Set "free" to invalid
    while( PitIdx < PITCount )
    {
        // Only examined blocks currently in use
        if( !pit[PitIdx].BlockSize )
            PitFree = PitIdx;
        else
        {
            // Bump the "examined" count of USED entries
            tmp1++;

            // See if we can use this page. It must be our size,
            // plus have an entry available
            if( pit[PitIdx].BlockSizeIdx == UseSizeIdx &&
                    pit[PitIdx].AllocCount < pit[PitIdx].BlocksPerPage )
                goto MMA_PITVALID;
        }

        // If we've checked all the used entries and have a free entry,
        // then use the free entry now
        if( tmp1 == PITUsed && PitFree != PITCount )
        {
            // Set Free Page
            PitIdx = PitFree;

            // Initialize free page
            mmInitPage( PitIdx, UseSizeIdx );

            goto MMA_PITVALID;
        }

        // Nothing found yet - try next entry
        PitIdx++;
    }

    // Here we didn't find a free or usable PIT, so we have an OOM
    // error or a fatal error
    if( PITUsed != PITCount )
        DbgPrintf(DBG_ERROR,"mmAlloc: PIT Used Sync");
    goto MMA_ERROR;

MMA_PITVALID:
    // Allocate the Memory
    UseSize = Id2Size[UseSizeIdx];

    // Init our search point (tmp1) to the most likely free block
    tmp1 = tmp2 = pit[PitIdx].IdxFreeCheck;

    pmb = (MEMORYBLOCK *)(pit[PitIdx].pPageStart+(tmp1*UseSize));

    // Find a free memory page
    while( pmb->Flags & MBF_BUSY )
    {
        // Bump the pmb
        if( ++tmp1 == pit[PitIdx].BlocksPerPage )
        {
            tmp1 = 0;
            pmb = (MEMORYBLOCK *)(pit[PitIdx].pPageStart);
        }
        else
            pmb = (MEMORYBLOCK *)((UINT8 *)pmb + UseSize );

        // Check for error (tmp1 wrapped)
        if( tmp1 == tmp2 )
        {
            // FATAL
            DbgPrintf(DBG_ERROR,"mmAlloc: PIT FreeBlk Sync");
            goto MMA_ERROR;
        }
    }

    // Allocate the memory page
    pmb->Flags |= MBF_BUSY;
    pit[PitIdx].AllocCount++;

    // Setup next possible free idx
    if( ++tmp1 == pit[PitIdx].BlocksPerPage )
        tmp1 = 0;
    pit[PitIdx].IdxFreeCheck = tmp1;

    // Maintain Block Statistics
    BlockCount[ UseSizeIdx ]++;
    if( BlockCount[ UseSizeIdx ] > BlockMax[ UseSizeIdx ] )
        BlockMax[ UseSizeIdx ] = BlockCount[ UseSizeIdx ];

    OEMSysCritOff( CritState );
    return( pmb->bData );

MMA_ERROR:
    mmFails++;
    OEMSysCritOff( CritState );
    return( 0 );
}

// Free Memory
void mmFree( void *p )
{
    MEMORYBLOCK* pmb;
    uint        PitIdx;
    uint        CritState;

    pmb = (MEMORYBLOCK *)((UINT8 *)p - sizeof(uint));

    // Check for double free
    if( !(pmb->Flags & MBF_BUSY) )
    {
        // FATAL
        DbgPrintf(DBG_WARN,"mmFree: Double Free");
        return;
    }

    // Get the index
    PitIdx = (uint)(pmb->Flags & MBF_INDEXMASK);

    CritState = OEMSysCritOn();

    mmFrees++;

    // Unallocate the block
    pmb->Flags &= ~MBF_BUSY;

    // Maintain Block
    BlockCount[ pit[PitIdx].BlockSizeIdx ]--;

    // Free the page if no blocks in use
    if( !(--pit[PitIdx].AllocCount) )
        mmUnInitPage( PitIdx );

    OEMSysCritOff( CritState );

    return;
}

// Memory Copy
void mmCopy( void* pDst, void* pSrc, uint len )
{
    UINT32 *pSrc32, *pDst32;
    UINT8  *pSrc8, *pDst8;

    // Fast Case
    if( !(((uint)pDst)&0x3) && !(((uint)pSrc)&0x3) )
    {
        pSrc32 = pSrc;
        pDst32 = pDst;

        while( len > 3 )
        {
            *pDst32++ = *pSrc32++;
            len -= 4;
        }

        if( len )
        {
            pSrc8 = (UINT8 *)pSrc32;
            pDst8 = (UINT8 *)pDst32;

            while( len-- )
                *pDst8++ = *pSrc8++;
        }
    }
    else
    {
        pSrc8 = pSrc;
        pDst8 = pDst;

        while( len-- )
            *pDst8++ = *pSrc8++;
    }
}

// Memory Clear
void mmZeroInit( void *pDst, uint len )
{
    UINT32 *pDst32;
    UINT8  *pDst8;

    pDst8 = pDst;

    // Copy 'till aligned
    while( (((uint)pDst8)&0x3) && len > 0 )
    {
        *pDst8++ = 0;
        len--;
    }

    if( len )
    {
        pDst32 = (UINT32 *)pDst8;

        // Copy 'till less than 4 bytes
        while( len > 3 )
        {
            *pDst32++ = 0;
            len -= 4;
        }

        if( len )
        {
            pDst8 = (UINT8 *)pDst32;

            // Copy 'till done
            while( len-- )
                *pDst8++ = 0;
        }
    }
}


static uint BulkSegId = 0;

//-------------------------------------------------------------
// _mmBulkAllocSeg
//
// This function is used to change the default segment for
// mmBulkAlloc() and mmBulkFree(). This function will only
// work if no calls to mmBulkAlloc() have been made.
//-------------------------------------------------------------
void _mmBulkAllocSeg( uint segId )
{
    uint CritState;

    CritState = OEMSysCritOn();

    if( !mmBulkCalls )
        BulkSegId = segId;

    OEMSysCritOff( CritState );
}


//-------------------------------------------------------------
// mmBulkAlloc
//
// This function is used to allocate memory larger than
// 3000 bytes
//-------------------------------------------------------------
void *mmBulkAlloc( INT32 Size )
{
    UINT32 *ptr;

    mmBulkCalls++;

    Size += 8;
    ptr = (UINT32 *)MEM_alloc( BulkSegId, Size, 4 );
    if( ptr != MEM_ILLEGAL )
    {
        *ptr = 0x87654321;
        *(ptr+1) = (UINT32)Size;
        return( (void *)(ptr+2) );
    }

    mmBulkFails++;

    return(0);
}

//-------------------------------------------------------------
// mmBulkFree
//
// This function is used to free memory allocated with
// mmBulkAlloc()
//-------------------------------------------------------------
void mmBulkFree( void *pMemory )
{
    UINT32 *ptr = (UINT32 *)pMemory;

    if( !ptr )
    {
        DbgPrintf(DBG_ERROR,"mmBulkFree: NULL pointer");
        return;
    }
    ptr -= 2;
    if( *ptr != 0x87654321 )
    {
        DbgPrintf(DBG_ERROR,"mmBulkFree: Corrupted mem or bad ptr (%08x)",ptr);
        return;
    }

    mmBulkFrees++;
    MEM_free( BulkSegId, ptr, *(ptr+1) );
}

//-------------------------------------------------------------
// Memory Check
//
// CallMode MMCHECK_MAP      : Map out allocated memory, but
//                             don't dump ID's
//          MMCHECK_DUMP     : Dump allocated block ID's
//          MMCHECK_SHUTDOWN : Dump allocated block's & free
//-------------------------------------------------------------
void _mmCheck( uint CallMode, int (*pPrn)(const char *,...) )
{
    uint   w;
    UINT32 tmp;
    uint   SizeIdx;
    UINT32 Total;
    uint   PitIdx;

    if( !pPrn )
        goto SHUTDOWN;

    // Memory Usage
    SizeIdx = 0;
    Total    = 0;
    while( SizeIdx < MEMORY_ID_COUNT )
    {
        if( !(SizeIdx&3) )
            (*pPrn)("\n");
        (*pPrn)("%4u:%-4u ",BlockMax[SizeIdx],Id2Size[SizeIdx]);
        tmp = (UINT32)(BlockMax[SizeIdx]) * (UINT32)(Id2Size[SizeIdx]);
        Total  += tmp;
        if(tmp)
            (*pPrn)("(%3d%%)  ",
            (tmp*100)/((UINT32)PageMax[SizeIdx]*(UINT32)RAW_PAGE_SIZE));
        else
            (*pPrn)("        ");

        SizeIdx++;
    }

    (*pPrn)("\n(%u/", PITHigh*(UINT32)RAW_PAGE_SIZE);
    (*pPrn)("%u",     PITCount*(INT32)RAW_PAGE_SIZE);
    (*pPrn)(" mmAlloc: %u/%u/%u,",mmCalls,mmFails,mmFrees);
    (*pPrn)(" mmBulk: %u/%u/%u)\n",mmBulkCalls,mmBulkFails,mmBulkFrees);

    // Walk Memory
    if( PITUsed )
    {
        (*pPrn)("\n");
        for( PitIdx=0; PitIdx<PITCount; PitIdx++ )
        {
            if( pit[PitIdx].BlockSize )
            {
                MEMORYBLOCK *pmb;

                if( !pit[PitIdx].AllocCount )
                    (*pPrn)("IE: No blocks in alloced page\n");
                else
                    (*pPrn)("%d blocks alloced in %d byte page\n",
                           pit[PitIdx].AllocCount, pit[PitIdx].BlockSize );

                if( CallMode != MMCHECK_MAP )
                {
                    w = 0;
                    while( w < pit[PitIdx].BlocksPerPage )
                    {
                        pmb = (MEMORYBLOCK *) (pit[PitIdx].pPageStart +
                                               (w*pit[PitIdx].BlockSize));
                        if( pmb->Flags & MBF_BUSY )
                            (*pPrn)("(%04X)  ", *((uint *)pmb->bData));
                        w++;
                    }
                    (*pPrn)("\n");
                }
            }
        }
    }

    (*pPrn)("\n");

SHUTDOWN:
    if( CallMode == MMCHECK_SHUTDOWN )
        PITCount = 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -