📄 mem5xx.c
字号:
/****************************************************************************/
/* memory.c v1.02 */
/* Copyright (c) 1993-1996 Texas Instruments Incorporated */
/****************************************************************************/
/*****************************************************************************/
/* */
/* This module contains the functions which implement the dynamic memory */
/* management routines for DSP C. The following assumptions/rules apply: */
/* */
/* 1) Packets are allocated a minimum of one word, max 32k words. */
/* 2) The heap can be reset at any time by calling the function "minit" */
/* */
/* The following items are defined in this module : */
/* minit() : Function to initialize dynamic memory management */
/* malloc() : Function to allocate memory from mem mgmt system. */
/* calloc() : Allocate an clear memory from mem mgmt system. */
/* realloc() : Reallocate a packet */
/* free() : Function to free allocated memory. */
/* */
/* minsert() : Insert a packet into free list, sorted by size */
/* mremove() : Remove a packet from the free list. */
/* */
/* _sys_memory : Array to contain all memory allocate by system. */
/* sys_free : Pointer to free list */
/* */
/*****************************************************************************/
#undef _INLINE /* DISABLE INLINE EXPANSION */
#include <stdlib.h>
#include <string.h>
/*****************************************************************************/
/* Declare the memory pool as a .usect called .sysmem. The size of the */
/* section .sysmem is determined by the linker via the -heap option */
/*****************************************************************************/
asm("__sys_memory .usect \".sysmem\",0");
extern int _sys_memory[];
/*****************************************************************************/
/* __SYSMEM_SIZE is symbol that the linker defines as the size of the heap. */
/* Access of that value from 'C' is done by taking the address of this symbol*/
/*****************************************************************************/
extern unsigned int _SYSMEM_SIZE;
#define MEMORY_SIZE ((unsigned int)&_SYSMEM_SIZE)
/*****************************************************************************/
/* "PACKET" is the template for a data packet. Packet size contains */
/* the number of words allocated for the user, excluding the size */
/* required for management of the packet (32 bits). Packets are always */
/* allocated in words. A negative size indicates a free packet. */
/*****************************************************************************/
typedef struct pack {
long packet_size; /* in words */
struct pack *size_ptr;
}
PACKET;
#define NIL (PACKET *)0
/*****************************************************************************/
/* POINTER TO THE LIST OF FREE BLOCKS */
/*****************************************************************************/
static PACKET *sys_free;
/*****************************************************************************/
/* */
/* MINSERT - Insert a packet into the free list. This list is sorted by */
/* size in increasing order. */
/* */
/*****************************************************************************/
static void minsert(PACKET *ptr)
{
PACKET *current = (PACKET *) sys_free;
PACKET *last = NIL;
/********************************************************************/
/* CHECK SPECIAL CASE, EMPTY FREE LIST. */
/********************************************************************/
if (current == NIL)
{
sys_free = ptr;
ptr->size_ptr = NIL;
return;
}
/********************************************************************/
/* SCAN THROUGH LIST, LOOKING FOR A LARGER PACKET. */
/********************************************************************/
while ((current != NIL) && (current->packet_size > ptr->packet_size))
{
last = current;
current = current->size_ptr;
}
/********************************************************************/
/* LINK THE NEW PACKET INTO THE LIST. THERE ARE THREE CASES : */
/* THE NEW POINTER WILL EITHER BE THE FIRST, THE LAST, OR IN THE */
/* MIDDLE SOMEWHERE. */
/********************************************************************/
if (current == NIL) /* PTR WILL BE LAST IN LIST */
{
last->size_ptr = ptr;
ptr->size_ptr = NIL;
}
else if (last == NIL) /* PTR WILL BE FIRST IN THE LIST */
{
ptr->size_ptr = sys_free;
sys_free = ptr;
}
else /* PTR IS IN THE MIDDLE OF THE LIST */
{
ptr->size_ptr = current;
last->size_ptr = ptr;
}
}
/*****************************************************************************/
/* */
/* MREMOVE - REMOVE A PACKET FROM THE FREE LIST. */
/* */
/*****************************************************************************/
static void mremove(PACKET *ptr)
{
PACKET *current = sys_free;
PACKET *last = NIL;
/********************************************************************/
/* SCAN THROUGH LIST, LOOKING FOR PACKET TO REMOVE */
/********************************************************************/
while ((current != NIL) && (current != ptr))
{
last = current;
current = current->size_ptr;
}
/********************************************************************/
/* REMOVE THE PACKET FROM THE LIST. THERE ARE TWO CASES : */
/* THE OLD POINTER WILL EITHER BE THE FIRST, OR NOT THE FIRST. */
/********************************************************************/
if (current == NIL) /* POINTER NOT FOUND IN LIST */
sys_free = NIL; /* FATAL ERROR */
else if (last == NIL) /* PTR WAS BE FIRST IN THE LIST */
sys_free = ptr->size_ptr;
else /* PTR IS IN THE MIDDLE OF THE LIST */
last->size_ptr = ptr->size_ptr;
}
/*****************************************************************************/
/* */
/* MINIT - This function can be called by the user to completely reset the */
/* memory management system. */
/* */
/*****************************************************************************/
void minit(void)
{
/************************************************************************/
/* TO INITIALIZE THE MEMORY SYSTEM, DEALLOCATE ONE PACKET WHICH USES */
/* AVAILABLE MEMORY AND INITIALIZE THE FREE LIST TO POINT TO IT. */
/* ENSURE CORRECT ALIGNMENT BY MAKING SURE SYS_FREE IS ON AN EVEN */
/* BOUNDARY. THIS GUARANTEES FIRST PACKET WILL BE ON AN EVEN BOUNDARY. */
/************************************************************************/
if (((unsigned int)_sys_memory & 1) == 0)
{
sys_free = (PACKET *) _sys_memory;
sys_free->packet_size = -(long) (MEMORY_SIZE - 2);
}
else
{
_sys_memory[0] = 0;
sys_free = (PACKET *) (_sys_memory + 1);
sys_free->packet_size = -(long) (MEMORY_SIZE - 3);
}
sys_free->size_ptr = NIL;
}
/*****************************************************************************/
/* */
/* MALLOC - Allocate a packet of a given size, and return pointer to it. */
/* This function only allocates in multiple of ints. */
/* */
/*****************************************************************************/
void *malloc(size_t usersize)
{
long size = usersize;
PACKET *current;
long oldsize;
static int first_call = 1;
if (first_call) { minit(); first_call = 0; }
current = sys_free;
if (size < 0) return(0);
if ((size & 1) == 1) ++size; /* MAKE SURE SIZE IS EVEN */
/***********************************************************************/
/* SCAN THROUGH FREE LIST FOR PACKET LARGE ENOUGH TO CONTAIN PACKET */
/* REMEMBER THAT FREE PACKAGE SIZES ARE NEGATIVE, SO NEGATE SIZE. */
/***********************************************************************/
size = -size;
while ((current != NIL) && (current->packet_size > size))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -