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

📄 srallo.c

📁 简单的动态分配函数
💻 C
字号:
#ifdef __cplusplus
extern "C" {
#endif

#include "srallo.h"

/*********************************************************************
 *Example:
 *  ----------
 *  |  0x7F  |  0x200   Header Seg1 (not allocated)
 *  |        |
 *  |        |
 *  |        |
 *  |        |
 *  |        |
 *  |        |
 *  |  0x89  |  0x280   Header Seg2 (allocated)
 *  |        |
 *  |        |
 *  |  0x00  |  0x30A   Header Seg3 (not allocated)
 *  |  0x73  |  0x30B   Header Seg4 (not allocated)
 *  |        |
 *  |        |
 *  |        |
 *  |        |
 *  |        |
 *  |        |
 *  |  0x80  |  0x37F   Tail
 *  ----------
 ********************************************************************/

/*********************************************************************
 * Reserve the memory heap
 ********************************************************************/

USIGN8 _uDynamicHeap[MAX_HEAP_SIZE];


/*********************************************************************
 * Private function declarations
 ********************************************************************/
static BOOL _SRAMmerge(SALLOC *pSegA);


/*********************************************************************
 * Function:        unsigned char * SRAMalloc(unsigned char length)
 ********************************************************************/

USIGN8 *SRAMalloc(USIGN8 nBytes)
{
    SALLOC  *pHeap;
    SALLOC  segHeader;
    USIGN8  segLen;
    SALLOC  *temp;

    ENTER_CRITICAL();

    // Do not allow allocation above the max minus one bytes.  Also, do
    // not allow a zero length packet.  Could cause problems.
    if ((nBytes > _MAX_SEGMENT_SIZE)||(nBytes == 0))
    	goto end;

    // Init the pointer to the heap
    pHeap = (SALLOC *)_uDynamicHeap;

    while (1)
    	{
        // Get the header of the segment
        segHeader = *pHeap;

        // Extract the segment length from the segment
        segLen = segHeader.bits.count;

        // A null segment indicates the end of the table
        if (segHeader.byte == 0x80)
        	break;

        // If this segment is not allocated then attempt to allocate it	
        if (!(segHeader.bits.alloc))
        	{
            // If the free segment is too small then attempt to merge
            if (segLen < nBytes)
            	{
                // If the merge fails them move on to the next segment
                if (!(_SRAMmerge(pHeap)))
                	{
                    pHeap +=(USIGN16)segHeader.bits.count + 1;
                	}
                // Fall through so we can check the newly created segment.
            	}

            // If the segment length matches the request then allocate the
            // header and return the pointer
            else if (nBytes == segLen)
            	{
                // Allocate the segment
                pHeap->bits.alloc = 1;

                // Return the pointer to the caller
                EXIT_CRITICAL();
                return ((unsigned char *)(pHeap + 1));
            	}

            // Else create a new segment
            else
            	{
                // Reset the header to point to a new segment
                pHeap->byte = nBytes + 0x80;

                // Remember the pointer to the first segment
                temp = pHeap + 1;

                // Point to the new segment
                pHeap += (USIGN16)nBytes + 1;

                // Insert the header for the new segment
                pHeap->byte = segLen - nBytes - 1;

                // Return the pointer to the user
                EXIT_CRITICAL();
                return ((unsigned char *) temp);
            	}
        	}

        // else set the pointer to the next segment header in the heap
        else
        	{
            pHeap += (USIGN16)segHeader.bits.count + 1;
        	}
    	}
end:
    EXIT_CRITICAL();
    return (NULL);
}

/*********************************************************************
 * Function:        void SRAMfree(unsigned char * pSRAM)
 ********************************************************************/
void SRAMfree(USIGN8 *pSRAM)
{
    SALLOC *pHeap, *pNextBlock;

    pHeap = (SALLOC *)_uDynamicHeap;
	
	ENTER_CRITICAL();
	while(pHeap->byte != 0x80)
		{
		pNextBlock = pHeap + (USIGN16)pHeap->bits.count + 1U;
		if(pSRAM < (USIGN8 *)pNextBlock && pSRAM > (USIGN8 *)pHeap)
			{
			// Release the segment
			pHeap->bits.alloc = 0;
			break;
			}
		else
			pHeap = pNextBlock;
		}


	EXIT_CRITICAL();	
}

/*********************************************************************
 * Function:        void SRAMInitHeap(void)
 ********************************************************************/
void SRAMInitHeap(void)
{
    USIGN8 * pHeap;
    USIGN16 count;

    pHeap = _uDynamicHeap;
    count = _MAX_HEAP_SIZE;

    while (1)
    	{
        if (count > _MAX_SEGMENT_SIZE)
        	{
            *pHeap = _MAX_SEGMENT_DATA_SIZE;
            pHeap += _MAX_SEGMENT_SIZE;
            count = count - _MAX_SEGMENT_SIZE;
        	}
        else
        	{
            *pHeap = count - 1;
            *(pHeap + count) = 0x80;	//add tail
            return;
        	}
    	}
}

/*********************************************************************
 * Function:        unsigned char _SRAMmerge(SALLOC * pSegA)
 ********************************************************************/
static BOOL _SRAMmerge(SALLOC *pSegA)
{
    SALLOC * pSegB;
    SALLOC uSegA, uSegB, uSum;

    // Init the pointer to the heap
    pSegB = pSegA + (USIGN16)(pSegA->bits.count) + 1;

    // Extract the headers for faster processing
    uSegA = *pSegA;
    uSegB = *pSegB;

    // Quit if the tail has been found
    if (uSegB.byte == 0x80)
    {
        return (FALSE);
    }

    // If either segment is allocated then do not merge
    if (uSegA.bits.alloc || uSegB.bits.alloc)
    {
        return (FALSE);
    }

    // If the first segment is max then nothing to merge
    if (uSegA.bits.count == _MAX_SEGMENT_DATA_SIZE)
    {
        return (FALSE);
    }

    // Get the sum of the two segments
    uSum.byte = (uSegA.byte + 1) + (uSegB.byte + 1);


    // If the sum of the two segments are > than the largest segment
    // then create a new segment equal to the max segment size and
    // point to the next segments
    if ((uSum.byte) > _MAX_SEGMENT_SIZE)
    {
        pSegA->byte = _MAX_SEGMENT_DATA_SIZE;
        pSegA += _MAX_SEGMENT_SIZE;
        pSegA->byte = uSum.byte - _MAX_SEGMENT_SIZE - 1;

        return (TRUE);
    }
    // Else combine the two segments into one segment and
    // do not adjust the pointers to the next segment
    else
    {
        pSegA->byte = uSum.byte - 1;
        return (TRUE);
    }
}

#ifdef __cplusplus
}
#endif

⌨️ 快捷键说明

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