dm: Split the simple malloc() implementation into its own file
authorSimon Glass <sjg@chromium.org>
Tue, 11 Nov 2014 00:16:43 +0000 (17:16 -0700)
committerSimon Glass <sjg@chromium.org>
Fri, 21 Nov 2014 07:12:28 +0000 (08:12 +0100)
The simple malloc() implementation is used when memory is tight. It provides
a simple buffer with an incrementing pointer.

At present the implementation is inside dlmalloc. Move it into its own file
so that it is easier to find.

Rather than using relocation as a signal that the full malloc() is
available, add a special GD_FLG_FULL_MALLOC_INIT flag. This signals that the
simple malloc() should no longer be used.

In some cases, such as SPL, even the code space used by the full malloc() is
wasteful. Add a CONFIG_SYS_MALLOC_SIMPLE option to provide only the simple
malloc. In this case the full malloc is not available at all. It saves about
1KB of code space and about 0.5KB of data on Thumb 2.

Acked-by: Tom Rini <trini@ti.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
common/Makefile
common/board_r.c
common/dlmalloc.c
common/malloc_simple.c [new file with mode: 0644]
include/asm-generic/global_data.h
include/malloc.h

index 6cc4de8a73f6ab24a20760ded2d64e395b65a94f..7a5c58e41c2feaf99b4e5aba4825608cc3b9f023 100644 (file)
@@ -251,6 +251,9 @@ obj-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o
 obj-y += console.o
 obj-$(CONFIG_CROS_EC) += cros_ec.o
 obj-y += dlmalloc.o
+ifdef CONFIG_SYS_MALLOC_F_LEN
+obj-y += malloc_simple.o
+endif
 obj-y += image.o
 obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
 obj-$(CONFIG_OF_LIBFDT) += image-fdt.o
index 7c339008ed2a46b91677d4c4c9e5e97fd58f4a1f..19c64271ab9d151be1d7e289af50973c62427875 100644 (file)
@@ -99,7 +99,8 @@ static int initr_trace(void)
 
 static int initr_reloc(void)
 {
-       gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
+       /* tell others: relocation done */
+       gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;
        bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
 
        return 0;
index 991229d5f788f6d85b77833122b8fa2b65102ae1..6453ee9c259fcde7bfbe63099255b9823d5580c2 100644 (file)
@@ -2184,17 +2184,8 @@ Void_t* mALLOc(bytes) size_t bytes;
   INTERNAL_SIZE_T nb;
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-       if (gd && !(gd->flags & GD_FLG_RELOC)) {
-               ulong new_ptr;
-               void *ptr;
-
-               new_ptr = gd->malloc_ptr + bytes;
-               if (new_ptr > gd->malloc_limit)
-                       panic("Out of pre-reloc memory");
-               ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes);
-               gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
-               return ptr;
-       }
+       if (gd && !(gd->flags & GD_FLG_FULL_MALLOC_INIT))
+               return malloc_simple(bytes);
 #endif
 
   /* check if mem_malloc_init() was run */
@@ -2462,7 +2453,7 @@ void fREe(mem) Void_t* mem;
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
        /* free() is a no-op - all the memory will be freed on relocation */
-       if (!(gd->flags & GD_FLG_RELOC))
+       if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
                return;
 #endif
 
@@ -2618,7 +2609,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   if (oldmem == NULL) return mALLOc(bytes);
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-       if (!(gd->flags & GD_FLG_RELOC)) {
+       if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                /* This is harder to support and should not be needed */
                panic("pre-reloc realloc() is not supported");
        }
