diff options
| author | Eric Andersen <andersen@codepoet.org> | 2001-02-21 19:11:26 +0000 | 
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2001-02-21 19:11:26 +0000 | 
| commit | 2109636071eb7b3c085b6fcefcbed272a61e6713 (patch) | |
| tree | 7510cdca3d60f248c81648522c6273911d5f4146 /libc/stdlib/malloc | |
| parent | 36970cc69149ef3a3f32d57663a14adedaebcbb9 (diff) | |
| download | uClibc-alpine-2109636071eb7b3c085b6fcefcbed272a61e6713.tar.bz2 uClibc-alpine-2109636071eb7b3c085b6fcefcbed272a61e6713.tar.xz  | |
Update to "malloc" so it will work on CPUs not supporting non-aligned words.
malloc still only works for little-endian CPUs... Patch by Jean-Yves Avenard
Diffstat (limited to 'libc/stdlib/malloc')
| -rw-r--r-- | libc/stdlib/malloc/malloc.c | 42 | 
1 files changed, 35 insertions, 7 deletions
diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c index 5131fb74a..b5cfee3f0 100644 --- a/libc/stdlib/malloc/malloc.c +++ b/libc/stdlib/malloc/malloc.c @@ -64,7 +64,7 @@  #include <sys/mman.h>  #include <string.h>  #include "malloc.h" - +#include <stdio.h>  #define M_DOTRIMMING 1  #define M_MULTITHREADED 0 @@ -168,8 +168,8 @@ void *__hunk_alloc(int size)  	unsigned long *cpl;  	int i, c; -	if (size >= HUNK_THRESHOLD) -		size = ALIGN(size); +	//	if (size >= HUNK_THRESHOLD) +	size = ALIGN(size);  	/* Look for already allocated hunkblocks */  	if ((p = __free_h[size]) == NULL) { @@ -183,7 +183,10 @@ void *__hunk_alloc(int size)  							 MAP_PRIVATE | 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]; @@ -195,31 +198,52 @@ void *__hunk_alloc(int size)  	}  	/* 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 = *(int *) (((unsigned char *) cpl) + 1); +			c = *(((unsigned char *) cpl) + 1);  			i++; -		} else -			c = *(int *) (unsigned char *) cpl; +		} +		else +		  { +		    c = *(unsigned char *) cpl; +		  }  	} else {  		i += 2;  		c = *(((unsigned char *) cpl) + 2);  		if (c == 0xFF) { -			c = *(int *) (((unsigned char *) cpl) + 3); +			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++; @@ -230,6 +254,8 @@ void *__hunk_alloc(int size)  		__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 */ @@ -636,6 +662,7 @@ void __malloc_init(void)  	}  	mutex_init(&malloc_lock);  	__malloc_initialized = 1; +	// fprintf(stderr, "malloc_init: hunk_t=%d\n", sizeof(Hunk_t));  }  #endif							/* L__malloc_init */ @@ -662,6 +689,7 @@ void *malloc(size_t size)  	if (__malloc_initialized)  		mutex_unlock(&malloc_lock); +	// fprintf(stderr, "malloc returning: s=%d, p=%p\n", size, p);  	return p;  }  #endif							/* L_malloc */  | 
