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

📄 malloc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
			DELFREEQ(blk);			/* make head of free queue immediately follow blk, unless			   blk was at the end of the queue */			nblk = blk->nextfree;			if (nblk != &(freeptr[1]))   {				MOVEHEAD(nblk);			}		}		/*      blk now points to an adequate block     */		if (((char *)blk->nextblk - (char *)blk) - nb >= MINBLKSZ)  {			/* carve out the right size block */			/* newblk will be the remainder */			newblk = (struct header *)((char *)blk + nb);			newblk->nextblk = blk->nextblk;			/* mark the block busy */			blk->nextblk = SETBUSY(newblk);			ADDFREEQ(newblk);			/* if blk was lastblk, make newblk lastblk */			if(blk==lastblk) lastblk = newblk;		}  else  {			/* just mark the block busy */			blk->nextblk = SETBUSY(blk->nextblk);		}	}	CHECKQ;	return (char *)blk + minhead;}/*      free(ptr) - free block that user thinks starts at ptr 	input - ptr-1 contains the block header.		If the header points forward, we have a normal			block pointing to the next block		if the header points backward, we have a small			block from a holding block.		In both cases, the busy bit must be set*/voidfree(ptr)char *ptr;{	register struct holdblk *holdblk;       /* block holding blk */	register struct holdblk *oldhead;       /* former head of the hold 						   block queue containing						   blk's holder */	if (TESTSMAL(((struct header *)(ptr - MINHEAD))->nextblk))  {		register struct lblk *lblk;     /* pointer to freed block */		register offset;		/* choice of header lists */		lblk = (struct lblk *)CLRBUSY(ptr - MINHEAD);		assert((struct header *)lblk < arenaend);		assert((struct header *)lblk > arena);		/* allow twits (e.g. awk) to free a block twice */		if (!TESTBUSY(holdblk = lblk->header.holder)) return;		holdblk = (struct holdblk *)CLRALL(holdblk);		/* put lblk on its hold block's free list */		lblk->header.nextfree = SETSMAL(holdblk->lfreeq);		holdblk->lfreeq = lblk;		/* move holdblk to head of queue, if its not already there */		offset = holdblk->blksz/grain;		oldhead = holdhead[offset];		if (oldhead != holdblk)  {			/* first take out of current spot */			holdhead[offset] = holdblk;			holdblk->nexthblk->prevhblk = holdblk->prevhblk;			holdblk->prevhblk->nexthblk = holdblk->nexthblk;			/* now add at front */			holdblk->nexthblk = oldhead;			holdblk->prevhblk = oldhead->prevhblk;			oldhead->prevhblk = holdblk;			holdblk->prevhblk->nexthblk = holdblk;		}	}  else  {		register struct header *blk;	    /* real start of block*/		register struct header *next;      /* next = blk->nextblk*/		register struct header *nextnext;       /* block after next */		blk = (struct header *)(ptr - minhead);		next = blk->nextblk;		/* take care of twits (e.g. awk) who return blocks twice */		if (!TESTBUSY(next))  return;		blk->nextblk = next = CLRBUSY(next);		ADDFREEQ(blk);		/* see if we can compact */		if (!TESTBUSY(nextnext = next->nextblk))  {			do  {				DELFREEQ(next);				next = nextnext;			}  while (!TESTBUSY(nextnext = next->nextblk));			if (next == arenaend) lastblk = blk;			blk->nextblk = next;		}	}	CHECKQ}/*      realloc(ptr,size) - give the user a block of size "size", with			    the contents pointed to by ptr.  Free ptr.*/void *realloc(ptr,size)char *ptr;		    /* block to change size of */unsigned size;	    /* size to change to */{	register struct header *blk;    /* block ptr is contained in */	register unsigned trusize;      /* size of block, as allocaters see it*/	char *newptr;	      /* pointer to user's new block */	register unsigned cpysize;      /* amount to copy */	register struct header *next;   /* block after blk */	if(size == 0) return NULL;	if (TESTSMAL(((struct lblk *)(ptr - MINHEAD))->header.holder))  {		/* we have a special small block which can't be expanded */		/* This makes the assumption that even if the user is 		   reallocating a free block, malloc doesn't alter the contents		   of small blocks */		newptr = malloc(size);		if (newptr == NULL)  return NULL;		/* this isn't to save time--its to protect the twits */		if(ptr != newptr)  {			(void)memcpy(newptr,ptr,(int)size);			free(ptr);		}	}  else  {		blk = (struct header *)(ptr - minhead);		next = blk->nextblk;		/* deal with twits who reallocate free blocks */		/* if they haven't reset minblk via getopt, that's		   thier problem */		if (!TESTBUSY(next))  {			DELFREEQ(blk);			blk->nextblk = SETBUSY(next);		}		next = CLRBUSY(next);		/* make blk as big as possible */		if (!TESTBUSY(next->nextblk))  {			do {				DELFREEQ(next);				next = next->nextblk;			}  while (!TESTBUSY(next->nextblk));			blk->nextblk = SETBUSY(next);			if (next >= arenaend) lastblk = blk;		}  		/* get size we really need */		trusize = size+minhead;		trusize = (trusize + ALIGNSZ - 1)/ALIGNSZ*ALIGNSZ;		trusize = (trusize >= MINBLKSZ) ? trusize : MINBLKSZ;		/* see if we have enough */		/* this isn't really the copy size, but I need a register */		cpysize = (char *)next - (char *)blk;		if (cpysize >= trusize)  {			/* carve out the size we need */			register struct header *newblk; /* remainder */				if (cpysize - trusize >= MINBLKSZ)				{				/* carve out the right size block */				/* newblk will be the remainder */				newblk = (struct header *)((char *)blk 					  + trusize);				newblk->nextblk = next;				blk->nextblk = SETBUSY(newblk);				/* at this point, next is invalid */				ADDFREEQ(newblk);				/* if blk was lastblk, make newblk lastblk */				if(blk==lastblk) lastblk = newblk;			}			newptr = ptr;		}  else  {			/* bite the bullet, and call malloc */			cpysize = (size > cpysize) ? cpysize : size;			newptr = malloc(size);			if (newptr == NULL)  return NULL;			(void)memcpy(newptr,ptr,(int)cpysize);			free(ptr);		}       	}	return newptr;}/*LINTLIBRARY*//*      calloc - allocate and clear memory block*/void *calloc(num, size)register unsigned num, size;{	register char *mp;	num *= size;	mp = malloc(num);	if(mp == NULL)		return(NULL);	(void)memset(mp,0,(int)num);	return(mp);}/*      Mallopt - set options for allocation	Mallopt provides for   control over the allocation algorithm.	The cmds available are:	M_MXFAST Set maxfast to value.  Maxfast is the size of the		 largest small, quickly allocated block.  Maxfast		 may be set to 0 to disable fast allocation entirely.	M_NLBLKS Set numlblks   to value.  Numlblks is the number of		 small blocks per holding block.  Value must be		 greater than 0.	M_GRAIN  Set grain to value.  The sizes of all blocks		 smaller than maxfast are considered to be rounded		 up to the nearest multiple of grain.    The default		 value of grain is the smallest number of bytes		 which will allow alignment of any data type.    Grain		 will   be rounded up to a multiple of its default,		 and maxsize will be rounded up to a multiple   of		 grain.  Value must be greater than 0.	M_KEEP   Retain data in freed   block until the next malloc,		 realloc, or calloc.  Value is ignored.		 This option is provided only for compatibility with		 the old version of malloc, and is not recommended.	returns - 0, upon successful completion		  1, if malloc has previously been called or		     if value or cmd have illegal values*/mallopt(cmd, value)register int cmd;	       /* specifies option to set */register int value;	     /* value of option */{	/* disallow changes once a small block is allocated */	if (change)  {		return 1;	}	switch (cmd)  {	    case M_MXFAST:		if (value < 0)  {			return 1;		}		fastct = (value + grain - 1)/grain;		maxfast = grain*fastct;		break;	    case M_NLBLKS:		if (value <= 1)  {			return 1;		}		numlblks = value;		break;	    case M_GRAIN:		if (value <= 0)  {			return 1;		}		/* round grain up to a multiple of ALIGNSZ */		grain = (value + ALIGNSZ - 1)/ALIGNSZ*ALIGNSZ;		/* reduce fastct appropriately */		fastct = (fastct + grain - 1)/grain*grain;		maxfast = grain*fastct;		break;	    case M_KEEP:		minhead = HEADSZ;		break;	    default:		return 1;	}	return 0;}/*	mallinfo-provide information about space usage	input - max; mallinfo will return the size of the		largest block < max.	output - a structure containing a description of		 of space usage, defined in malloc.h*/struct mallinfomallinfo(){	struct header *blk, *next;	/* ptr to ordinary blocks */	struct holdblk *hblk;		/* ptr to holding blocks */	struct mallinfo inf;		/* return value */	register i;			/* the ubiquitous counter */	int size;			/* size of a block */	int fsp;			/* free space in 1 hold block */	(void)memset (&inf, 0, sizeof(struct mallinfo));	blk = CLRBUSY(arena[1].nextblk);	/* return total space used */	inf.arena = (char *)arenaend - (char *)blk;	/* loop through arena, counting # of blocks, and	   and space used by blocks */	next = CLRBUSY(blk->nextblk);	while (next != &(arena[1])) {		inf.ordblks++;		size = (char *)next - (char *)blk;		if (TESTBUSY(blk->nextblk))  {			inf.uordblks += size;			inf.keepcost += HEADSZ-MINHEAD;		}  else  {			inf.fordblks += size;		}		blk = next;		next = CLRBUSY(blk->nextblk);	}	/* 	examine space in holding blks	*/	for (i=fastct; i>0; i--)  {  /* loop thru ea. chain */	    hblk = holdhead[i];	    size = hblk->blksz + sizeof(struct lblk) - sizeof(int);	    if (hblk != HGROUND)  {  /* do only if chain not empty */		do  {		     /* loop thru 1 hold blk chain */		    inf.hblks++;    		    fsp = freespace(hblk);		    inf.fsmblks += fsp;		    inf.usmblks += numlblks*size - fsp;		    inf.smblks += numlblks;		    hblk = hblk->nexthblk;		}  while (hblk != holdhead[i]);	    }	}	inf.hblkhd = (inf.smblks/numlblks)*sizeof(struct holdblk);	/* holding block were counted in ordblks, so subtract off */	inf.ordblks -= inf.hblks;	inf.uordblks -= inf.hblkhd + inf.usmblks + inf.fsmblks;	inf.keepcost -= inf.hblks*(HEADSZ - MINHEAD);	return inf;}/*	freespace - calc. how much space is used in the free		    small blocks in a given holding block	input - hblk = given holding block	returns space used in free small blocks of hblk*/freespace(holdblk)  register struct holdblk *holdblk;{	register struct lblk *lblk;	register int space = 0;	register int size;	register struct lblk *unused;	lblk = CLRSMAL(holdblk->lfreeq);	size = holdblk->blksz + sizeof(struct lblk) - sizeof(int);	unused = CLRSMAL(holdblk->unused);	/* follow free chain */	while ((lblk != LGROUND) && (lblk != unused))  {		space += size;		lblk = CLRSMAL(lblk->header.nextfree);	}	space += ((char *)holdblk + HOLDSZ(size)) - (char *)unused;	return space;}#ifdef RSTALLOC/*      rstalloc - reset alloc routines	description - return allocated memory and reset		      allocation pointers.	Warning - This is for debugging purposes only.		  It will return all memory allocated after		  the first call to malloc, even if some		  of it was fetched by a user's sbrk().*/rstalloc(){	struct header *temp;	temp = arena;	minhead = MINHEAD;	grain = ALIGNSZ;	numlblks = NUMLBLKS;	fastct = FASTCT;	maxfast = MAXFAST;	change = 0;	if(freeptr->nextfree == GROUND) return;	brk(CLRBUSY(arena[1].nextblk));	freeptr->nextfree = GROUND;}#endif /*RSTALLOC*/

⌨️ 快捷键说明

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