@@ -2970,7 +2961,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
   else
   {
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-       if (!(gd->flags & GD_FLG_RELOC)) {
+       if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                MALLOC_ZERO(mem, sz);
                return mem;
        }
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
new file mode 100644 (file)
index 0000000..afdacff
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Simple malloc implementation
+ *
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void *malloc_simple(size_t bytes)
+{
+       ulong new_ptr;
+       void *ptr;
+
+       new_ptr = gd->malloc_ptr + bytes;
+       if (new_ptr > gd->malloc_limit)
+               panic("Out of pre-reloc memory");
+       ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes);
+       gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
+       return ptr;
+}
+
+#ifdef CONFIG_SYS_MALLOC_SIMPLE
+void *calloc(size_t nmemb, size_t elem_size)
+{
+       size_t size = nmemb * elem_size;
+       void *ptr;
+
+       ptr = malloc(size);
+       memset(ptr, '\0', size);
+
+       return ptr;
+}
+#endif
index 74df21003363305e98a7b84d27275612df1a98fe..5e5dc3725a5495c2000396abec32d0e358035683 100644 (file)
@@ -107,5 +107,6 @@ typedef struct global_data {
 #define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out)      */
 #define GD_FLG_ENV_READY       0x00080 /* Env. imported into hash table   */
 #define GD_FLG_SERIAL_READY    0x00100 /* Pre-reloc serial console ready  */
+#define GD_FLG_FULL_MALLOC_INIT        0x00200 /* Full malloc() is ready          */
 
 #endif /* __ASM_GENERIC_GBL_DATA_H */
index c33f3b494eb95b4390c5c2192295fa8f85937edb..5df634873f147f93fb444b9621abf07e1e6e21e1 100644 (file)
@@ -872,33 +872,46 @@ extern Void_t*     sbrk();
 
 #else
 
-#ifdef USE_DL_PREFIX
-#define cALLOc         dlcalloc
-#define fREe           dlfree
-#define mALLOc         dlmalloc
-#define mEMALIGn       dlmemalign
-#define rEALLOc                dlrealloc
-#define vALLOc         dlvalloc
-#define pvALLOc                dlpvalloc
-#define mALLINFo       dlmallinfo
-#define mALLOPt                dlmallopt
-#else /* USE_DL_PREFIX */
-#define cALLOc         calloc
-#define fREe           free
-#define mALLOc         malloc
-#define mEMALIGn       memalign
-#define rEALLOc                realloc
-#define vALLOc         valloc
-#define pvALLOc                pvalloc
-#define mALLINFo       mallinfo
-#define mALLOPt                mallopt
-#endif /* USE_DL_PREFIX */
+#ifdef CONFIG_SYS_MALLOC_SIMPLE
+#define malloc malloc_simple
+#define realloc realloc_simple
+#define memalign memalign_simple
+static inline void free(void *ptr) {}
+void *calloc(size_t nmemb, size_t size);
+void *memalign_simple(size_t alignment, size_t bytes);
+void *realloc_simple(void *ptr, size_t size);
+#else
+
+# ifdef USE_DL_PREFIX
+# define cALLOc                dlcalloc
+# define fREe          dlfree
+# define mALLOc                dlmalloc
+# define mEMALIGn      dlmemalign
+# define rEALLOc               dlrealloc
+# define vALLOc                dlvalloc
+# define pvALLOc               dlpvalloc
+# define mALLINFo      dlmallinfo
+# define mALLOPt               dlmallopt
+# else /* USE_DL_PREFIX */
+# define cALLOc                calloc
+# define fREe          free
+# define mALLOc                malloc
+# define mEMALIGn      memalign
+# define rEALLOc               realloc
+# define vALLOc                valloc
+# define pvALLOc               pvalloc
+# define mALLINFo      mallinfo
+# define mALLOPt               mallopt
+# endif /* USE_DL_PREFIX */
 
 #endif
 
 /* Public routines */
 
-#if __STD_C
+/* Simple versions which can be used when space is tight */
+void *malloc_simple(size_t size);
+
+# if __STD_C
 
 Void_t* mALLOc(size_t);
 void    fREe(Void_t*);
@@ -913,7 +926,7 @@ size_t  malloc_usable_size(Void_t*);
 void    malloc_stats(void);
 int     mALLOPt(int, int);
 struct mallinfo mALLINFo(void);
-#else
+# else
 Void_t* mALLOc();
 void    fREe();
 Void_t* rEALLOc();
@@ -927,6 +940,7 @@ size_t  malloc_usable_size();
 void    malloc_stats();
 int     mALLOPt();
 struct mallinfo mALLINFo();
+# endif
 #endif
 
 /*