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

📄 malloc.cpp

📁 自已写的一个嵌入式实时多任务抢占式操作系统。花了几个礼拜
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*	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 + -