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

📄 malloc.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  malloc - heap manager based on heavy use of virtual memory management.  Copyright (C) 1998   Valery Shchedrin  This library is free software; you can redistribute it and/or  modify it under the terms of the GNU Library General Public  License as published by the Free Software Foundation; either  version 2 of the License, or (at your option) any later version.  This library is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  Library General Public License for more details.  You should have received a copy of the GNU Library General Public  License along with this library; if not, write to the Free  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,  MA 02111-1307, USA    Public Functions:    void *malloc(size_t size);      Allocates `size` bytes    returns NULL if no free memory available    void *calloc(size_t unit, size_t quantity);      Allocates `quantity*unit` zeroed bytes via internal malloc call    void *realloc(void *ptr, size_t size);      Reallocates already allocated block `ptr`, if `ptr` is not valid block    then it works as malloc. NULL is returned if no free memory available    void *_realloc_no_move(void *ptr, size_t size);      Reallocates already allocated block `ptr`, if `ptr` is not valid block    or if reallocation can't be done with shrinking/expanding already    allocated block NULL is returned    void free(void *ptr);      Frees already allocated block, if `ptr` is incorrect one nothing will    happen.*//* * Manuel Novoa III         Jan 2001 * * Modified to decrease object sizes. *   Broke into independent object files. *   Converted INIT_BLOCK() and FREE_MEM_DEL_BLOCK() from macros to functions. */#include <features.h>#ifndef _XOPEN_SOURCE#define _XOPEN_SOURCE#endif#include <sys/types.h>#include <unistd.h>#include <limits.h>#include <sys/time.h>#include <asm/page.h>#include <unistd.h>#include <sys/mman.h>#include <string.h>#include "malloc.h"#include <stdio.h>#define M_DOTRIMMING 1#define M_MULTITHREADED 0#define VALLOC_MSTART  ((void*)0x1c000000)#define LARGE_MSTART   ((void*)0x19000000)#define HUNK_MSTART    ((void*)0x18000000)#define HUNK_MSIZE     M_PAGESIZE#define HUNK_ID        0x99171713/* alignment of allocations > HUNK_THRESHOLD */#define MALLOC_ALIGN    4/* allocations < HUNK_THRESHOLD will not be aligned */#define HUNK_THRESHOLD  4/*up to HUNK_MAXSIZE blocks will be joined together to decrease memory waste*/#define HUNK_MAXSIZE 128/* returns value not less than size, aligned to MALLOC_ALIGN */#define ALIGN(size) (((size)+(MALLOC_ALIGN)-1)&(~((MALLOC_ALIGN)-1)))/* aligns s or p to page boundaries */#define PAGE_ALIGN(s) (((s)+M_PAGESIZE-1)&(~(M_PAGESIZE-1)))#define PAGE_ALIGNP(p) ((char*)PAGE_ALIGN((unsigned)(p)))#define PAGE_DOWNALIGNP(p) ((char*)(((unsigned)(p))&(~(M_PAGESIZE-1))))/* returns v * 2 for your machine (speed-up) */#define MUL2(v)  ((v)*2)/* does v *= 8 for your machine (speed-up) */#define EMUL8(v) v*=8/* does v/8 for your machind (speed-up) */#define DIV8(v)  ((v)/8)#if M_MULTITHREADED#error This version does not support threads#elsetypedef int mutex_t;#define mutex_lock(x)#define mutex_unlock(x)#define mutex_init(x)#define MUTEX_INITIALIZER 0//static mutex_t malloc_lock = MUTEX_INITIALIZER;#endifextern int __malloc_initialized;#ifdef L__malloc_initint __malloc_initialized = -1; /* -1 == uninitialized, 0 == initializing, 1 == initialized */#endif#ifndef MAP_FAILED#define MAP_FAILED ((void*)-1)#endif#if defined(MAP_ANONYMOUS) && !defined(MAP_ANON)#define MAP_ANON MAP_ANONYMOUS#endif#ifndef NULL#define NULL ((void*)0)#endif/* guess pagesize */#define M_PAGESIZE getpagesize()/* HUNK MANAGER */typedef struct Hunk_s Hunk_t;struct Hunk_s {					/* Hunked block - 8 byte overhead */	int id;						/* unique id */	unsigned int total:12, used:12, size:8;	Hunk_t *next;				/* next free in __free_h */};#define usagemap(h) (((unsigned char *)(h))+sizeof(Hunk_t))#define hunk_ptr(h) (((char*)(h))+sizeof(Hunk_t)+ALIGN(DIV8(h->total+7)))#define hunk(h)  ((Hunk_t*)(h))extern Hunk_t *__free_h[HUNK_MAXSIZE + 1];extern int __total_h[HUNK_MAXSIZE + 1];#ifdef L__malloc_initHunk_t *__free_h[HUNK_MAXSIZE + 1];	/* free hash */int __total_h[HUNK_MAXSIZE + 1];	/* Hunk_t's `total` member */#endifextern void *__hunk_alloc(int size);#ifdef L_malloc/* __hunk_alloc allocates <= HUNK_MAXSIZE blocks */void *__hunk_alloc(int size){	Hunk_t *p;	unsigned long *cpl;	int i, c;	//	if (size >= HUNK_THRESHOLD)	size = ALIGN(size);	/* Look for already allocated hunkblocks */	if ((p = __free_h[size]) == NULL) {		if (			(p =			 (Hunk_t *) mmap(HUNK_MSTART, HUNK_MSIZE,							 PROT_READ | PROT_WRITE,#ifdef __UCLIBC_HAS_MMU__							 MAP_PRIVATE | MAP_ANONYMOUS#else							 MAP_SHARED | MAP_ANONYMOUS#endif							 , 0, 0)) == (Hunk_t *) MAP_FAILED)		  // {		  //  printf("hunk_alloc failed: %d, %d\n", size, errno);			return NULL;		  // }		memset(p, 0, HUNK_MSIZE);		p->id = HUNK_ID;		p->total = __total_h[size];		/* p->used = 0; */		p->size = size;		/* p->next = (Hunk_t*)NULL; */		/* memset(usagemap(p), 0, bound); */		__free_h[size] = p;	}	/* Locate free point in usagemap */		/* First find a word where not all the bits are set */	for (cpl = (unsigned long *) usagemap(p); *cpl == 0xFFFFFFFF; cpl++);	/* Remember the byte position of that word */	i = ((unsigned char *) cpl) - usagemap(p);	/* Now find find a free bit in the word using binary search */	if (*(unsigned short *) cpl != 0xFFFF) {		if (*(unsigned char *) cpl == 0xFF) {			c = *(((unsigned char *) cpl) + 1);			i++;		}		else		  {		    c = *(unsigned char *) cpl;		  }	} else {		i += 2;		c = *(((unsigned char *) cpl) + 2);		if (c == 0xFF) {			c = *(((unsigned char *) cpl) + 3);			i++;		}	}		/*	 * Multiply i by 8 for the bit position	 * Further down, we divide by 8 again to find the byte position	 */	EMUL8(i);		/* If bottom nibble is set, shift down the top nibble */	if ((c & 0xF) == 0xF) {		c >>= 4;		i += 4;	}		/* If bottom 2 bits are set, shift down the top two */	if ((c & 0x3) == 0x3) {		c >>= 2;		i += 2;	}		/* Check which one of the two bits is set */	if (c & 1)		i++;	usagemap(p)[DIV8(i)] |= (1 << (i & 7));	/* set bit */	/* Increment counter and update hashes */	if (++p->used == p->total) {		__free_h[p->size] = p->next;		p->next = NULL;	}		// fprintf(stderr, "hunk_alloc: i=%d, p->size=%d, p=%p\n", i, p->size, p);	return hunk_ptr(p) + i * p->size;}#endif							/* L_malloc */extern void __hunk_free(char *ptr);#ifdef L__free_support/* __hunk_free frees blocks allocated by __hunk_alloc */void __hunk_free(char *ptr){	unsigned char *up;	int i, v;	Hunk_t *h;	if (!ptr)		return;	h = (Hunk_t *) PAGE_DOWNALIGNP(ptr);	/* Validate `ptr` */	if (h->id != HUNK_ID)		return;	v = ptr - hunk_ptr(h);	i = v / h->size;	if (v % h->size != 0 || i < 0 || i >= h->total)		return;	/* Update `usagemap` */	up = &(usagemap(h)[DIV8(i)]);	i = 1 << (i & 7);	if (!(*up & i))		return;	*up ^= i;	/* Update hunk counters */	if (h->used == h->total) {		if (--h->used) {		/* insert into __free_h */			h->next = __free_h[h->size];			__free_h[h->size] = h;		}						/* else - it will be unmapped */	} else {		if (!--h->used) {		/* delete from __free_h - will be __bl_freed */			Hunk_t *p, *pp;			for (p = __free_h[h->size], pp = NULL; p != h;				 pp = p, p = p->next);			if (!pp)				__free_h[h->size] = p->next;			else				pp->next = p->next;		}	}	/* Unmap empty Hunk_t */	if (!h->used)		munmap((void *) h, HUNK_MSIZE);}#endif							/* L__free_support *//* BLOCK MANAGER */typedef struct Block_s Block_t;struct Block_s {				/* 32-bytes long control structure (if 4-byte aligned) */	char *ptr;					/* pointer to related data */	Block_t *next;				/* next in free_mem list */	Block_t *l_free_mem, *r_free_mem;	/* left & right subtrees of <free_mem> */	Block_t *l_ptrs, *r_ptrs;	/* left & right subtrees of <ptrs> */	size_t size;				/* size - divided by align */	/* packed 4-byte attributes *//* { */	signed char bal_free_mem:8;	/* balance of <free_mem> subtree */	signed char bal_ptrs:8;		/* balance of <ptrs> subtree */	unsigned int used:1;		/* used/free state of the block */	unsigned int broken:1;		/* 1 if previous block can't be merged with it *//* } */};extern Block_t *__bl_last;		/* last mmapped block */#ifdef L__malloc_initBlock_t *__bl_last;				/* last mmapped block */#endif#define bl_get() __hunk_alloc(sizeof(Block_t))#define bl_rel(p) __hunk_free((char*)p)extern Block_t *__Avl_Block_tfree_mem_tree;extern Block_t *__free_mem_ins(Block_t * data);extern void __free_mem_del(Block_t * data);extern void __free_mem_replace(Block_t * data);extern Block_t *__Avl_Block_tptrs_tree;extern Block_t *__ptrs_ins(Block_t * data);extern void __ptrs_del(Block_t * data);extern void __bl_uncommit(Block_t * b);extern void __bl_free(Block_t * b);/* like C++ templates ;-) */#include "avlmacro.h"#define FREE_MEM_COMPARE(i,a,b) \{ \  if ( (a)->size < (b)->size ) { \     i = -1; \  } else if ( (a)->size > (b)->size ) { \     i = 1; \  } else { \     i = 0; \  } \}#define PTRS_COMPARE(i,a,b) \{ \  if ( (a)->ptr < (b)->ptr ) { \     i = -1; \  } else if ( (a)->ptr > (b)->ptr ) { \     i = 1; \  } else { \     i = 0; \  } \}#ifdef L__avl_supportAvl_Tree(free_mem, Block_t, free_mem, FREE_MEM_COMPARE)	Avl_Tree_no_replace(ptrs, Block_t, ptrs, PTRS_COMPARE)#endif#define free_mem_root Avl_Root(Block_t, free_mem)#define ptrs_root Avl_Root(Block_t, ptrs)/* pp is freed block */#define FREE_MEM_DEL_BLOCK(pp,p) {p = __free_mem_del_block(pp,p);}extern Block_t *__free_mem_del_block(Block_t * pp, Block_t * p);#ifdef L_mallocBlock_t *__free_mem_del_block(Block_t * pp, Block_t * p){	for (p = free_mem_root;;)		if (p->size > pp->size)			p = p->l_free_mem;		else if (p->size < pp->size)			p = p->r_free_mem;		else			break;	if (p == pp) {		if (pp->next)			__free_mem_replace(pp->next);		else			__free_mem_del(pp);	} else {		for (; p->next != pp; p = p->next);		p->next = pp->next;	}	return p;}#endif							/* L_malloc */#define FREE_MEM_INS_BLOCK(pp) \{ \  if ((p = __free_mem_ins(pp)) != NULL)\  {\    pp->next = p->next;\    p->next = pp;\  }\  else pp->next = NULL; \}/* `b` is current block, `pp` is next block */#define COMBINE_BLOCKS(b,pp) \{\  __ptrs_del(pp); \  b->size += pp->size; \  if (pp == __bl_last) __bl_last = b; \  bl_rel(pp); \}/* initializes new block b */#define INIT_BLOCK(b, pppp, sz) { p = __init_block(b, pppp, sz); }extern Block_t *__init_block(Block_t * b, char *pppp, size_t sz);

⌨️ 快捷键说明

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