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

📄 malloc.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef L_mallocBlock_t *__init_block(Block_t * b, char *pppp, size_t sz){	Block_t *p;	memset(b, 0, sizeof(Block_t));	b->ptr = pppp;	b->size = sz;	__ptrs_ins(b);	FREE_MEM_INS_BLOCK(b);	return p;}#endif							/* L_malloc *//* `b` is current block, `sz` its new size *//* block `b` will be splitted to one busy & one free block */#define SPLIT_BLOCK(b,sz) \{\  Block_t *bt; \  bt = bl_get(); \  INIT_BLOCK(bt, b->ptr + sz, b->size - sz); \  b->size = sz; \  if (__bl_last == b) __bl_last = bt; \  __bl_uncommit(bt);\}/* `b` is current block, `pp` is next free block, `sz` is needed size */#define SHRINK_BLOCK(b,pp,sz) \{\  FREE_MEM_DEL_BLOCK(pp,p); \  pp->ptr = b->ptr + sz; \  pp->size += b->size - sz; \  b->size = sz; \  FREE_MEM_INS_BLOCK(pp); \  __bl_uncommit(pp); \}#ifdef L_mallocstatic Block_t *bl_mapnew(size_t size){	size_t map_size;	Block_t *pp, *p;	void *pt;	map_size = PAGE_ALIGN(size);	pt = mmap(LARGE_MSTART, map_size, PROT_READ | PROT_WRITE | PROT_EXEC,#ifdef __UCLIBC_HAS_MMU__							 MAP_PRIVATE | MAP_ANONYMOUS#else							 MAP_SHARED | MAP_ANONYMOUS#endif							 , 0, 0);	if (pt == MAP_FAILED)		return (Block_t *) NULL;	__bl_last = pp = bl_get();	INIT_BLOCK(pp, (char *) pt, map_size);	pp->broken = 1;	return pp;}void __bl_uncommit(Block_t * b){	char *u_start, *u_end;	u_start = PAGE_ALIGNP(b->ptr);	u_end = PAGE_DOWNALIGNP(b->ptr + b->size);	if (u_end <= u_start)		return;#if M_DOTRIMMING	mmap(u_start, u_end - u_start, PROT_READ | PROT_WRITE | PROT_EXEC,#ifdef __UCLIBC_HAS_MMU__							 MAP_PRIVATE | MAP_ANONYMOUS |MAP_FIXED#else							 MAP_SHARED | MAP_ANONYMOUS |MAP_FIXED#endif							 , 0, 0);#endif}/* requested size must be aligned to ALIGNMENT */static Block_t *bl_alloc(size_t size){	Block_t *p, *pp;	/* try to find needed space in existing memory */	for (p = free_mem_root, pp = NULL; p;) {		if (p->size > size) {			pp = p;			p = p->l_free_mem;		} else if (p->size < size)			p = p->r_free_mem;		else {			pp = p;			break;		}	}	if (!pp) {					/* map some memory */		if (!__bl_last) {		/* just do initial mmap */			pp = bl_mapnew(size);			if (!pp)				return NULL;		} else if (!__bl_last->used) {	/* try growing last unused */			if (mremap(PAGE_DOWNALIGNP(__bl_last->ptr),					   PAGE_ALIGNP(__bl_last->ptr + __bl_last->size) -					   PAGE_DOWNALIGNP(__bl_last->ptr),					   PAGE_ALIGNP(__bl_last->ptr + size) -					   PAGE_DOWNALIGNP(__bl_last->ptr), 0) == MAP_FAILED) {	/* unable to grow -- initiate new block */				pp = bl_mapnew(size);				if (!pp)					return NULL;			} else {				pp = __bl_last;				FREE_MEM_DEL_BLOCK(pp, p);				pp->size = PAGE_ALIGNP(pp->ptr + size) - pp->ptr;				FREE_MEM_INS_BLOCK(pp);			}		} else {				/* __bl_last is used block */			if (mremap(PAGE_DOWNALIGNP(__bl_last->ptr),					   PAGE_ALIGNP(__bl_last->ptr + __bl_last->size) -					   PAGE_DOWNALIGNP(__bl_last->ptr),					   PAGE_ALIGNP(__bl_last->ptr + __bl_last->size +								   size) - PAGE_DOWNALIGNP(__bl_last->ptr),					   0) == MAP_FAILED) {				pp = bl_mapnew(size);				if (!pp)					return NULL;			} else {				pp = bl_get();				INIT_BLOCK(pp, __bl_last->ptr + __bl_last->size,						   PAGE_ALIGNP(__bl_last->ptr + __bl_last->size +									   size) - __bl_last->ptr -						   __bl_last->size);				__bl_last = pp;			}		}	}	/* just delete this node from free_mem tree */	if (pp->next)		__free_mem_replace(pp->next);	else		__free_mem_del(pp);	pp->used = 1;	if (pp->size - size > MALLOC_ALIGN) {	/* this block can be splitted (it is unused,not_broken) */		SPLIT_BLOCK(pp, size);	}	return pp;}#endif							/* L_malloc */#ifdef L__free_supportvoid __bl_free(Block_t * b){	Block_t *p, *bl_next, *bl_prev;	/* Look for blocks before & after `b` */	for (p = ptrs_root, bl_next = NULL, bl_prev = NULL; p;) {		if (p->ptr > b->ptr) {			bl_next = p;			p = p->l_ptrs;		} else if (p->ptr < b->ptr) {			bl_prev = p;			p = p->r_ptrs;		} else			break;	}	if (b->l_ptrs)		for (bl_prev = b->l_ptrs; bl_prev->r_ptrs;			 bl_prev = bl_prev->r_ptrs);	if (b->r_ptrs)		for (bl_next = b->r_ptrs; bl_next->l_ptrs;			 bl_next = bl_next->l_ptrs);	if (bl_next && !bl_next->broken && !bl_next->used) {		FREE_MEM_DEL_BLOCK(bl_next, p)			COMBINE_BLOCKS(b, bl_next)	}	if (bl_prev && !b->broken && !bl_prev->used) {		FREE_MEM_DEL_BLOCK(bl_prev, p)			COMBINE_BLOCKS(bl_prev, b)			b = bl_prev;	}	b->used = 0;	FREE_MEM_INS_BLOCK(b)		__bl_uncommit(b);}#endif							/* L__free_support */extern void __malloc_init(void);#ifdef L__malloc_initvoid __malloc_init(void){	int i, mapsize, x, old_x, gcount;	mapsize = M_PAGESIZE;	__malloc_initialized = 0;	__bl_last = NULL;	free_mem_root = NULL;	ptrs_root = NULL;	mapsize -= sizeof(Hunk_t);	for (i = 1; i <= HUNK_MAXSIZE; i++) {		__free_h[i] = (Hunk_t *) NULL;		for (x = mapsize / i, gcount = 0, old_x = 0; old_x != x;) {			old_x = x;			x = (mapsize - ALIGN(DIV8(old_x + 7))) / i;			if (gcount > 1 && x * i + ALIGN(DIV8(x + 7)) <= mapsize)				break;			if (x * i + ALIGN(DIV8(x + 7)) > mapsize)				gcount++;		}		__total_h[i] = x;	}	mutex_init(&malloc_lock);	__malloc_initialized = 1;	// fprintf(stderr, "malloc_init: hunk_t=%d\n", sizeof(Hunk_t));}#endif							/* L__malloc_init */#ifdef L_mallocvoid *malloc(size_t size){	void *p;	if (size == 0)		return NULL;	if (__malloc_initialized < 0)		__malloc_init();	if (__malloc_initialized)		mutex_lock(&malloc_lock);	if (size <= HUNK_MAXSIZE)		p = __hunk_alloc(size);	else {		if ((p = bl_alloc(ALIGN(size))) != NULL)			p = ((Block_t *) p)->ptr;	}	if (__malloc_initialized)		mutex_unlock(&malloc_lock);	// fprintf(stderr, "malloc returning: s=%d, p=%p\n", size, p);	return p;}#endif							/* L_malloc */#ifdef L_freevoid free(void *ptr){	Block_t *p, *best;	if (__malloc_initialized < 0)		return;	if (__malloc_initialized)		mutex_lock(&malloc_lock);	for (p = ptrs_root, best = NULL; p;) {		if (p->ptr > (char *) ptr)			p = p->l_ptrs;		else {			best = p;			p = p->r_ptrs;		}	}	if (!best || !best->used || best->ptr != (char *) ptr) {		__hunk_free(ptr);		if (__malloc_initialized)			mutex_unlock(&malloc_lock);		return;	}	__bl_free(best);	if (__malloc_initialized)		mutex_unlock(&malloc_lock);}#endif							/* L_free */extern void *_realloc_no_move(void *ptr, size_t size);#ifdef L__realloc_no_movevoid *_realloc_no_move(void *ptr, size_t size){	Block_t *p, *best, *next;	if (size <= HUNK_MAXSIZE)		return NULL;	if (__malloc_initialized <= 0)		return malloc(size);	mutex_lock(&malloc_lock);	/* Locate block */	for (p = ptrs_root, best = NULL; p;) {		if (p->ptr > (char *) ptr)			p = p->l_ptrs;		else {			best = p;			p = p->r_ptrs;		}	}	if (!best || !best->used || best->ptr != (char *) ptr) {		mutex_unlock(&malloc_lock);		return NULL;	}	size = ALIGN(size);	if (size == best->size) {		mutex_unlock(&malloc_lock);		return ptr;	}	if (best->r_ptrs)			/* get block just after */		for (next = best->r_ptrs; next->l_ptrs; next = next->l_ptrs);	else		for (p = ptrs_root, next = NULL; p;) {			if (p->ptr > best->ptr) {				next = p;				p = p->l_ptrs;			} else if (p->ptr < best->ptr)				p = p->r_ptrs;			else				break;		}	if (size < best->size) {	/* shrink block */		if (!next || next->used || next->broken) {			if (best->size - size > MALLOC_ALIGN) {	/* do split */				SPLIT_BLOCK(best, size);			}		} else {				/* just move border of next block */			SHRINK_BLOCK(best, next, size);		}	} else if (next && !next->broken && !next->used) {	/* can expand */		if (best->size + next->size > size + HUNK_MAXSIZE) {	/* shrink next free block */			SHRINK_BLOCK(best, next, size);		} else if (best->size + next->size >= size) {	/* combine blocks (eat next one) */			FREE_MEM_DEL_BLOCK(next, p);			COMBINE_BLOCKS(best, next);		} else {				/* not enough memory in next block */			mutex_unlock(&malloc_lock);			return NULL;		}	} else {					/* no next block */		mutex_unlock(&malloc_lock);		return NULL;	}	mutex_unlock(&malloc_lock);	return best->ptr;}#endif							/* L__realloc_no_move */#ifdef L_reallocvoid *realloc(void *ptr, size_t size){	void *tmp;	tmp = _realloc_no_move(ptr, size);	if (!tmp) {		Block_t *p, *best;		mutex_lock(&malloc_lock);		for (p = ptrs_root, best = NULL; p;) {			if (p->ptr > (char *) ptr)				p = p->l_ptrs;			else {				best = p;				p = p->r_ptrs;			}		}		if (!best || !best->used || best->ptr != (char *) ptr) {			if (ptr) {				Hunk_t *h;				h = (Hunk_t *) PAGE_DOWNALIGNP(ptr);				if (h->id == HUNK_ID) {					mutex_unlock(&malloc_lock);					if ((size >= HUNK_THRESHOLD && ALIGN(size) == h->size)						|| size == h->size)						return ptr;					if ((tmp = malloc(size)) == NULL)						return NULL;					mutex_lock(&malloc_lock);					memcpy(tmp, ptr, ((size < h->size) ? size : h->size));					__hunk_free(ptr);					mutex_unlock(&malloc_lock);					return tmp;				}			}			mutex_unlock(&malloc_lock);			return malloc(size);		}		mutex_unlock(&malloc_lock);		/* copy whole block */		if ((tmp = malloc(size)) == NULL)			return NULL;		memcpy(tmp, ptr, ((size < best->size) ? size : best->size));		mutex_lock(&malloc_lock);		__bl_free(best);		mutex_unlock(&malloc_lock);	}	return tmp;}#endif							/* L_realloc */#ifdef L_callocvoid *calloc(size_t unit, size_t quantity){	void *p;	unit *= quantity;	if ((p = malloc(unit)) == NULL)		return NULL;	memset(p, 0, unit);	return p;}#endif							/* L_calloc */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -