libc/libminc malloc reorganization
. rename minix malloc sources to minix-* so Makefile
    references aren't ambiguous
  . throw out malloc source file copies in libminc
  . make libminc use phkmalloc instead of minix malloc (slightly faster)
			
			
This commit is contained in:
		
							parent
							
								
									c087a60ed2
								
							
						
					
					
						commit
						d3d8c30c2e
					
				| @ -44,9 +44,9 @@ SRCS+= erand48_ieee754.c | |||||||
| SRCS+=	jemalloc.c | SRCS+=	jemalloc.c | ||||||
| .elif (${USE_MINIXMALLOC} != "no") | .elif (${USE_MINIXMALLOC} != "no") | ||||||
| SRCS+=	\ | SRCS+=	\ | ||||||
| 	minix/malloc.c	\ | 	minix/minix-malloc.c	\ | ||||||
| 	minix/calloc.c	\ | 	minix/minix-calloc.c	\ | ||||||
| 	minix/malloc-debug.c | 	minix/minix-malloc-debug.c | ||||||
| .else | .else | ||||||
| SRCS+=	malloc.c | SRCS+=	malloc.c | ||||||
| .endif | .endif | ||||||
|  | |||||||
| @ -15,6 +15,12 @@ | |||||||
| #ifdef __minix | #ifdef __minix | ||||||
| #define mmap minix_mmap | #define mmap minix_mmap | ||||||
| #define munmap minix_munmap | #define munmap minix_munmap | ||||||
|  | #ifdef _LIBSYS | ||||||
|  | #include <minix/sysutil.h> | ||||||
|  | #define MALLOC_NO_SYSCALLS | ||||||
|  | #define wrtwarning(w) printf("libminc malloc warning: %s\n", w) | ||||||
|  | #define wrterror(w) panic("libminc malloc error: %s\n", w) | ||||||
|  | #endif | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| @ -309,6 +315,7 @@ static void *imalloc(size_t size); | |||||||
| static void ifree(void *ptr); | static void ifree(void *ptr); | ||||||
| static void *irealloc(void *ptr, size_t size); | static void *irealloc(void *ptr, size_t size); | ||||||
| 
 | 
 | ||||||
|  | #ifndef MALLOC_NO_SYSCALLS | ||||||
| static void | static void | ||||||
| wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4) | wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4) | ||||||
| { | { | ||||||
| @ -341,6 +348,7 @@ wrtwarning(const char *p) | |||||||
|     if (malloc_abort || issetugid() || getuid() == 0 || getgid() == 0) |     if (malloc_abort || issetugid() || getuid() == 0 || getgid() == 0) | ||||||
| 	wrterror(p); | 	wrterror(p); | ||||||
| } | } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Allocate a number of pages from the OS |  * Allocate a number of pages from the OS | ||||||
| @ -452,16 +460,20 @@ extend_pgdir(size_t idx) | |||||||
| static void | static void | ||||||
| malloc_init(void) | malloc_init(void) | ||||||
| { | { | ||||||
|  |     int save_errno = errno; | ||||||
|  | #ifndef MALLOC_NO_SYSCALLS | ||||||
|     const char *p; |     const char *p; | ||||||
|     char b[64]; |     char b[64]; | ||||||
|     size_t i; |     size_t i; | ||||||
|     ssize_t j; |     ssize_t j; | ||||||
|     int save_errno = errno; |  | ||||||
| 
 | 
 | ||||||
|     /*
 |     /*
 | ||||||
|      * Compute page-size related variables. |      * Compute page-size related variables. | ||||||
|      */ |      */ | ||||||
|     malloc_pagesize = (size_t)sysconf(_SC_PAGESIZE); |     malloc_pagesize = (size_t)sysconf(_SC_PAGESIZE); | ||||||
|  | #else | ||||||
|  |     malloc_pagesize = PAGE_SIZE; | ||||||
|  | #endif | ||||||
|     malloc_pagemask = malloc_pagesize - 1; |     malloc_pagemask = malloc_pagesize - 1; | ||||||
|     for (malloc_pageshift = 0; |     for (malloc_pageshift = 0; | ||||||
| 	 (1UL << malloc_pageshift) != malloc_pagesize; | 	 (1UL << malloc_pageshift) != malloc_pagesize; | ||||||
| @ -474,6 +486,7 @@ malloc_init(void) | |||||||
|     malloc_junk = 1; |     malloc_junk = 1; | ||||||
| #endif /* MALLOC_EXTRA_SANITY */ | #endif /* MALLOC_EXTRA_SANITY */ | ||||||
| 
 | 
 | ||||||
|  | #ifndef MALLOC_NO_SYSCALLS | ||||||
|     for (i = 0; i < 3; i++) { |     for (i = 0; i < 3; i++) { | ||||||
| 	if (i == 0) { | 	if (i == 0) { | ||||||
| 	    j = readlink("/etc/malloc.conf", b, sizeof b - 1); | 	    j = readlink("/etc/malloc.conf", b, sizeof b - 1); | ||||||
| @ -519,6 +532,7 @@ malloc_init(void) | |||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|     UTRACE(0, 0, 0); |     UTRACE(0, 0, 0); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -47,7 +47,6 @@ SRCS+=	memset.c | |||||||
| #
 | #
 | ||||||
| # Customized versions of libc functions.
 | # Customized versions of libc functions.
 | ||||||
| #
 | #
 | ||||||
| SRCS+= 	calloc.c malloc.c |  | ||||||
| SRCS+= 	fputs.c _stdfile.c | SRCS+= 	fputs.c _stdfile.c | ||||||
| CPPFLAGS.fputs.c+= -I${LIBCSRCDIR}/include | CPPFLAGS.fputs.c+= -I${LIBCSRCDIR}/include | ||||||
| 
 | 
 | ||||||
| @ -65,7 +64,7 @@ SRCS+=	${i} | |||||||
| .endfor | .endfor | ||||||
| # Import from stdlib
 | # Import from stdlib
 | ||||||
| .for i in abort.c atexit.c atoi.c exit.c getenv.c \ | .for i in abort.c atexit.c atoi.c exit.c getenv.c \ | ||||||
| 	getopt.c ldiv.c | 	getopt.c ldiv.c malloc.c | ||||||
| .PATH.c: ${LIBCSRCDIR}/stdlib | .PATH.c: ${LIBCSRCDIR}/stdlib | ||||||
| SRCS+= ${i} | SRCS+= ${i} | ||||||
| CPPFLAGS.${i}+= -I${LIBCSRCDIR}/stdlib -I${LIBCSRCDIR}/include  | CPPFLAGS.${i}+= -I${LIBCSRCDIR}/stdlib -I${LIBCSRCDIR}/include  | ||||||
|  | |||||||
| @ -1,28 +0,0 @@ | |||||||
| /* $Header$ */ |  | ||||||
| #include	<stdlib.h> |  | ||||||
| 
 |  | ||||||
| /* replace undef by define */ |  | ||||||
| #define  ALIGN_EIGHT_BYTES /* Use 8-byte alignment. */ |  | ||||||
| 
 |  | ||||||
| #ifdef  ALIGN_EIGHT_BYTES |  | ||||||
| #define ALIGN_SIZE 8 |  | ||||||
| #else |  | ||||||
| #define ALIGN_SIZE sizeof(size_t) |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #define ALIGN(x)	(((x) + (ALIGN_SIZE - 1)) & ~(ALIGN_SIZE - 1)) |  | ||||||
| 
 |  | ||||||
| void * |  | ||||||
| calloc(size_t nelem, size_t elsize) |  | ||||||
| { |  | ||||||
| 	register char *p; |  | ||||||
| 	register size_t *q; |  | ||||||
| 	size_t size = ALIGN(nelem * elsize); |  | ||||||
| 
 |  | ||||||
| 	p = malloc(size); |  | ||||||
| 	if (p == NULL) return NULL; |  | ||||||
| 	q = (size_t *) (p + size); |  | ||||||
| 	while ((char *) q > p) *--q = 0; |  | ||||||
| 	return p; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @ -1,243 +0,0 @@ | |||||||
| /* $Header$ */ |  | ||||||
| 
 |  | ||||||
| /* replace undef by define */ |  | ||||||
| #define  ALIGN_EIGHT_BYTES /* Use 8-byte alignment. */ |  | ||||||
| #define	 DEBUG		   /* check assertions */ |  | ||||||
| #undef	 SLOWDEBUG	   /* some extra test loops (requires DEBUG) */ |  | ||||||
| 
 |  | ||||||
| #ifndef DEBUG |  | ||||||
| #define NDEBUG |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #include	<stdlib.h> |  | ||||||
| #include	<string.h> |  | ||||||
| #include	<errno.h> |  | ||||||
| #include	<assert.h> |  | ||||||
| 
 |  | ||||||
| #define CHECK_DBG(statement) |  | ||||||
| 
 |  | ||||||
| #define	ptrint		int |  | ||||||
| 
 |  | ||||||
| #define BRKSIZE		4096 |  | ||||||
| #ifdef ALIGN_EIGHT_BYTES |  | ||||||
| #define PTRSIZE		8 |  | ||||||
| #else |  | ||||||
| #define	PTRSIZE		((int) sizeof(void *)) |  | ||||||
| #endif |  | ||||||
| #define Align(x,a)	(((x) + (a - 1)) & ~(a - 1)) |  | ||||||
| #define NextSlot(p)	(* (void **) ((p) - PTRSIZE)) |  | ||||||
| #define NextFree(p)	(* (void **) (p)) |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * A short explanation of the data structure and algorithms. |  | ||||||
|  * An area returned by malloc() is called a slot. Each slot |  | ||||||
|  * contains the number of bytes requested, but preceeded by |  | ||||||
|  * an extra pointer to the next the slot in memory. |  | ||||||
|  * '_bottom' and '_top' point to the first/last slot. |  | ||||||
|  * More memory is asked for using brk() and appended to top. |  | ||||||
|  * The list of free slots is maintained to keep malloc() fast. |  | ||||||
|  * '_empty' points the the first free slot. Free slots are |  | ||||||
|  * linked together by a pointer at the start of the |  | ||||||
|  * user visable part, so just after the next-slot pointer. |  | ||||||
|  * Free slots are merged together by free(). |  | ||||||
|  * |  | ||||||
|  * Since modern processors prefer 8-byte alignment, we now pretend |  | ||||||
|  * our pointers are 8 bytes wide. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| extern void *_sbrk(int); |  | ||||||
| extern int _brk(void *); |  | ||||||
| static void *_bottom, *_top, *_empty; |  | ||||||
| 
 |  | ||||||
| static int grow(size_t len) |  | ||||||
| { |  | ||||||
|   register char *p; |  | ||||||
| 
 |  | ||||||
|   assert(NextSlot((char *)_top) == 0); |  | ||||||
|   if ((char *) _top + len < (char *) _top |  | ||||||
|       || (p = (char *)Align((ptrint)_top + len, BRKSIZE)) < (char *) _top ) { |  | ||||||
| 	errno = ENOMEM; |  | ||||||
| 	return(0); |  | ||||||
|   } |  | ||||||
|   if (_brk(p) != 0) |  | ||||||
| 	return(0); |  | ||||||
|   NextSlot((char *)_top) = p; |  | ||||||
|   NextSlot(p) = 0; |  | ||||||
|   free(_top); |  | ||||||
|   _top = p; |  | ||||||
|   return 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void * |  | ||||||
| malloc(const size_t size) |  | ||||||
| { |  | ||||||
|   register char *prev, *p, *next, *new; |  | ||||||
|   unsigned ntries; |  | ||||||
| 
 |  | ||||||
|   if (size == 0) |  | ||||||
| 	return NULL; |  | ||||||
| 
 |  | ||||||
|   CHECK_DBG(return _dbg_malloc(size)); |  | ||||||
| 
 |  | ||||||
|   for (ntries = 0; ntries < 2; ntries++) { |  | ||||||
| 	unsigned len = Align(size, PTRSIZE) + PTRSIZE; |  | ||||||
| 	if (len < 2 * PTRSIZE) { |  | ||||||
| 		errno = ENOMEM; |  | ||||||
| 		return NULL; |  | ||||||
| 	} |  | ||||||
| 	if (_bottom == 0) { |  | ||||||
| 		if ((p = _sbrk(2 * PTRSIZE)) == (char *) -1) |  | ||||||
| 			return NULL; |  | ||||||
| 		p = (char *) Align((ptrint)p, PTRSIZE); |  | ||||||
| 		p += PTRSIZE; |  | ||||||
| 		_top = _bottom = p; |  | ||||||
| 		NextSlot(p) = 0; |  | ||||||
| 	} |  | ||||||
| #ifdef SLOWDEBUG |  | ||||||
| 	for (p = _bottom; (next = NextSlot(p)) != 0; p = next) |  | ||||||
| 		assert(next > p); |  | ||||||
| 	assert(p == _top); |  | ||||||
| #endif |  | ||||||
| 	for (prev = 0, p = _empty; p != 0; prev = p, p = NextFree(p)) { |  | ||||||
| 		next = NextSlot(p); |  | ||||||
| 		new = p + len;	/* easily overflows!! */ |  | ||||||
| 		if (new > next || new <= p) |  | ||||||
| 			continue;		/* too small */ |  | ||||||
| 		if (new + PTRSIZE < next) {	/* too big, so split */ |  | ||||||
| 			/* + PTRSIZE avoids tiny slots on free list */ |  | ||||||
| 			NextSlot(new) = next; |  | ||||||
| 			NextSlot(p) = new; |  | ||||||
| 			NextFree(new) = NextFree(p); |  | ||||||
| 			NextFree(p) = new; |  | ||||||
| 		} |  | ||||||
| 		if (prev) |  | ||||||
| 			NextFree(prev) = NextFree(p); |  | ||||||
| 		else |  | ||||||
| 			_empty = NextFree(p); |  | ||||||
| 		return p; |  | ||||||
| 	} |  | ||||||
| 	if (grow(len) == 0) |  | ||||||
| 		break; |  | ||||||
|   } |  | ||||||
|   assert(ntries != 2); |  | ||||||
|   return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void * |  | ||||||
| realloc(void *oldp, size_t size) |  | ||||||
| { |  | ||||||
|   register char *prev, *p, *next, *new; |  | ||||||
|   char *old = oldp; |  | ||||||
|   register size_t len, n; |  | ||||||
| 
 |  | ||||||
|   if (old == 0) |  | ||||||
| 	return malloc(size); |  | ||||||
|   if (size == 0) { |  | ||||||
| 	free(old); |  | ||||||
| 	return NULL; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   CHECK_DBG(return _dbg_realloc(oldp, size)); |  | ||||||
| 
 |  | ||||||
|   len = Align(size, PTRSIZE) + PTRSIZE; |  | ||||||
|   next = NextSlot(old); |  | ||||||
|   n = (int)(next - old);			/* old length */ |  | ||||||
|   /*
 |  | ||||||
|    * extend old if there is any free space just behind it |  | ||||||
|    */ |  | ||||||
|   for (prev = 0, p = _empty; p != 0; prev = p, p = NextFree(p)) { |  | ||||||
| 	if (p > next) |  | ||||||
| 		break; |  | ||||||
| 	if (p == next) {	/* 'next' is a free slot: merge */ |  | ||||||
| 		NextSlot(old) = NextSlot(p); |  | ||||||
| 		if (prev) |  | ||||||
| 			NextFree(prev) = NextFree(p); |  | ||||||
| 		else |  | ||||||
| 			_empty = NextFree(p); |  | ||||||
| 		next = NextSlot(old); |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
|   } |  | ||||||
|   new = old + len; |  | ||||||
|   /*
 |  | ||||||
|    * Can we use the old, possibly extended slot? |  | ||||||
|    */ |  | ||||||
|   if (new <= next && new >= old) {		/* it does fit */ |  | ||||||
| 	if (new + PTRSIZE < next) {		/* too big, so split */ |  | ||||||
| 		/* + PTRSIZE avoids tiny slots on free list */ |  | ||||||
| 		NextSlot(new) = next; |  | ||||||
| 		NextSlot(old) = new; |  | ||||||
| 		free(new); |  | ||||||
| 	} |  | ||||||
| 	return old; |  | ||||||
|   } |  | ||||||
|   if ((new = malloc(size)) == NULL)		/* it didn't fit */ |  | ||||||
| 	return NULL; |  | ||||||
|   memcpy(new, old, n);				/* n < size */ |  | ||||||
|   free(old); |  | ||||||
|   return new; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void |  | ||||||
| free(void *ptr) |  | ||||||
| { |  | ||||||
|   register char *prev, *next; |  | ||||||
|   char *p = ptr; |  | ||||||
| 
 |  | ||||||
|   if (p == 0) |  | ||||||
| 	return; |  | ||||||
| 
 |  | ||||||
|   CHECK_DBG(_dbg_free(ptr); return); |  | ||||||
| 
 |  | ||||||
| #ifdef SLOWDEBUG |  | ||||||
|   { |  | ||||||
|   	int found; |  | ||||||
| 	char *curr; |  | ||||||
| 
 |  | ||||||
| 	/* block must be in block list */ |  | ||||||
| 	assert(_bottom); |  | ||||||
| 	found = 0; |  | ||||||
| 	for (curr = _bottom; (next = NextSlot(curr)) != 0; curr = next) { |  | ||||||
| 		assert(next > curr); |  | ||||||
| 		if (curr == p) found = 1; |  | ||||||
| 	} |  | ||||||
| 	if (curr == p) found = 1; |  | ||||||
| 	assert(found); |  | ||||||
| 
 |  | ||||||
| 	/* block must not be in free list */ |  | ||||||
| 	if (_empty) { |  | ||||||
| 		found = 0; |  | ||||||
| 		for (curr = _empty; (next = NextFree(curr)) != 0; curr = next) { |  | ||||||
| 			assert(next > curr); |  | ||||||
| 			if (curr == p) found = 1; |  | ||||||
| 		} |  | ||||||
| 		if (curr == p) found = 1; |  | ||||||
| 		assert(!found); |  | ||||||
| 	} |  | ||||||
|   } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|   assert((char *) NextSlot(p) > p); |  | ||||||
|   for (prev = 0, next = _empty; next != 0; prev = next, next = NextFree(next)) |  | ||||||
| 	if (p < next) |  | ||||||
| 		break; |  | ||||||
|   NextFree(p) = next; |  | ||||||
|   if (prev) |  | ||||||
| 	NextFree(prev) = p; |  | ||||||
|   else |  | ||||||
| 	_empty = p; |  | ||||||
|   if (next) { |  | ||||||
| 	assert((char *) NextSlot(p) <= next); |  | ||||||
| 	if (NextSlot(p) == next) {		/* merge p and next */ |  | ||||||
| 		NextSlot(p) = NextSlot(next); |  | ||||||
| 		NextFree(p) = NextFree(next); |  | ||||||
| 	} |  | ||||||
|   } |  | ||||||
|   if (prev) { |  | ||||||
| 	assert((char *) NextSlot(prev) <= p); |  | ||||||
| 	if (NextSlot(prev) == p) {		/* merge prev and p */ |  | ||||||
| 		NextSlot(prev) = NextSlot(p); |  | ||||||
| 		NextFree(prev) = NextFree(p); |  | ||||||
| 	} |  | ||||||
|   } |  | ||||||
| } |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ben Gras
						Ben Gras