📄 mallocx.c
字号:
/******************************************************************************
**
** COPYRIGHT (C) 2001 Intel Corporation
**
** FILENAME: mallocx.c
**
** PURPOSE: A general purpose implementation of "malloc" and "free".
**
** $Modtime: 7/17/03 1:01p $
**
******************************************************************************/
/*
*******************************************************************************
* HEADER FILES
*******************************************************************************
*/
#include <stdio.h>
#include "systypes.h"
#include "dm_errors.h"
#include "cotulla.h"
#define MALLOCX_GLOBALS
#include "mallocx.h"
#define ALIGN 16
#define HEAPSIZE (HEAPEND-HEAPADDR)
// sizeof(MemBlockT) must be <= ALIGN !
typedef struct {
PUINT8 pAddr; // The physical address of this block,
// same as the Non-Cached, Non-Buffered address.
PUINT8 cbAddr; // Cached, Buffered virtual address of this block.
PUINT8 cxAddr; // Cached, Non-Buffered virtual address of this block.
UINT32 size;
} MemBlockT;
ErrorT retVal;
/*
*******************************************************************************
*
* FUNCTION: malloc
*
* DESCRIPTION: Implements the standard "malloc" function.
* Allocates a 16-byte-aligned memory block from the heap.
*
* INPUT PARAMETERS: UINT32 size - Size of requested allocation in bytes.
* -1 = get largest available.
*
* RETURNS: A pointer to the allocated memory or NULL on error.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: The heap is identity mapped as non-cached, non-buffered
* for DMA usage. It may also be mapped elsewhere for
* "normal" usage.
*
* CALLS: None.
*
* CALLED BY: Anyone.
*
* PROTOTYPE: PVOID malloc(UINT32 size)
*
*******************************************************************************
*/
extern int print_malloc;
PVOID malloc(UINT32 size)
{
MemBlockT *memBlockP, *nextMemBlockP, *largestMemBlockP;
largestMemBlockP = memBlockP = (MemBlockT *)HEAPADDR;
if (size != -1) {
size += ALIGN; // Allow room for the header.
size = ((size+ALIGN-1)/ALIGN)*ALIGN; // Round up to a multiple of "ALIGN" bytes.
}
if (
(BYTE *)memBlockP > HEAPEND ||
memBlockP->size > HEAPSIZE ||
memBlockP->size == 0 ||
memBlockP->size%ALIGN != 0
) {
retVal = ERRORCODEX(ERR_L_HEAP, 0, 0, ERR_T_UNEXPECTED); // Corrupt chain.
return NULL;
}
while (memBlockP->cbAddr || memBlockP->size < size)
{
nextMemBlockP = (MemBlockT *)((BYTE *)memBlockP + memBlockP->size);
if ((BYTE *)nextMemBlockP == HEAPEND) {
memBlockP = largestMemBlockP;
if (size == -1 && !memBlockP->cbAddr) goto out;
retVal = ERRORCODEX(ERR_L_HEAP, 0, 0, ERR_T_NO_MEM_AVAIL); // No room.
return NULL;
}
if (
(BYTE *)nextMemBlockP > HEAPEND ||
nextMemBlockP->size > HEAPSIZE ||
nextMemBlockP->size == 0 ||
nextMemBlockP->size%ALIGN != 0
) {
retVal = ERRORCODEX(ERR_L_HEAP, 0, 1, ERR_T_UNEXPECTED); // Corrupt chain.
return NULL;
}
// Try to combine two free blocks
if (!memBlockP->cbAddr && !nextMemBlockP->cbAddr)
memBlockP->size += nextMemBlockP->size;
else memBlockP = nextMemBlockP;
if (
!memBlockP->cbAddr && (
largestMemBlockP->cbAddr ||
memBlockP->size > largestMemBlockP->size
)
) largestMemBlockP = memBlockP;
}
// Found room!
nextMemBlockP = (MemBlockT *)((BYTE *)memBlockP + size);
// Do we have room to split the block?
if (memBlockP->size > size) {
nextMemBlockP->size = memBlockP->size - size;
memBlockP->size = size;
nextMemBlockP->cbAddr = NULL;
nextMemBlockP->cxAddr = NULL;
nextMemBlockP->pAddr = (BYTE *)nextMemBlockP;
}
// Continue on to audit the heap integrity.
while ((BYTE *)nextMemBlockP != HEAPEND) {
if (
(BYTE *)nextMemBlockP > HEAPEND ||
nextMemBlockP->size > HEAPSIZE ||
nextMemBlockP->size == 0 ||
nextMemBlockP->size%ALIGN != 0
) {
retVal = ERRORCODEX(ERR_L_HEAP, 0, 2, ERR_T_UNEXPECTED); // Corrupt chain.
return NULL;
}
nextMemBlockP = (MemBlockT *)((BYTE *)nextMemBlockP + nextMemBlockP->size);
}
out:
retVal = ERR_NONE;
memBlockP->cbAddr = (((BYTE *)memBlockP) - MEMORYSTART) + MEMORYCACHEDBUFFEREDSTART;
memBlockP->cxAddr = (((BYTE *)memBlockP) - MEMORYSTART) + MEMORYCACHEDSTART;
// Point past the header.
return (PVOID)((BYTE *)memBlockP + ALIGN);
}
/*
*******************************************************************************
*
* FUNCTION: free
*
* DESCRIPTION: Free a memory block allocated by malloc or mallocx.
*
* INPUT PARAMETERS: A pointer to the memory block.
*
* RETURNS: An error code.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: None.
*
* CALLS: None.
*
* CALLED BY: Anyone.
*
* PROTOTYPE: ErrorT free(PVOID pAddr)
*
*******************************************************************************
*/
ErrorT free(PVOID pAddr)
{
MemBlockT *memBlockP;
memBlockP = (MemBlockT *)HEAPADDR;
// Get the physical address of this block.
pAddr = (PVOID)(((MemBlockT *)((BYTE *)pAddr - ALIGN))->pAddr);
while (pAddr != memBlockP) {
if (
(BYTE *)memBlockP > HEAPEND ||
memBlockP->size > HEAPSIZE ||
memBlockP->size == 0 ||
memBlockP->size%ALIGN != 0
) return ERRORCODEX(ERR_L_HEAP, 1, 0, ERR_T_UNEXPECTED); // Corrupt chain.
memBlockP = (MemBlockT *)((BYTE *)memBlockP + memBlockP->size);
if ((BYTE *)memBlockP == HEAPEND)
return ERRORCODEX(ERR_L_HEAP, 1, 1, ERR_T_ILLPARAM); // Block not found in chain.
}
memBlockP->cbAddr = NULL; // We found it!
memBlockP->cxAddr = NULL;
// Continue on to audit the heap integrity.
do {
if (
(BYTE *)memBlockP > HEAPEND ||
memBlockP->size > HEAPSIZE ||
memBlockP->size == 0 ||
memBlockP->size%ALIGN != 0
) return ERRORCODEX(ERR_L_HEAP, 1, 2, ERR_T_UNEXPECTED); // Corrupt chain.
memBlockP = (MemBlockT *)((BYTE *)memBlockP + memBlockP->size);
} while ((BYTE *)memBlockP != HEAPEND);
return ERR_NONE;
}
/*
*******************************************************************************
*
* FUNCTION: mallocx
*
* DESCRIPTION: Legacy function.
*
* INPUT PARAMETERS:
* size - Size of requested allocation in bytes. -1 = get largest available.
* virtualAddr - Where to return the vitual address of the allocated block.
* physicalAddr - Where to return the physical address of the allocated block.
*
* RETURNS: An error code.
* virtualAddr and physicalAddr are filled in with the
* corresponding values or NULL if there is an error.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: None.
*
* CALLS: None.
*
* CALLED BY: Anyone.
*
* PROTOTYPE:
* ErrorT mallocx(UINT32 size, void **virtualAddr, void **physicalAddr);
*
*******************************************************************************
*/
ErrorT mallocx(UINT32 size, void **virtualAddr, void **physicalAddr)
{
*virtualAddr = *physicalAddr = malloc(size);
return retVal;
}
/*
*******************************************************************************
*
* FUNCTION: mallocxSWInit
*
* DESCRIPTION: Allocate and initialize the heaps.
*
* INPUT PARAMETERS: None.
*
* RETURNS: Nothing.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: None.
*
* CALLS: None.
*
* CALLED BY: System.
*
* PROTOTYPE: void mallocxSWInit(void)
*
*******************************************************************************
*/
void mallocxSWInit(void)
{
((MemBlockT *)HEAPADDR)->pAddr = HEAPADDR;
((MemBlockT *)HEAPADDR)->cbAddr = NULL; // Mark free.
((MemBlockT *)HEAPADDR)->cxAddr = NULL;
((MemBlockT *)HEAPADDR)->size = HEAPSIZE;
}
/*
*******************************************************************************
*
* FUNCTION: mallocSize
*
* DESCRIPTION: Return the size of an allocated block.
*
* INPUT PARAMETERS: A pointer to the memory block.
*
* RETURNS: The size of the allocated block.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: None.
*
* CALLS: None.
*
* CALLED BY: Anyone.
*
* PROTOTYPE: UINT32 mallocSize(PVOID pAddr);
*
*******************************************************************************
*/
UINT32 mallocSize(PVOID pAddr)
{
// Look back at the header.
return ((MemBlockT *)(((PUINT8)pAddr)-ALIGN))->size - ALIGN;
}
/*
*******************************************************************************
*
* FUNCTION: malloc_cb
*
* DESCRIPTION: Get the Cached, Buffered address of an allocated block.
*
* INPUT PARAMETERS: A pointer to the memory block.
*
* RETURNS: The Cached, Buffered address of the allocated block.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: None.
*
* CALLS: None.
*
* CALLED BY: Anyone.
*
* PROTOTYPE: PVOID malloc_cb(PVOID pAddr);
*
*******************************************************************************
*/
PVOID malloc_cb(PVOID pAddr)
{
// Look back at the header.
return ((MemBlockT *)(((PUINT8)pAddr)-ALIGN))->cbAddr + ALIGN;
}
/*
*******************************************************************************
*
* FUNCTION: malloc_cx
*
* DESCRIPTION: Get the Cached, Non-Buffered address of an allocated block.
*
* INPUT PARAMETERS: A pointer to the memory block.
*
* RETURNS: The Cached, Non-Buffered address of the allocated block.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: None.
*
* CALLS: None.
*
* CALLED BY: Anyone.
*
* PROTOTYPE: PVOID malloc_cx(PVOID pAddr);
*
*******************************************************************************
*/
PVOID malloc_cx(PVOID pAddr)
{
// Look back at the header.
return ((MemBlockT *)(((PUINT8)pAddr)-ALIGN))->cxAddr + ALIGN;
}
/*
*******************************************************************************
*
* FUNCTION: mallocErr
*
* DESCRIPTION: Get the error code from the last malloc().
*
* INPUT PARAMETERS: None.
*
* RETURNS: The error code.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: None.
*
* CALLS: None.
*
* CALLED BY: Anyone.
*
* PROTOTYPE: ErrorT mallocErr(void);
*
*******************************************************************************
*/
ErrorT mallocErr(void)
{
// Look back at the header.
return retVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -