From 3bb1b5d92fdf2f78535eb72a83d542c21830b2fc Mon Sep 17 00:00:00 2001 From: Greg Haerr Date: Mon, 16 Dec 2024 18:47:38 -0700 Subject: [PATCH] [libc] Add malloc_usable_size, write general-purpose realloc --- libc/include/malloc.h | 33 +++++++++++++++++++-------------- libc/malloc/Makefile | 2 +- libc/malloc/amalloc.c | 13 +++++++++++++ libc/malloc/malloc.c | 7 +++++++ libc/malloc/realloc.c | 16 ++++++---------- libc/malloc/v7malloc.c | 20 ++++++++++++++++---- 6 files changed, 62 insertions(+), 29 deletions(-) diff --git a/libc/include/malloc.h b/libc/include/malloc.h index b1640e4f6..769819ad2 100644 --- a/libc/include/malloc.h +++ b/libc/include/malloc.h @@ -4,27 +4,32 @@ #include /* default malloc (dev86) */ -void *malloc(size_t); -void *realloc(void *, size_t); -void free(void *); +void *malloc(size_t); +void free(void *); +size_t malloc_usable_size(void *); /* debug malloc (v7 malloc) */ -void *__dmalloc(size_t); -void *__drealloc(void *, size_t); -void __dfree(void *); +void *__dmalloc(size_t); +void *__drealloc(void *, size_t); +void __dfree(void *); +size_t __dmalloc_usable_size(void *); /* arena malloc (64k near/unlimited far heap) */ -void *__amalloc(size_t); -int __amalloc_add_heap(char __far *start, size_t size); -void *__arealloc(void *, size_t); /* NYI */ -void __afree(void *); +void *__amalloc(size_t); +int __amalloc_add_heap(char __far *start, size_t size); +void *__arealloc(void *, size_t); /* NYI */ +void __afree(void *); +size_t __dmalloc_usable_size(void *); -void *calloc(size_t elm, size_t sz); +/* usable with all mallocs */ +void *realloc(void *, size_t); +void *calloc(size_t elm, size_t sz); /* alloc/free from main memory */ void __far *fmemalloc(unsigned long size); -int fmemfree(void __far *ptr); -int _fmemalloc(int paras, unsigned short *pseg); -int _fmemfree(unsigned short seg); +int fmemfree(void __far *ptr); + +int _fmemalloc(int paras, unsigned short *pseg); /* syscall */ +int _fmemfree(unsigned short seg); /* syscall */ #endif diff --git a/libc/malloc/Makefile b/libc/malloc/Makefile index 0414d5a66..523cb76a1 100644 --- a/libc/malloc/Makefile +++ b/libc/malloc/Makefile @@ -18,7 +18,6 @@ CFLAGS += -DMCHUNK=16 DEFAULT_MALLOC_OBJS = \ malloc.o \ free.o \ - realloc.o \ __mini_malloc.o \ __alloca_alloc.o \ __freed_list.o \ @@ -33,6 +32,7 @@ ARENA_MALLOC_OBJS = amalloc.o # these objects work with any malloc OBJS = \ + realloc.o \ calloc.o \ brk.o \ sbrk.o \ diff --git a/libc/malloc/amalloc.c b/libc/malloc/amalloc.c index 407387391..3a50c1ba3 100644 --- a/libc/malloc/amalloc.c +++ b/libc/malloc/amalloc.c @@ -249,6 +249,19 @@ __afree(void *ptr) malloc_show_heap(); } +size_t __amalloc_usable_size(void *ptr) +{ + NPTR p = (NPTR)ptr; + + if (p == NULL) + return 0; + ASSERT(FP_SEG(ptr)==allocseg); + ASSERT(p>clearbusy(allocs[allocsize-1].ptr)&&p<=alloct); + --p; + ASSERT(testbusy(next(p))); + return (clearbusy(next(p)) - clearbusy(p)) * sizeof(union store); +} + #if LATER /* realloc(p, nbytes) reallocates a block obtained from malloc() * and freed since last call of malloc() diff --git a/libc/malloc/malloc.c b/libc/malloc/malloc.c index 6a07acfe1..473154569 100644 --- a/libc/malloc/malloc.c +++ b/libc/malloc/malloc.c @@ -188,6 +188,13 @@ __search_chunk(unsigned int mem_size) return p1; } +size_t malloc_usable_size(void *ptr) +{ + if (ptr == 0) + return 0; + return (m_size(((mem *) ptr) - 1) - 1) * sizeof(mem); +} + void * malloc(size_t size) { diff --git a/libc/malloc/realloc.c b/libc/malloc/realloc.c index d652e9ca4..04b5a0eee 100644 --- a/libc/malloc/realloc.c +++ b/libc/malloc/realloc.c @@ -1,26 +1,22 @@ #include #include -#include "_malloc.h" - -#undef malloc - -void * -realloc(void *ptr, size_t size) +/* this realloc usable with all malloc allocators */ +void *realloc(void *ptr, size_t size) { void *nptr; - unsigned int osize; + size_t osize; if (ptr == 0) return malloc(size); - osize = (m_size(((mem *) ptr) - 1) - 1) * sizeof(mem); - + osize = malloc_usable_size(ptr); +#if LATER if (size <= osize) return ptr; +#endif nptr = malloc(size); - if (nptr == 0) return 0; diff --git a/libc/malloc/v7malloc.c b/libc/malloc/v7malloc.c index 5d3b81f5e..08662534e 100644 --- a/libc/malloc/v7malloc.c +++ b/libc/malloc/v7malloc.c @@ -109,8 +109,8 @@ __dmalloc(size_t nbytes) if (nbytes < MINALLOC) nbytes = MINALLOC; - /* check INT overflow beyond 32762 (nbytes/WORD+WORD+WORD+(WORD-1) > 0xFFFF/WORD/WORD)*/ - if (nbytes > ((unsigned)-1)/WORD-WORD-WORD-(WORD-1)) { + /* check INT overflow beyond 32762 (nbytes/WORD+2*WORD+(WORD-1) > 0xFFFF/WORD/WORD) */ + if (nbytes > ((unsigned)-1)/WORD-2*WORD-(WORD-1)) { debug(" (req too big) = NULL\n"); errno = ENOMEM; return(NULL); @@ -133,8 +133,8 @@ __dmalloc(size_t nbytes) (next(q) - q) * sizeof(union store)); next(p) = next(q); } - debug2("q %04x p %04x nw %d p+nw %04x ", (unsigned)q, (unsigned)p, - nw, (unsigned)(p+nw)); + /*debug2("q %04x p %04x nw %d p+nw %04x ", (unsigned)q, (unsigned)p, + nw, (unsigned)(p+nw));*/ if(q>=p+nw && p+nw>=p) goto found; } @@ -227,6 +227,18 @@ __dfree(void *ptr) malloc_show_heap(); } +size_t __dmalloc_usable_size(void *ptr) +{ + NPTR p = (NPTR)ptr; + + if (p == NULL) + return 0; + ASSERT(p>clearbusy(allocs[SIZE-1].ptr)&&p<=alloct); + --p; + ASSERT(testbusy(next(p))); + return (clearbusy(next(p)) - clearbusy(p)) * sizeof(union store); +} + /* realloc(p, nbytes) reallocates a block obtained from malloc() * and freed since last call of malloc() * to have new size nbytes, and old content