702 lines
16 KiB
C
702 lines
16 KiB
C
#include "mymem.h"
|
||
#include "sdram.h"
|
||
|
||
|
||
|
||
// 定义是否使用ccm内存,1,使用,0,不使用
|
||
#define USE_CCM 0
|
||
|
||
|
||
#ifndef BOOTLOADER
|
||
#define OS_RTT
|
||
#ifdef OS_RTT
|
||
#include "rthw.h"
|
||
#define IRQ_DISABLE() rt_enter_critical()
|
||
#define IRQ_ENABLE() rt_exit_critical()
|
||
#else
|
||
#include "os.h"
|
||
#define IRQ_DISABLE() {CPU_SR_ALLOC(); CPU_CRITICAL_ENTER();}
|
||
#define IRQ_ENABLE() CPU_CRITICAL_EXIT()
|
||
#endif
|
||
#else
|
||
#define IRQ_DISABLE() { }
|
||
#define IRQ_ENABLE() { }
|
||
#endif
|
||
|
||
|
||
static void exmem_init(void); //内存管理初始化函数
|
||
static u32 exmem_malloc(u32 size); //内存分配
|
||
static u8 exmem_free(u32 offset); //内存释放
|
||
|
||
static void mem_init(void); //内存管理初始化函数
|
||
static u32 mem_malloc(u32 size); //内存分配
|
||
static u8 mem_free(u32 offset); //内存释放
|
||
|
||
static void ccm_init(void) ;
|
||
|
||
|
||
|
||
void mymem_init (void)
|
||
{
|
||
mem_init ();
|
||
exmem_init( );
|
||
// ccm_init();
|
||
}
|
||
|
||
|
||
#define EXMEM_BLOCK_SIZE (256) //内存块大小为64字节
|
||
|
||
#define EXMEM_MAX_SIZE ((uint64_t)((SDRAM_USER_SIZE))*EXMEM_BLOCK_SIZE/(EXMEM_BLOCK_SIZE+2))
|
||
#define EXMEM_ALLOC_TABLE_SIZE ((u32)(EXMEM_MAX_SIZE/EXMEM_BLOCK_SIZE)&(~3)) //内存表大小,必须为偶数,双字对齐
|
||
|
||
|
||
|
||
//分配的内存都是双字对齐的
|
||
#define EXMEM_BASE ((u8 *)(SDRAM_USER_ADDR+EXMEM_ALLOC_TABLE_SIZE*2))
|
||
#define EXMEMMAP_BASE ((u16 *)(SDRAM_USER_ADDR))
|
||
|
||
//内存管理参数
|
||
u32 exmemtblsize ; //内存表大小
|
||
u32 exmemblksize; //内存分块大小
|
||
uint64_t exmemsize ; //内存总大小
|
||
|
||
|
||
//内存管理控制器
|
||
struct _m_mallco_dev exmallco_dev;
|
||
|
||
//复制内存
|
||
//*des:目的地址
|
||
//*src:源地址
|
||
//n:需要复制的内存长度(字节为单位)
|
||
void mymemcpy(void *des,void *src,u32 n)
|
||
{
|
||
u8 *xdes=des;
|
||
u8 *xsrc=src;
|
||
while(n--)*xdes++=*xsrc++;
|
||
}
|
||
|
||
//设置内存
|
||
//*s:内存首地址
|
||
//c :要设置的值
|
||
//count:需要设置的内存大小(字节为单位)
|
||
void mymemset(void *s,u8 c,u32 count)
|
||
{
|
||
u8 *xs = s;
|
||
while(count--)*xs++=c;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//内存管理初始化
|
||
//memx:所属内存块
|
||
static void exmem_init(void)
|
||
{
|
||
exmemtblsize = EXMEM_ALLOC_TABLE_SIZE; //内存表大小
|
||
exmemblksize = EXMEM_BLOCK_SIZE; //内存分块大小
|
||
exmemsize = EXMEM_MAX_SIZE; //内存总大小
|
||
|
||
exmallco_dev.membase=EXMEM_BASE; //内存池
|
||
exmallco_dev.memmap=EXMEMMAP_BASE; //内存管理状态表
|
||
exmallco_dev.memrdy=0; //内存管理未就绪
|
||
|
||
|
||
mymemset(exmallco_dev.memmap, 0,exmemtblsize*2);//内存状态表数据清零
|
||
mymemset(exmallco_dev.membase, 0,exmemsize); //内存池所有数据清零
|
||
exmallco_dev.memrdy=1; //内存管理初始化OK
|
||
}
|
||
|
||
//获取内存使用率
|
||
//memx:所属内存块
|
||
//返回值:使用率(0~100)
|
||
int exmem_perused(void)
|
||
{
|
||
u32 used=0;
|
||
u32 i;
|
||
for(i=0;i<exmemtblsize;i++)
|
||
{
|
||
if(exmallco_dev.memmap[i])used++;
|
||
}
|
||
return (used*10000)/(exmemtblsize);
|
||
}
|
||
|
||
//内存分配(内部调用)
|
||
//memx:所属内存块
|
||
//size:要分配的内存大小(字节)
|
||
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
|
||
static u32 exmem_malloc(u32 size)
|
||
{
|
||
signed long offset=0;
|
||
u32 nmemb; //需要的内存块数
|
||
u32 cmemb=0;//连续空内存块数
|
||
u32 i;
|
||
// if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化
|
||
if(size==0)return 0XFFFFFFFF;//不需要分配
|
||
|
||
nmemb=size/exmemblksize; //获取需要分配的连续内存块数
|
||
if(size%exmemblksize)nmemb++;
|
||
for(offset=exmemtblsize-1;offset>=0;offset--)//搜索整个内存控制区
|
||
{
|
||
if(!exmallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
|
||
else cmemb=0; //连续内存块清零
|
||
if(cmemb==nmemb) //找到了连续nmemb个空内存块
|
||
{
|
||
for(i=0;i<nmemb;i++) //标注内存块非空
|
||
{
|
||
exmallco_dev.memmap[offset+i]=nmemb;
|
||
}
|
||
return (offset*exmemblksize);//返回偏移地址
|
||
}
|
||
}
|
||
return 0XFFFFFFFF;//未找到符合分配条件的内存块
|
||
}
|
||
|
||
//释放内存(内部调用)
|
||
//memx:所属内存块
|
||
//offset:内存地址偏移
|
||
//返回值:0,释放成功;1,释放失败;
|
||
static u8 exmem_free(u32 offset)
|
||
{
|
||
u32 i;
|
||
if(!exmallco_dev.memrdy)//未初始化,先执行初始化
|
||
{
|
||
//mallco_dev.init();
|
||
return 1;//未初始化
|
||
}
|
||
if(offset<exmemsize)//偏移在内存池内.
|
||
{
|
||
u32 index=offset/exmemblksize; //偏移所在内存块号码
|
||
u32 nmemb=exmallco_dev.memmap[index]; //内存块数量
|
||
for(i=0;i<nmemb;i++) //内存块清零
|
||
{
|
||
exmallco_dev.memmap[index+i]=0;
|
||
}
|
||
return 0;
|
||
}else return 2;//偏移超区了.
|
||
}
|
||
|
||
|
||
|
||
|
||
//------------------------------------内部SRAM---------------------------------------
|
||
|
||
|
||
#define SRAM_USER_SIZE (120*1024)
|
||
u8 g_sram_mem[SRAM_USER_SIZE];
|
||
|
||
#define MEM_BLOCK_SIZE (32) //内存块大小为64字节
|
||
|
||
#define MEM_MAX_SIZE (((SRAM_USER_SIZE))*MEM_BLOCK_SIZE/(MEM_BLOCK_SIZE+2))
|
||
#define MEM_ALLOC_TABLE_SIZE ((MEM_MAX_SIZE/MEM_BLOCK_SIZE)&(~3)) //内存表大小,必须为偶数,双字对齐
|
||
|
||
#define SRAM_USER_ADDR ((u32)g_sram_mem)
|
||
|
||
//分配的内存都是双字对齐的
|
||
#define MEM_BASE ((u8 *)(SRAM_USER_ADDR+MEM_ALLOC_TABLE_SIZE*2))
|
||
#define MEMMAP_BASE ((u16 *)(SRAM_USER_ADDR))
|
||
|
||
|
||
|
||
|
||
//内存管理参数
|
||
u32 memtblsize ; //内存表大小
|
||
u32 memblksize; //内存分块大小
|
||
u32 memsize ; //内存总大小
|
||
|
||
|
||
//内存管理控制器
|
||
struct _m_mallco_dev mallco_dev;
|
||
|
||
|
||
|
||
|
||
//内存管理初始化
|
||
//memx:所属内存块
|
||
static void mem_init(void)
|
||
{
|
||
memtblsize = MEM_ALLOC_TABLE_SIZE; //内存表大小
|
||
memblksize = MEM_BLOCK_SIZE; //内存分块大小
|
||
memsize = MEM_MAX_SIZE; //内存总大小
|
||
|
||
// mallco_dev.init=mem_init; //内存初始化
|
||
// mallco_dev.perused=mem_perused; //内存使用率
|
||
mallco_dev.membase=MEM_BASE; //内存池
|
||
mallco_dev.memmap=MEMMAP_BASE; //内存管理状态表
|
||
mallco_dev.memrdy=0; //内存管理未就绪
|
||
|
||
|
||
mymemset(mallco_dev.memmap, 0,memtblsize*2);//内存状态表数据清零
|
||
mymemset(mallco_dev.membase, 0,memsize); //内存池所有数据清零
|
||
mallco_dev.memrdy=1; //内存管理初始化OK
|
||
}
|
||
|
||
|
||
|
||
//获取内存使用率
|
||
//memx:所属内存块
|
||
//返回值:使用率(0~100)
|
||
int mem_perused(void)
|
||
{
|
||
u32 used=0;
|
||
u32 i;
|
||
for(i=0;i<memtblsize;i++)
|
||
{
|
||
if(mallco_dev.memmap[i])used++;
|
||
}
|
||
return (used*10000)/(memtblsize);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//内存分配(内部调用)
|
||
//memx:所属内存块
|
||
//size:要分配的内存大小(字节)
|
||
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
|
||
static u32 mem_malloc(u32 size)
|
||
{
|
||
signed long offset=0;
|
||
u16 nmemb; //需要的内存块数
|
||
u16 cmemb=0;//连续空内存块数
|
||
u32 i;
|
||
// if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化
|
||
if(size==0)return 0XFFFFFFFF;//不需要分配
|
||
|
||
nmemb=size/memblksize; //获取需要分配的连续内存块数
|
||
if(size%memblksize)nmemb++;
|
||
for(offset=memtblsize-1;offset>=0;offset--)//搜索整个内存控制区
|
||
{
|
||
if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
|
||
else cmemb=0; //连续内存块清零
|
||
if(cmemb==nmemb) //找到了连续nmemb个空内存块
|
||
{
|
||
for(i=0;i<nmemb;i++) //标注内存块非空
|
||
{
|
||
mallco_dev.memmap[offset+i]=nmemb;
|
||
}
|
||
return (offset*memblksize);//返回偏移地址
|
||
}
|
||
}
|
||
return 0XFFFFFFFF;//未找到符合分配条件的内存块
|
||
}
|
||
|
||
//释放内存(内部调用)
|
||
//memx:所属内存块
|
||
//offset:内存地址偏移
|
||
//返回值:0,释放成功;1,释放失败;
|
||
static u8 mem_free(u32 offset)
|
||
{
|
||
int i;
|
||
if(!mallco_dev.memrdy)//未初始化,先执行初始化
|
||
{
|
||
//mallco_dev.init();
|
||
return 1;//未初始化
|
||
}
|
||
if(offset<exmemsize)//偏移在内存池内.
|
||
{
|
||
int index=offset/memblksize; //偏移所在内存块号码
|
||
int nmemb=mallco_dev.memmap[index]; //内存块数量
|
||
for(i=0;i<nmemb;i++) //内存块清零
|
||
{
|
||
mallco_dev.memmap[index+i]=0;
|
||
}
|
||
return 0;
|
||
}else return 2;//偏移超区了.
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//------------------------------------内部CCM---------------------------------------
|
||
|
||
|
||
#if USE_CCM==1
|
||
|
||
#define CCM_USER_SIZE 64*1024
|
||
u8 g_ccm_mem[CCM_USER_SIZE] __attribute__((at(0x10000000)));
|
||
|
||
#define CCM_BLOCK_SIZE (32) //内存块大小为64字节
|
||
|
||
#define CCM_MAX_SIZE (((CCM_USER_SIZE))*CCM_BLOCK_SIZE/(CCM_BLOCK_SIZE+2))
|
||
#define CCM_ALLOC_TABLE_SIZE ((CCM_MAX_SIZE/CCM_BLOCK_SIZE)&(~3)) //内存表大小,必须为偶数,双字对齐
|
||
|
||
#define CCM_USER_ADDR ((u32)g_ccm_mem)
|
||
|
||
//分配的内存都是双字对齐的
|
||
#define CCM_BASE ((u8 *)(CCM_USER_ADDR+CCM_ALLOC_TABLE_SIZE*2))
|
||
#define CCMMAP_BASE ((u16 *)(CCM_USER_ADDR))
|
||
|
||
|
||
|
||
|
||
//内存管理参数
|
||
u32 ccm_memtblsize ; //内存表大小
|
||
u32 ccm_memblksize; //内存分块大小
|
||
u32 ccm_memsize ; //内存总大小
|
||
|
||
|
||
//内存管理控制器
|
||
struct _m_mallco_dev ccm_mallco_dev;
|
||
|
||
|
||
|
||
|
||
//内存管理初始化
|
||
//memx:所属内存块
|
||
static void ccm_init(void)
|
||
{
|
||
ccm_memtblsize = CCM_ALLOC_TABLE_SIZE; //内存表大小
|
||
ccm_memblksize = CCM_BLOCK_SIZE; //内存分块大小
|
||
ccm_memsize = CCM_MAX_SIZE; //内存总大小
|
||
|
||
ccm_mallco_dev.membase=CCM_BASE; //内存池
|
||
ccm_mallco_dev.memmap=CCMMAP_BASE; //内存管理状态表
|
||
ccm_mallco_dev.memrdy=0; //内存管理未就绪
|
||
|
||
|
||
mymemset(ccm_mallco_dev.memmap, 0,ccm_memtblsize*2);//内存状态表数据清零
|
||
mymemset(ccm_mallco_dev.membase, 0,ccm_memsize); //内存池所有数据清零
|
||
ccm_mallco_dev.memrdy=1; //内存管理初始化OK
|
||
}
|
||
|
||
|
||
|
||
//获取内存使用率
|
||
//memx:所属内存块
|
||
//返回值:使用率(0~100)
|
||
int ccm_perused(void)
|
||
{
|
||
u32 used=0;
|
||
u32 i;
|
||
for(i=0;i<ccm_memtblsize;i++)
|
||
{
|
||
if(ccm_mallco_dev.memmap[i])used++;
|
||
}
|
||
return (used*10000)/(ccm_memtblsize);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//内存分配(内部调用)
|
||
//memx:所属内存块
|
||
//size:要分配的内存大小(字节)
|
||
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
|
||
static u32 ccm_malloc(u32 size)
|
||
{
|
||
signed long offset=0;
|
||
u16 nmemb; //需要的内存块数
|
||
u16 cmemb=0;//连续空内存块数
|
||
u32 i;
|
||
// if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化
|
||
if(size==0)return 0XFFFFFFFF;//不需要分配
|
||
|
||
nmemb=size/ccm_memblksize; //获取需要分配的连续内存块数
|
||
if(size%ccm_memblksize)nmemb++;
|
||
for(offset=ccm_memtblsize-1;offset>=0;offset--)//搜索整个内存控制区
|
||
{
|
||
if(!ccm_mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
|
||
else cmemb=0; //连续内存块清零
|
||
if(cmemb==nmemb) //找到了连续nmemb个空内存块
|
||
{
|
||
for(i=0;i<nmemb;i++) //标注内存块非空
|
||
{
|
||
ccm_mallco_dev.memmap[offset+i]=nmemb;
|
||
}
|
||
return (offset*ccm_memblksize);//返回偏移地址
|
||
}
|
||
}
|
||
return 0XFFFFFFFF;//未找到符合分配条件的内存块
|
||
}
|
||
|
||
//释放内存(内部调用)
|
||
//memx:所属内存块
|
||
//offset:内存地址偏移
|
||
//返回值:0,释放成功;1,释放失败;
|
||
static u8 ccm_free(u32 offset)
|
||
{
|
||
int i;
|
||
if(!ccm_mallco_dev.memrdy)//未初始化,先执行初始化
|
||
{
|
||
//mallco_dev.init();
|
||
return 1;//未初始化
|
||
}
|
||
if(offset<exmemsize)//偏移在内存池内.
|
||
{
|
||
int index=offset/ccm_memblksize; //偏移所在内存块号码
|
||
int nmemb=ccm_mallco_dev.memmap[index]; //内存块数量
|
||
for(i=0;i<nmemb;i++) //内存块清零
|
||
{
|
||
ccm_mallco_dev.memmap[index+i]=0;
|
||
}
|
||
return 0;
|
||
}else return 2;//偏移超区了.
|
||
}
|
||
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|
||
//释放内存(外部调用)
|
||
//memx:所属内存块
|
||
//ptr:内存首地址
|
||
void myfree(void *ptr)
|
||
{
|
||
IRQ_DISABLE();
|
||
u32 free_addr=(u32)ptr;
|
||
u32 offset;
|
||
if(ptr==NULL)
|
||
{
|
||
IRQ_ENABLE();
|
||
return;//地址为0.
|
||
}
|
||
else if ((free_addr&0xf0000000)==0x20000000)//sram
|
||
{
|
||
offset=(u32)ptr-(u32)mallco_dev.membase;
|
||
mem_free(offset);//释放内存
|
||
}
|
||
else
|
||
{
|
||
offset=(u32)ptr-(u32)exmallco_dev.membase;
|
||
exmem_free(offset);//释放内存
|
||
}
|
||
//printf ("free:%#X\r\n",free_addr);
|
||
IRQ_ENABLE();
|
||
}
|
||
|
||
|
||
//分配内存(外部调用)
|
||
//首先尝试在内部分配,失败后再外部分配
|
||
//size:内存大小(字节)
|
||
//返回值:分配到的内存首地址.
|
||
void *mymalloc(size_t size)
|
||
{
|
||
IRQ_DISABLE();
|
||
u32 offset;
|
||
void *ret_addr=NULL;
|
||
if (size>5*1024)
|
||
offset=0XFFFFFFFF;
|
||
else
|
||
offset=mem_malloc(size);
|
||
if(offset!=0XFFFFFFFF)
|
||
{
|
||
ret_addr=(void*)((u32)mallco_dev.membase+offset);
|
||
}
|
||
else
|
||
{
|
||
offset=exmem_malloc(size);
|
||
if (offset!=0XFFFFFFFF)
|
||
{
|
||
ret_addr=(void*)((u32)exmallco_dev.membase+offset);
|
||
}
|
||
}
|
||
//printf ("malloc:%#X,%d\r\n",(u32)ret_addr,size);
|
||
IRQ_ENABLE();
|
||
return ret_addr;
|
||
}
|
||
|
||
|
||
|
||
//分配内存(外部调用)
|
||
//首先尝试在内部分配,失败后再外部分配
|
||
//size:内存大小(字节)
|
||
//返回值:分配到的内存首地址.
|
||
void *mymalloc_fast(u32 size)
|
||
{
|
||
IRQ_DISABLE();
|
||
u32 offset;
|
||
void *ret_addr=NULL;
|
||
offset=mem_malloc(size);
|
||
if(offset!=0XFFFFFFFF)
|
||
{
|
||
ret_addr=(void*)((u32)mallco_dev.membase+offset);
|
||
}
|
||
else
|
||
{
|
||
offset=exmem_malloc(size);
|
||
if (offset!=0XFFFFFFFF)
|
||
{
|
||
ret_addr=(void*)((u32)exmallco_dev.membase+offset);
|
||
}
|
||
}
|
||
//printf ("malloc:%#X,%d\r\n",(u32)ret_addr,size);
|
||
IRQ_ENABLE();
|
||
return ret_addr;
|
||
}
|
||
|
||
|
||
|
||
//分配外部内存(外部调用)
|
||
//首先尝试在内部分配,失败后再外部分配
|
||
//size:内存大小(字节)
|
||
//返回值:分配到的内存首地址.
|
||
void *mymalloc_exm(u32 size)
|
||
{
|
||
IRQ_DISABLE();
|
||
u32 offset;
|
||
void *ret_addr=NULL;
|
||
offset=exmem_malloc(size);
|
||
if (offset!=0XFFFFFFFF)
|
||
{
|
||
ret_addr=(void*)((u32)exmallco_dev.membase+offset);
|
||
}
|
||
IRQ_ENABLE();
|
||
return ret_addr;
|
||
}
|
||
|
||
|
||
|
||
|
||
#if USE_CCM==1
|
||
|
||
//释放CCM内存
|
||
void myfree_ccm(void *ptr)
|
||
{
|
||
IRQ_DISABLE();
|
||
u32 free_addr=(u32)ptr;
|
||
u32 offset;
|
||
if(ptr==NULL)
|
||
{
|
||
IRQ_ENABLE();
|
||
return;//地址为0.
|
||
}
|
||
else if ((free_addr&0xf0000000)==0x10000000)//sram
|
||
{
|
||
offset=(u32)ptr-(u32)ccm_mallco_dev.membase;
|
||
ccm_free(offset);//释放内存
|
||
}
|
||
else
|
||
{
|
||
offset=(u32)ptr-(u32)exmallco_dev.membase;
|
||
exmem_free(offset);//释放内存
|
||
}
|
||
//printf ("free:%#X\r\n",free_addr);
|
||
IRQ_ENABLE();
|
||
}
|
||
|
||
|
||
|
||
//分配CCM内存
|
||
void *mymalloc_ccm(u32 size)
|
||
{
|
||
IRQ_DISABLE();
|
||
u32 offset;
|
||
void *ret_addr=NULL;
|
||
offset=ccm_malloc(size);
|
||
if(offset!=0XFFFFFFFF)
|
||
{
|
||
ret_addr=(void*)((u32)ccm_mallco_dev.membase+offset);
|
||
}
|
||
else
|
||
{
|
||
offset=exmem_malloc(size);
|
||
if (offset!=0XFFFFFFFF)
|
||
{
|
||
ret_addr=(void*)((u32)exmallco_dev.membase+offset);
|
||
}
|
||
}
|
||
IRQ_ENABLE();
|
||
return ret_addr;
|
||
}
|
||
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|
||
//重新分配内存(外部调用)
|
||
//memx:所属内存块
|
||
//*ptr:旧内存首地址
|
||
//size:要分配的内存大小(字节)
|
||
//返回值:新分配到的内存首地址.
|
||
void *myrealloc(void *ptr,u32 size)
|
||
{
|
||
IRQ_DISABLE();
|
||
void *ret_addr;
|
||
ret_addr=mymalloc_exm(size);
|
||
if(ret_addr!=NULL)
|
||
{
|
||
if(ptr!=NULL)
|
||
{
|
||
mymemcpy (ret_addr,ptr,size);
|
||
myfree(ptr);
|
||
}
|
||
}
|
||
IRQ_ENABLE();
|
||
|
||
return ret_addr;
|
||
}
|
||
|
||
|
||
//分配内存并清零
|
||
void *mycalloc (u32 size)
|
||
{
|
||
void *ptr=mymalloc(size);
|
||
if (ptr) mymemset(ptr,0,size);
|
||
return ptr;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
//基本调用接口
|
||
|
||
|
||
|
||
|
||
void *malloc(size_t size)
|
||
{
|
||
return mymalloc(size);
|
||
}
|
||
|
||
void free (void *ptr)
|
||
{
|
||
myfree(ptr);
|
||
}
|
||
|
||
|
||
void *realloc(void *ptr,size_t size)
|
||
{
|
||
return myrealloc(ptr,size);
|
||
}
|
||
|
||
|
||
void *calloc(size_t nmemb, size_t size)
|
||
{
|
||
return mycalloc(nmemb*size);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|