From: Alan Cox Date: Tue, 21 Jun 2016 20:27:07 +0000 (+0100) Subject: libc: split libm nicely add a draft tinymalloc X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=a18b56d786f4176f0b79077b666c982ff39eb7ca;p=FUZIX.git libc: split libm nicely add a draft tinymalloc --- diff --git a/Library/libs/Makefile b/Library/libs/Makefile index a2f59874..23bdf443 100644 --- a/Library/libs/Makefile +++ b/Library/libs/Makefile @@ -68,33 +68,35 @@ SRC_HARD += regexp.c #SRC_C += strncpy.c strpbrk.c strrchr.c strspn.c strstr.c strtok.c #SRC_C += memchr.c memcmp.c memcpy.c memset.c -SRC_C += acosf.c acoshf.c asinf.c asinhf.c atan2f.c atanf.c atanhf.c -SRC_C += cbrtf.c ceilf.c copysignf.c erff.c expf.c expm1f.c -SRC_C += fabsf.c fdimf.c floorf.c fmaxf.c fminf.c fmodf.c frexpf.c -SRC_C += hypotf.c ilogbf.c j0f.c j1f.c jnf.c -SRC_C += ldexpf.c lgammaf.c lgammaf_r.c logf.c log2f.c log10f.c logbf.c -SRC_C += lrintf.c lroundf.c -SRC_C += modff.c nearbyintf.c nextafterf.c powf.c -SRC_C += remainderf.c remquof.c rintf.c -SRC_C += scalbnf.c scalbinf.c -SRC_C += sinf.c sincosf.c sinhf.c -SRC_C += sqrtf.c tgammaf.c -SRC_C += __expo2f.c __float_bits.c __fpclassifyf.c __log1pf.c __signgam.c - SRC_CT += termcap.c SRC_CURS = $(shell find curses -name '*.c') -SRC_LM = vfscanf.c vfprintf.c -OBJ_LM = vfscanf-libm.rel vfprintf-libm.rel +SRC_LM += acosf.c acoshf.c asinf.c asinhf.c atan2f.c atanf.c atanhf.c +SRC_LM += cbrtf.c ceilf.c copysignf.c erff.c expf.c expm1f.c +SRC_LM += fabsf.c fdimf.c floorf.c fmaxf.c fminf.c fmodf.c frexpf.c +SRC_LM += hypotf.c ilogbf.c j0f.c j1f.c jnf.c +SRC_LM += ldexpf.c lgammaf.c lgammaf_r.c logf.c log2f.c log10f.c logbf.c +SRC_LM += lrintf.c lroundf.c +SRC_LM += modff.c nearbyintf.c nextafterf.c powf.c +SRC_LM += remainderf.c remquof.c rintf.c +SRC_LM += scalbnf.c scalbinf.c +SRC_LM += sinf.c sincosf.c sinhf.c +SRC_LM += sqrtf.c tgammaf.c +SRC_LM += vfscanf_m.c vfprintf_m.c +SRC_LM += __expo2f.c __float_bits.c __fpclassifyf.c __log1pf.c __signgam.c + +SRC_TM = tinymalloc.c OBJ_C = $(SRC_C:.c=.rel) OBJ_CURS = $(SRC_CURS:.c=.rel) OBJ_CT = $(SRC_CT:.c=.rel) +OBJ_LM = $(SRC_LM:.c=.rel) +OBJ_TM = $(SRC_TM:.c=.rel) OBJ_HARD = $(SRC_HARD:.c=.rel) OBJ_ALL = $(OBJ_ASM) $(OBJ_C) $(OBJ_HARD) -all: syslib$(PLATFORM).lib crt0$(PLATFORM).rel crt0nostdio$(PLATFORM).rel liberror.txt curses$(PLATFORM).lib termcap$(PLATFORM).lib m$(PLATFORM).lib +all: syslib$(PLATFORM).lib crt0$(PLATFORM).rel crt0nostdio$(PLATFORM).rel liberror.txt curses$(PLATFORM).lib termcap$(PLATFORM).lib m$(PLATFORM).lib tinymalloc$(PLATFORM).lib libc.l:%.l:$(OBJ_ALL) ls $(OBJ_ALL) > libc.l @@ -125,13 +127,17 @@ curses$(PLATFORM).lib: $(OBJ_CURS) $(AR) rc curses$(PLATFORM).lib $(OBJ_CURS) $(AR) s curses$(PLATFORM).lib +m$(PLATFORM).lib: $(OBJ_LM) + $(AR) rc m$(PLATFORM).lib $(OBJ_LM) + $(AR) s m$(PLATFORM).lib + termcap$(PLATFORM).lib: $(OBJ_CT) $(AR) rc termcap$(PLATFORM).lib $(OBJ_CT) $(AR) s termcap$(PLATFORM).lib -m$(PLATFORM).lib: $(OBJ_LM) - $(AR) rc m$(PLATFORM).lib $(OBJ_LM) - $(AR) s m$(PLATFORM).lib +tinymalloc$(PLATFORM).lib: $(OBJ_TM) + $(AR) rc tinymalloc$(PLATFORM).lib $(OBJ_TM) + $(AR) s tinymalloc$(PLATFORM).lib $(OBJ_ASM):%.rel: %.s $(ASM) $(ASM_OPT) $@ $(@:.rel=.s) @@ -151,11 +157,11 @@ $(OBJ_CT):%.rel: %.c $(OBJ_CURS):%.rel: %.c $(CC) $(CC_OPT) $(@:.rel=.c) -o $@ -vfscanf-libm.rel: vfscanf.c +$(OBJ_LM):%.rel: %.c $(CC) $(CC_OPT) -DBUILD_LIBM $< -o $@ -vfprintf-libm.rel: vfscanf.c - $(CC) $(CC_OPT) -DBUILD_LIBM $< -o $@ +$(OBJ_TM):%.rel: %.c + $(CC) $(CC_OPT) $(@:.rel=.c) $(OBJ_HARD):%.rel: %.c $(CC) $(CC_NOOPT) $(@:.rel=.c) @@ -168,4 +174,4 @@ clean: install: cp crt0$(PLATFORM).rel crt0nostdio$(PLATFORM).rel c$(PLATFORM).lib /opt/fcc/lib/ cp curses$(PLATFORM).lib termcap$(PLATFORM).lib /opt/fcc/lib/ - cp m$(PLATFORM).lib /opt/fcc/lib/ + cp m$(PLATFORM).lib tinymalloc$(PLATFORM).lib /opt/fcc/lib/ diff --git a/Library/libs/tinymalloc.c b/Library/libs/tinymalloc.c new file mode 100644 index 00000000..5c14b68f --- /dev/null +++ b/Library/libs/tinymalloc.c @@ -0,0 +1,75 @@ +/* + * A tiny stub malloc for those cases that can use it + * + * - malloc is fully implemented + * - free only applies in reverse order + * - realloc only applies to last malloc + * + * But if you can meet those rules it's really quite efficient 8) + */ + +#include +#include +#include +#include + +static intptr_t *last; + +static void check(void *p) +{ + if (p != (void *)(last - 1)) { + write(2, "tinymalloc: unsupported.\n", 26); + exit(1); + } +} + +static uint8_t dobrk(uint8_t *p, size_t n) +{ + if (n + 7 < n) + return 0; + n = (n + 7) & ~7; + /* Overflow catch */ + if (p + n < p || brk(p + n)) + return 0; + return 1; +} + +void *malloc(size_t n) +{ + uint8_t *p; + + + /* Here be dragons: sbrk takes a signed value. We can however in C malloc + a size_t: We also assume nobody else misaligns the brk boundary, we won't + fix it if so - maybe we should ? */ + + /* Current end of memory */ + p = sbrk(0); + if (p == (uint8_t *) -1 || !dobrk(p, n)) + return NULL; + /* Fake it as a used block and free it into the free list */ + *(intptr_t *)p = (intptr_t)last; + last = (intptr_t *)p; + return p + 1; +} + +void free(void *p) +{ + intptr_t n; + + check(p); + n = last[-1]; + brk(last); + last = (intptr_t *)n; +} + +void *realloc(void *pv, size_t n) +{ + uint8_t *p; + check(pv); + + p = (uint8_t *)last[-1]; + if (!dobrk(p, n)) + return NULL; + return pv; +}