[U-Boot] [PATCH v2 02/13] dm: Split the simple malloc() implementation into its own file

Simon Glass sjg at chromium.org
Thu Oct 23 21:15:59 CEST 2014


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.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2:
- Correct the Makefile condition for simple_malloc

 common/Makefile                   |  3 ++
 common/board_r.c                  |  3 +-
 common/dlmalloc.c                 | 19 ++++---------
 common/malloc_simple.c            | 38 +++++++++++++++++++++++++
 include/asm-generic/global_data.h |  1 +
 include/malloc.h                  | 60 ++++++++++++++++++++++++---------------
 6 files changed, 86 insertions(+), 38 deletions(-)
 create mode 100644 common/malloc_simple.c

diff --git a/common/Makefile b/common/Makefile
index c84b3bc..ad2fc7d 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -250,6 +250,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
diff --git a/common/board_r.c b/common/board_r.c
index 3affb63..54e9a93 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -105,7 +105,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;
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index f987339..16dc2ff 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -2181,17 +2181,8 @@ Void_t* mALLOc(bytes) size_t bytes;
   INTERNAL_SIZE_T nb;
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-	if (!(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->flags & GD_FLG_FULL_MALLOC_INIT))
+		return malloc_simple(bytes);
 #endif
 
   /* check if mem_malloc_init() was run */
@@ -2459,7 +2450,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
 
@@ -2615,7 +2606,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");
 	}
@@ -2967,7 +2958,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
index 0000000..bed227a
--- /dev/null
+++ b/common/malloc_simple.c
@@ -0,0 +1,38 @@
+/*
+ * Simple malloc implementation
+ *
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.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
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 74df210..5e5dc37 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -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 */
diff --git a/include/malloc.h b/include/malloc.h
index c33f3b4..5df6348 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -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
 
 /*
-- 
2.1.0.rc2.206.gedb03e5



More information about the U-Boot mailing list