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

📄 vxmalloc.c

📁 This version of malloc for VxWorks contains two different algorithms. One is the BSD based Kingsley
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Allocate more memory to the indicated bucket. */static voidmorecore(bucket)        int bucket;{        register union overhead *op;        register int sz;		/* size	of desired block */        int amt;			/* amount to allocate */        int nblks;			/* how many blocks we get */        /*	 * sbrk_size <=	0 only for big, FLUFFY, requests (about	 * 2^30	bytes on a VAX, I think) or for a negative arg.	 */        sz = 1 << (bucket + 3);        if (sz <= 0)		return;        if (sz < pagesz) {		amt = pagesz;		nblks =	amt / sz;        } else {		amt = sz + pagesz;		nblks =	1;        }        op = (union overhead *)sbrk(amt);        /* no more room! */        if ((int)op == -1)		return;        /*	 * Add new memory allocated to that on	 * free	list for this hash bucket.	 */        nextf[bucket] = op;        while (--nblks > 0) {		op->ov_next = (union overhead *)((caddr_t)op + sz);		op = (union overhead *)((caddr_t)op + sz);        }}voidbsd_free(void *cp){           register int size;        register union overhead *op;        assert(bsd_malloc_initialized);        if (cp == NULL)		return;        semTake(bsd_mem_sid, WAIT_FOREVER);        op = (union overhead *)((caddr_t)cp - sizeof (union overhead));        if (op->ov_magic != MAGIC)  {		semGive(bsd_mem_sid);		return;				/* sanity */        }        assert(op->ov_rmagic == RMAGIC);        assert(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);        size = op->ov_index;        assert(size < NBUCKETS);        op->ov_next = nextf[size];      /* also clobbers ov_magic */        nextf[size] = op;        nmalloc[size]--;        semGive(bsd_mem_sid);}/* * When a program attempts "storage compaction" as mentioned in the * old malloc man page, it realloc's an already freed block.  Usually * this is the last block it freed; occasionally it might be farther * back.  We have to search all the free lists for the block in order * to determine its bucket: 1st we make one pass thru the lists * checking only the first block in each; if that fails we search * ``realloc_srchlen'' blocks in each list for a match (the variable * is extern so the caller can modify it).  If that fails we just copy * however many bytes was given to realloc() and hope it's not huge. */int realloc_srchlen = 4;        /* 4 should be plenty, -1 =>'s whole list */void *bsd_realloc(void *cp, int nbytes){           register u_int onb;        register int i;        union overhead *op;        char *res;        int was_alloced = 0;        assert(bsd_malloc_initialized);        semTake(bsd_mem_sid, WAIT_FOREVER);        if (cp == NULL)	 {		semGive(bsd_mem_sid);		return (bsd_malloc(nbytes));        }        op = (union overhead *)((caddr_t)cp - sizeof (union overhead));        if (op->ov_magic == MAGIC) {		was_alloced++;		i = op->ov_index;        } else {		/*		 * Already free, doing "compaction".		 *		 * Search for the old block of memory on the		 * free	list.  First, check the most common		 * case	(last element free'd), then (this failing)		 * the last ``realloc_srchlen''	items free'd.		 * If all lookups fail,	then assume the size of		 * the memory block being realloc'd is the		 * largest possible (so	that all "nbytes" of new		 * memory are copied into).  Note that this could cause		 * a memory fault if the old area was tiny, and	the moon		 * is gibbous.	However, that is very unlikely.		 */		if ((i = findbucket(op,	1)) < 0 &&		    (i = findbucket(op,	realloc_srchlen)) < 0)			i = NBUCKETS;        }        onb = 1 << (i + 3);        if (onb < pagesz)		onb -= sizeof (*op) + RSLOP;        else		onb += pagesz -	sizeof (*op) - RSLOP;        /* avoid the copy if same size block */        if (was_alloced) {		if (i) {			i = 1 << (i + 2);			if (i <	pagesz)				i -= sizeof (*op) + RSLOP;			else				i += pagesz - sizeof (*op) - RSLOP;	        }		if (nbytes <= onb && nbytes > i) {			op->ov_size = (nbytes +	RSLOP - 1) & ~(RSLOP - 1);			*(u_short *)((caddr_t)(op + 1) + op->ov_size) =	RMAGIC;			semGive(bsd_mem_sid);			return(cp);		} else			bsd_free(cp);        }        if ((res = bsd_malloc(nbytes)) == NULL)	 {		semGive(bsd_mem_sid);		return (NULL);        }        if (cp != res)		/* common optimization if "compacting" */		bcopy(cp, res, (nbytes < onb) ?	nbytes : onb);        semGive(bsd_mem_sid);        return (res);}/* * Search ``srchlen'' elements of each free list for a block whose * header starts at ``freep''.  If srchlen is -1 search the whole list. * Return bucket number, or -1 if not found. */static intfindbucket(freep, srchlen)        union overhead *freep;        int srchlen;{        register union overhead *p;        register int i, j;        for (i = 0; i < NBUCKETS; i++) {		j = 0;		for (p = nextf[i]; p &&	j != srchlen; p = p->ov_next) {			if (p == freep)				return (i);			j++;	        }        }        return (-1);}/* * mstats - print out statistics about malloc *  * Prints two lines of numbers, one showing the length of the free list * for each size category, the second showing the number of mallocs - * frees for each size category. */voidbsd_mstats(int mode){        register int i, j;        register union overhead *p;        unsigned int totfree = 0, totused = 0;        dbg_printf("\nBSD memory allocation statistics\n");        if (mode) {		dbg_printf("%12s size %12s free	%10s used\n"," ", " ", " ");		for (i = 0; i <	NBUCKETS; i++) {			for (j = 0, p =	nextf[i]; p && j < INFINITE;			     p = p->ov_next, j++)			        ;			if (j == INFINITE) /* just in case something is	corrupted */			  {			    dbg_printf("\nToo many links in block %d(%u)!\n", i,				 (1<< (i+3)));			    return;			  }		        			dbg_printf("%16u: %16u %16u\n",	(1<< (i + 3)), j, nmalloc[i]);			totfree	+= j * (1 << (i + 3));			totused	+= nmalloc[i] * (1 << (i+3));	        }        }        dbg_printf("\n");        dbg_printf("\tbytes in use: %16u\n", totused);        dbg_printf("\tbytes free:   %16u\n", totfree);        dbg_printf("\tpool size:    %16d\n", 				(int)(bsd_malloc_top - bsd_malloc_bottom));        dbg_printf("\tmargin:	    %16d\n",  				(int)(bsd_malloc_top - bsd_malloc_brk));        dbg_printf("\n");        dbg_printf("\tbottom:	    0x%x\n", (int)bsd_malloc_bottom);        dbg_printf("\ttop:	    0x%x\n", (int)bsd_malloc_top);        dbg_printf("\tbrk:	    0x%x\n",  (int)bsd_malloc_brk);}#endif /* USE_BSD */#ifdef USE_DL/*   A version of malloc/free/realloc written by Doug Lea and released to the   public domain.  Send questions/comments/complaints/performance data  to dl@cs.oswego.edu*//* VERSION 2.6.2  Mon Jan  8 10:28:33 1996  Doug Lea  (dl at gee)     Note: There may be an updated version of this malloc obtainable at	   ftp://g.oswego.edu/pub/misc/malloc.c	 Check before installing!* Synopsis of public routines  (Much fuller descriptions are contained in the program documentation below.)  malloc(size_t n);     Return a pointer to a newly allocated chunk of at least n bytes, or null     if no space is available.  free(Void_t* p);     Release the chunk of memory pointed to by p, or no effect if p is null.  realloc(Void_t* p, size_t n);     Return a pointer to a chunk of size n that contains the same data     as does chunk p up to the minimum of (n, p's size) bytes, or null     if no space is available. The returned pointer may or may not be     the same as p. If p is null, equivalent to malloc.	 Unless the     #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a     size argument of zero (re)allocates a minimum-sized chunk.  memalign(size_t alignment, size_t n);     Return a pointer to a newly allocated chunk of n bytes, aligned     in accord with the alignment argument, which must be a power of     two.  valloc(size_t n);     Equivalent to memalign(pagesize, n), where pagesize is the page     size of the system (or as near to this as can be figured out from     all the includes/defines below.)  calloc(size_t unit, size_t quantity);     Returns a pointer to quantity * unit bytes, with all locations     set to zero.  cfree(Void_t* p);     Equivalent to free(p).  malloc_trim(size_t pad);     Release all but pad bytes of freed top-most memory back      to the system. Return 1 if successful, else 0.  malloc_usable_size(Void_t* p);     Report the number usable allocated bytes associated with allocated     chunk p. This may or may not report more bytes than were requested,     due to alignment and minimum size constraints.  malloc_stats();     Prints brief summary statistics on stderr.  mallinfo()     Returns (by copy) a struct containing various summary statistics.  mallopt(int parameter_number, int parameter_value)     Changes one of the tunable parameters described below. Returns     1 if successful in changing the parameter, else 0.* Vital statistics:  Alignment:				8-byte       8 byte alignment is currently hardwired into the design.	 This       seems to suffice for all current machines and C compilers.  Assumed pointer representation:       4 bytes  Assumed size_t  representation:       4 bytes  Minimum overhead per allocated chunk: 4 bytes       Each malloced chunk has a hidden overhead of 4 bytes holding size       and status information.    Minimum allocated size:	       16 bytes	(12 bytes usable, 4 overhead)       When a chunk is freed, 12 additional bytes are needed; 4 for a       trailing size field and 8 bytes for free list pointers. Thus,       the minimum allocatable size is 16 bytes, of which 12 bytes are       usable. Even a request for zero bytes (i.e., malloc(0)) returns        a pointer to something of the minimum allocatable size.    Maximum allocated size:      2147483640 (2^31 - 8) bytes       It is assumed that (possibly signed) 32 bit values suffice to       represent chunk sizes. `Possibly signed' is due to the fact       that `size_t' may be defined on a system as either a signed or       an unsigned type. To be conservative, values that would appear       as negative numbers are avoided.	 The maximum size chunk is       2^31 - 8 bytes.  Requests for negative sizes (when size_t is       signed) or those greater than (2^31 - 8) bytes will return a       minimum-sized chunk.  Maximum overhead wastage per allocated chunk: normally 15 bytes       Alignnment demands, plus the minimum allocatable size restriction       make the normal worst-case wastage 15 bytes (i.e., up to 15       more bytes will be allocated than were requested in malloc), with        two exceptions:	 1. Because requests for zero bytes allocate non-zero space,	    the	worst case wastage for a request of zero bytes is 24 bytes.	 2. For	requests >= mmap_threshold that are serviced via	    mmap(), the	worst case wastage is 8 bytes plus the remainder	    from a system page (the minimal mmap unit);	typically 4096 bytes.* Synopsis of compile-time options:    People have reported using previous versions of this malloc on all    versions of Unix, sometimes by tweaking some of the defines    below. It has been tested most extensively on Solaris and    Linux. People have also reported adapting this malloc for use in    stand-alone embedded systems.    The implementation is in straight, hand-tuned ANSI C.  Among other    consequences, it uses a lot of macros.  Because of this, to be at    all usable, this code should be compiled using an optimizing compiler    (for example gcc -O2) that can simplify expressions and control    paths.  __STD_C		   (default: derived from C compiler defines)     Nonzero if using ANSI-standard C compiler, a C++ compiler, or     a C compiler sufficiently close to ANSI to get away with it.  DEBUG			   (default: NOT defined)     Define to enable debugging. Adds fairly extensive assertion-based      checking to help track down memory errors, but noticeably slows down     execution.  REALLOC_ZERO_BYTES_FREES (default: NOT defined)      Define this if you think that realloc(p, 0) should be equivalent     to free(p). Otherwise, since malloc returns a unique pointer for     malloc(0), so does realloc(p, 0).  HAVE_MEMCPY		    (default: defined)     Define if you are not otherwise using ANSI STD C, but still      have memcpy and memset in your C library and want to use them.     Otherwise, simple internal versions are supplied.  HAVE_MMAP		    (default: defined as 1)     Define to non-zero to optionally make malloc() use mmap() to     allocate very large blocks.    malloc_getpagesize	    (default: derived from system #includes)     Either a constant or routine call returning the system page size.  HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined)      Optionally define if you are on a system with a /usr/include/malloc.h     that declares struct mallinfo. It is not at all necessary to     define this even if you do, but will ensure consistency.  INTERNAL_LINUX_C_LIB	    (default: NOT defined)     Defined only when compiled as part of Linux libc.     Also note that there is some odd internal name-magling via defines     (for example, internally, `malloc' is named `mALLOc') needed     when compiling in this case. These look funny but don't otherwise     affect anything.  MORECORE		    (default: sbrk)     The name of the routine to call to obtain more memory from the system.  MORECORE_FAILURE	    (default: -1)     The value returned upon failure of MORECORE.  DEFAULT_TRIM_THRESHOLD  DEFAULT_TOP_PAD         DEFAULT_MMAP_THRESHOLD  DEFAULT_MMAP_MAX           Default values of tunable parameters (described in detail below)     controlling interaction with host system routines (sbrk, mmap, etc).     These values may also be changed dynamically via mallopt(). The     preset defaults are those that give best performance for typical     programs/systems.*//*History:    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)      * Integrated most documentation with the code.      * Add support for mmap, with help from         Wolfram Gloger (Gloger@lrz.uni-muenchen.de).      * Use last_remainder in more cases.

⌨️ 快捷键说明

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