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/malloc.c | |
parent | 36970cc69149ef3a3f32d57663a14adedaebcbb9 (diff) |
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/malloc.c')
-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 */ |