📄 malloc.cpp
字号:
/* Implementation module : Malloc.c
Copyright 1989 Diab Data AB, Sweden
Description :
Implemention of libc functions
void *Malloc(size_t size)
void *calloc(size_t nmemb, size_t size)
void Free(void *ptr)
int mallopt(int, int)
struct mallinfo mallinfo()
The functionality of mallopt is not needed
in this implementation of Malloc, but the
function is there for compability reasons.
History :
When Who What
890307 teve initial
910305 teve inserted some checking
*/
/**************** Globle variable this lib ***********************/
/*
char * __heap_beg ;
_lib_mutex __malloc_mutex
int __m_mxfast; * max size for "fast" allocation *
int __m_grain; * alignment of __m_mxfast *
int __m_nlblks; * number of blocks in each holding blk *
int __m_keep; * "safe" Malloc *
char *__heap_ptr ;
static size_t __malloc_blocksz ;
__m_hold *__small_mall ;
NP __brk_start ;
long __brk_tot ;
static char * __heap_end ;
*/
/*****************************************************************/
/* never profile nor run-time check this code */
#pragma option -Xprof-all=0
#pragma option -Xrtc=0
/************** Imported modules ********************************/
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include "in_malloc.h"
#include "Malloc.h"
#include "fnames.h"
//#include "rta/rtaenv.h"
#include "rtaenv.h"
#include "memfile.h"
/************** Local data, types, fns and macros ***************/
//int __no_malloc_warning; /* set this to 1 to kill warnings */
//int __malloc_init; /* if __malloc_init is set, all malloced*/
//int __malloc_val; /* memory is initialized to __malloc_val*/
//int __malloc_check; /* check list every Malloc()/Free() */
static size_t __malloc_blocksz; /* block align size for get_more() */
struct node __freeptr;
int __m_mxfast; /* max size for "fast" allocation */
int __m_grain; /* alignment of __m_mxfast */
int __m_nlblks; /* number of blocks in each holding blk */
int __m_keep; /* "safe" Malloc */
long __brk_tot;
NP __brk_start;
__m_hold *__small_mall;
_lib_mutex __malloc_mutex;
extern void *__malloc(size_t size);
extern void __free(void * ptr);
void _STI__05__malloc(void)
{
static struct node zeronode;
__malloc_mutex = 0;
// __no_malloc_warning = 0;
// __malloc_init = 0;
// __malloc_val = 0;
// __malloc_check = 0;
__malloc_blocksz = 1 << (12+1);
__freeptr = zeronode;
__m_mxfast = 0;
__m_grain = ALIGN;
__m_nlblks = 100;
__m_keep = 0;
__brk_start = NULL;
__brk_tot = 0;
}
void _STI__15__malloc(void)
{
__malloc_mutex = _lib_alloc_mutex();
}
//void __malloc_check_fn() ygr modify
bool __malloc_check_fn()
{
NP p, pn;
int size;
p = __brk_start;
if (p == NULL) return false;
//while ( (pn = NEXT(p)) ) {
pn = NEXT(p) ; //ygr
while (pn ) {
if (!ISDUMMY(p)) {
size = (char *)pn - (char *)p - __m_keep;
if (size > __m_mxfast) {
if (!ISBUSY(p) && !ISFREE(p)) {
return false; //ygr
//MALLERR("mallcheck: fatal error: Malloc list is corrupted\n");
}
}
}
p = pn;
pn = NEXT(p) ; //ygr
}
return true;
}
void __mallopt_fix(size_t size, int inc_flag)
{
int old_mxfast;
__m_hold *hp;
if (__small_mall == NULL) {
old_mxfast = __m_mxfast;
__m_mxfast = 0;
__small_mall =(__m_hold *) calloc(old_mxfast/__m_grain,sizeof(__m_hold));
if (__small_mall == NULL) return;
__m_mxfast = old_mxfast;
}
hp = __small_mall + (size-1)/__m_grain;
if (inc_flag) {
if (++hp->used > hp->avail) hp->avail += __m_nlblks;
} else {
--hp->used;
}
}
static void mall_init(void) /* first time init */
{
NP freepp;
char *var;
int i;
freepp = &__freeptr;
freepp->next = freepp;
SETBUSY(freepp);
freepp->u.free.next = freepp;
freepp->u.free.prev = freepp;
/*
if ((var = getenv("DMALLOC_INIT")) != NULL) {
__malloc_init = 1;
__malloc_val = atoi(var);
}
if ((var = getenv("DMALLOC_CHECK")) != NULL) {
__malloc_check = 1;
}
if ((var = getenv("DMALLOC_WARNING")) != NULL) {
if (*var == '\0') i = 1;
else i = atoi(var);
__no_malloc_warning = !i;
}
*/
}
void __insert(NP ptr) /* insert block in freetab */
{
NP freep;
freep = &__freeptr;
ptr->u.free.prev = freep;
ptr->u.free.next = freep->u.free.next;
freep->u.free.next->u.free.prev = ptr;
freep->u.free.next = ptr;
}
static int get_more(size_t size) /* get more memory */
{
NP ptr, freep, next;
static NP last_brk;
while(((long)SBRK(0) & (ALIGN-1)) != 0) {
/* Must do alignment 1 at a time to handle all possible brks! */
SBRK(1);
}
size = size+2*BOFFSET+__malloc_blocksz-1 & ~(__malloc_blocksz-1);
ptr = (NP)SBRK(size);
if (ptr == (NP)-1) return 0;
__brk_tot += size;
if (__brk_start == NULL) {
__brk_start = ptr;
} else if ((char *)last_brk+BOFFSET == (char *)ptr) {
ptr = last_brk;
size += BOFFSET;
} else {
last_brk->next = ptr; /* dummy busy block #define size_t*/
SETDUMMY(last_brk);
}
ptr->next = last_brk = (NP)((char *)ptr + size - BOFFSET);
last_brk->next = NULL;
SETBUSY(last_brk);
SETFREE(ptr);
__insert(ptr);
return 1;
}
void *__malloc(size_t size)
{
int n;
void *rval;
NP freepp, freep, newp, next;
size_t bsize;
if(__malloc_mutex) _lib_lock_mutex(__malloc_mutex);
// if (__malloc_check) __malloc_check_fn(); ygr modify
if (size <= __m_mxfast) {
if (size == 0) {
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
return NULL;
}
size = ((size+__m_grain-1)/__m_grain)*__m_grain;
__mallopt_fix(size,1);
}
size += __m_keep;
if (size < MINSZ) size = MINSZ;
else size = (size + ALIGN-1) & ~(ALIGN-1);
freepp = &__freeptr;
if (freepp->next == NULL) { /* first time */
Mem_init();//mall_init();
}
for(;;) {
freep = freepp->u.free.next;
while(freep != freepp) {
next = freep->next;
if (ISFREE(next)) {
do {
/* concat two free blocks */
Delete(next);
SETCLEAR(next);
next = next->next;
} while(ISFREE(next));
freep->next = next;
}
bsize = SIZE2(freep,next);
if (size <= bsize) {
/* block found! */
if (bsize-size > sizeof(struct node) + __m_keep) {
/* split node */
newp = (NP)(freep->u.buf+size);
*newp = *freep;
freep->next = newp;
freep->u.free.prev->u.free.next = newp;
freep->u.free.next->u.free.prev = newp;
} else {
Delete(freep);
}
SETBUSY(freep);
freep->u.free.next = NULL;
freep->u.free.prev = NULL;
//if (__malloc_init) { //ygr note: 分配空间赋初值
// Memset(freep->u.buf,__malloc_val,size);
//}
rval = &freep->u.buf[__m_keep];
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
return rval;
}
freep = freep->u.free.next;
}
/* no block found, create one */
if (!get_more(size)) {
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
return NULL;
}
}
}
void __free(void *ptr)
{
NP np, p, freep;
size_t size;
if (ptr == NULL) return;
if(__malloc_mutex) _lib_lock_mutex(__malloc_mutex);
// if (__malloc_check) __malloc_check_fn(); //ygr modify
np = (NP)((char *)ptr - BOFFSET - __m_keep);
if (!ISBUSY(np)) {
if (ISFREE(np)) {
//MALLERR("Free: warning: multiple Free() with same pointer\n");
} else if (__m_keep) {
np = (NP)((char *)ptr - BOFFSET);
}
if (!ISBUSY(np)) {
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
//MALLERR("Free: warning: not a valid pointer\n");
return;
}
}
if (__m_mxfast > 0) {
size = SIZE(np);
if (size <= __m_mxfast) __mallopt_fix(size,0);
}
SETFREE(np);
p = np->next;
while(ISFREE(p)) {
Delete(p);
SETCLEAR(p);
np->next = p = p->next;
}
freep = &__freeptr;
np->u.free.prev = freep;
np->u.free.next = freep->u.free.next;
freep->u.free.next->u.free.prev = np;
freep->u.free.next = np;
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
}
/************** Implementation of exported functions ************/
void *Malloc(size_t size)
{
void* p;
p = __malloc(size);
/* if RTEC is initialized, inform it
if (__rtc_alloc_ptr) {
(__rtc_alloc_ptr)(p, size);
}*/
return p;
}
void *calloc(size_t nmemb, size_t size)
{
char *ptr;
size = nmemb*size;
ptr = (char *)Malloc(size);
if (ptr == NULL) return NULL;
Memset(ptr,0,size);
return ptr;
}
void Free(void *ptr)
{
/* Free trough RTEC if initialized, else just Free the block
if (__rtc_free_ptr) {
(__rtc_free_ptr)(ptr, NULL, (void (*)(void*, void*))__free);
}
else */{
__free(ptr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -