[comp.bugs.4bsd] malloc 5.6 bug fix

welsh@cvl.umd.edu (Chris Welsh) (01/07/89)

1d0
< 
23,36d21
< /*
<  * Modified, 12/21/88
<  * Chris Welsh, Center for Automation Research, U of Md., welsh@cvl.umd.edu
<  *
<  * Modification rectifies an omission whereby, if a request was made of a size
<  * for which the apropos hash bucket was empty, and sbrk() didn't come through
<  * with more memory, rather than scan larger buckets for blocks that could've
<  * been fragmented to fill the hash bucket at issue, malloc() returned NULL.
<  * This feature had the unfortunate consequence that a program engaging in a
<  * cycle of malloc()ing and free()ing of blocks of decreasing size could reach
<  * a state where all free memory was concentrated in blocks too large to
<  * satisfy the current request. 
<  */
< 
117c102
<   	register int bucket, donor;
---
>   	register int bucket;
147c132
< 	if (nbytes <= (pagesz - sizeof(*op) - RSLOP)) {
---
> 	if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) {
154a140
> 		n = -(sizeof (*op) + RSLOP);
159,160c145
< 	n = sizeof(*op) + RSLOP;
< 	while (nbytes > amt - n) {
---
> 	while (nbytes > amt + n) {
172,202c157,158
< 
< 		/*
< 		 * If the system had nothing to offer, see if there are any
< 		 * blocks in a larger bucket that we can cannibalize into
< 		 * smaller ones. This will fragment memory, but the alternative
< 		 * is to fail.
< 		 */
< 		donor = bucket;
< 		while (((op = nextf[donor]) == NULL) && (donor < NBUCKETS))
< 			donor++;
< 
< 		/*
< 		 * If the request is going to be honored by a block from a
< 		 * donor (that is, larger) bucket, remove that block from
< 		 * its bucket, split it into the appropriate number of
< 		 * sub-blocks, each half the size of the last, and attach
< 		 * them each to the front of their appropriate bucket.
< 		 */
< 		if (donor != bucket) {
< 	  		if (donor >= NBUCKETS)
<   				return( NULL );
< 			nextf[donor] = nextf[donor]->ov_next;
< 			for ( ; donor - bucket; donor--) {
< 				union overhead *op2;
< 	(op2 = (union overhead *)((caddr_t)op + (1 << (donor+2))))->ov_next
< 					= nextf[donor-1];
< 				nextf[donor-1] = op2;
< 			}
< 			op->ov_next = nextf[bucket];
< 			nextf[bucket] = op;
< 		}
---
>   		if ((op = nextf[bucket]) == NULL)
>   			return (NULL);
204d159
< 
250c205
< 		amt = sz;
---
> 		amt = sz + pagesz;