+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * This code is based on a version (aka dlmalloc) of malloc/free/realloc written
+ * by Doug Lea and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/-
+ *
+ * The original code is available at http://gee.cs.oswego.edu/pub/misc/
+ * as file malloc-2.6.6.c.
+ */
+
#include <common.h>
+#include <log.h>
+#include <asm/global_data.h>
-#ifdef CONFIG_SANDBOX
+#if CONFIG_IS_ENABLED(UNIT_TEST)
#define DEBUG
#endif
{
new_address = findRegion (new_address, new_size);
- if (new_address == 0)
+ if (!new_address)
return (void*)-1;
gAddressBase = gNextAddress =
(size + gNextAddress -
AlignPage (gNextAddress)),
MEM_COMMIT, PAGE_READWRITE);
- if (res == 0)
+ if (!res)
return (void*)-1;
}
tmp = (void*)gNextAddress;
| Unused space (may be 0 bytes long) .
. .
. |
+
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`foot:' | Size of chunk, in bytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
static inline void malloc_bin_reloc(void) {}
#endif
+#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
+static void malloc_init(void);
+#endif
+
ulong mem_malloc_start = 0;
ulong mem_malloc_end = 0;
ulong mem_malloc_brk = 0;
mem_malloc_end = start + size;
mem_malloc_brk = start;
+#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
+ malloc_init();
+#endif
+
debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start,
mem_malloc_end);
#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
static unsigned long max_mmapped_mem = 0;
#endif
+#ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
+static void malloc_init(void)
+{
+ int i, j;
+
+ debug("bins (av_ array) are at %p\n", (void *)av_);
+
+ av_[0] = NULL; av_[1] = NULL;
+ for (i = 2, j = 2; i < NAV * 2 + 2; i += 2, j++) {
+ av_[i] = bin_at(j - 2);
+ av_[i + 1] = bin_at(j - 2);
+
+ /* Just print the first few bins so that
+ * we can see there are alright.
+ */
+ if (i < 10)
+ debug("av_[%d]=%lx av_[%d]=%lx\n",
+ i, (ulong)av_[i],
+ i + 1, (ulong)av_[i + 1]);
+ }
+ /* Init the static bookkeeping as well */
+ sbrk_base = (char *)(-1);
+ max_sbrked_mem = 0;
+ max_total_mem = 0;
+#ifdef DEBUG
+ memset((void *)¤t_mallinfo, 0, sizeof(struct mallinfo));
+#endif
+}
+#endif
/*
Debugging support
#endif /* HAVE_MMAP */
-
-
-
/*
Extend the top-most chunk by obtaining memory from system.
Main interface to sbrk (but see also malloc_trim).
INTERNAL_SIZE_T nb;
-#ifdef CONFIG_SYS_MALLOC_F_LEN
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
return malloc_simple(bytes);
#endif
#if HAVE_MMAP
/* If big and would otherwise need to extend, try to use mmap instead */
if ((unsigned long)nb >= (unsigned long)mmap_threshold &&
- (victim = mmap_chunk(nb)) != 0)
+ (victim = mmap_chunk(nb)))
return chunk2mem(victim);
#endif
mchunkptr fwd; /* misc temp for linking */
int islr; /* track whether merging with last_remainder */
-#ifdef CONFIG_SYS_MALLOC_F_LEN
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
/* free() is a no-op - all the memory will be freed on relocation */
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
return;
mchunkptr fwd; /* misc temp for linking */
#ifdef REALLOC_ZERO_BYTES_FREES
- if (bytes == 0) { fREe(oldmem); return 0; }
+ if (!bytes) {
+ fREe(oldmem);
+ return NULL;
+ }
#endif
if ((long)bytes < 0) return NULL;
/* realloc of null is supposed to be same as malloc */
if (oldmem == NULL) return mALLOc(bytes);
-#ifdef CONFIG_SYS_MALLOC_F_LEN
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
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");
if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
/* Must alloc, copy, free. */
newmem = mALLOc(bytes);
- if (newmem == 0) return 0; /* propagate failure */
+ if (!newmem)
+ return NULL; /* propagate failure */
MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
munmap_chunk(oldp);
return newmem;
if ((long)bytes < 0) return NULL;
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+ if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
+ return memalign_simple(alignment, bytes);
+ }
+#endif
+
/* If need less alignment than we give anyway, just relay to malloc */
if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
return NULL;
else
{
-#ifdef CONFIG_SYS_MALLOC_F_LEN
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
- MALLOC_ZERO(mem, sz);
+ memset(mem, 0, sz);
return mem;
}
#endif
int initf_malloc(void)
{
-#ifdef CONFIG_SYS_MALLOC_F_LEN
+#if CONFIG_VAL(SYS_MALLOC_F_LEN)
assert(gd->malloc_base); /* Set up by crt0.S */
- gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
+ gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
gd->malloc_ptr = 0;
#endif