libc: split libm nicely add a draft tinymalloc
authorAlan Cox <alan@linux.intel.com>
Tue, 21 Jun 2016 20:27:07 +0000 (21:27 +0100)
committerAlan Cox <alan@linux.intel.com>
Tue, 21 Jun 2016 20:27:07 +0000 (21:27 +0100)
Library/libs/Makefile
Library/libs/tinymalloc.c [new file with mode: 0644]

index a2f5987..23bdf44 100644 (file)
@@ -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 (file)
index 0000000..5c14b68
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+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;
+}