summaryrefslogtreecommitdiff
path: root/core/mem
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-03-20 17:14:21 +0000
committerMatt Fleming <matt.fleming@intel.com>2013-03-22 13:57:44 +0000
commit37d43cf9dd5dd2d2cef1e86aa651097473fd0b48 (patch)
tree07a7df546f178c4e1576f4cbcc0bb4db3a8e18b4 /core/mem
parentbf20364b582c383b4927f898de213b1cc0981a80 (diff)
parenta107cb3b6fa219cf5f65bef366c9b00b108e9a3a (diff)
downloadsyslinux-37d43cf9dd5dd2d2cef1e86aa651097473fd0b48.tar.gz
Merge tag 'syslinux-5.10-pre2' into for-hpa/elflink/firmware
syslinux-5.10-pre2 Conflicts: NEWS com32/include/netinet/in.h com32/include/sys/cpu.h com32/lib/Makefile core/Makefile core/fs/diskio.c core/fs/pxe/pxe.h core/init.c core/mem/free.c core/mem/malloc.c mk/devel.mk version
Diffstat (limited to 'core/mem')
-rw-r--r--core/mem/free.c16
-rw-r--r--core/mem/init.c6
-rw-r--r--core/mem/malloc.c17
-rw-r--r--core/mem/malloc.h18
4 files changed, 55 insertions, 2 deletions
diff --git a/core/mem/free.c b/core/mem/free.c
index 6fb8cfdd..2d16cd1c 100644
--- a/core/mem/free.c
+++ b/core/mem/free.c
@@ -75,7 +75,11 @@ void bios_free(void *ptr)
((struct arena_header *)ptr - 1);
#ifdef DEBUG_MALLOC
- assert( ARENA_TYPE_GET(ah->a.attrs) == ARENA_TYPE_USED );
+ if (ah->a.magic != ARENA_MAGIC)
+ dprintf("failed free() magic check: %p\n", ptr);
+
+ if (ARENA_TYPE_GET(ah->a.attrs) != ARENA_TYPE_USED)
+ dprintf("invalid arena type: %d\n", ARENA_TYPE_GET(ah->a.attrs));
#endif
__free_block(ah);
@@ -88,7 +92,9 @@ __export void free(void *ptr)
if ( !ptr )
return;
+ sem_down(&__malloc_semaphore, 0);
firmware->mem->free(ptr);
+ sem_up(&__malloc_semaphore);
/* Here we could insert code to return memory to the system. */
}
@@ -110,6 +116,8 @@ void __inject_free_block(struct free_arena_header *ah)
ARENA_SIZE_GET(ah->a.attrs), ah,
ARENA_HEAP_GET(ah->a.attrs), head);
+ sem_down(&__malloc_semaphore, 0);
+
for (nah = head->a.next ; nah != head ; nah = nah->a.next) {
n_end = (size_t) nah + ARENA_SIZE_GET(nah->a.attrs);
@@ -124,6 +132,7 @@ void __inject_free_block(struct free_arena_header *ah)
printf("conflict:ah: %p, a_end: %p, nah: %p, n_end: %p\n", ah, a_end, nah, n_end);
/* Otherwise we have some sort of overlap - reject this block */
+ sem_up(&__malloc_semaphore);
return;
}
@@ -134,6 +143,8 @@ void __inject_free_block(struct free_arena_header *ah)
ah->a.prev->a.next = ah;
__free_block(ah);
+
+ sem_up(&__malloc_semaphore);
}
/*
@@ -143,6 +154,8 @@ static void __free_tagged(malloc_tag_t tag) {
struct free_arena_header *fp, *head;
int i;
+ sem_down(&__malloc_semaphore, 0);
+
for (i = 0; i < NHEAP; i++) {
dprintf("__free_tagged(%u) heap %d\n", tag, i);
head = &__core_malloc_head[i];
@@ -153,6 +166,7 @@ static void __free_tagged(malloc_tag_t tag) {
}
}
+ sem_up(&__malloc_semaphore);
dprintf("__free_tagged(%u) done\n", tag);
}
diff --git a/core/mem/init.c b/core/mem/init.c
index 0526dfbf..ea9461c1 100644
--- a/core/mem/init.c
+++ b/core/mem/init.c
@@ -34,6 +34,9 @@ int scan_highmem_area(void *data, addr_t start, addr_t len, bool is_ram)
if (len >= 2 * sizeof(struct arena_header)) {
fp = (struct free_arena_header *)start;
fp->a.attrs = ARENA_TYPE_USED | (HEAP_MAIN << ARENA_HEAP_POS);
+#ifdef DEBUG_MALLOC
+ fp->a.magic = ARENA_MAGIC;
+#endif
ARENA_SIZE_SET(fp->a.attrs, len);
dprintf("will inject a block start:0x%x size 0x%x", start, len);
__inject_free_block(fp);
@@ -88,6 +91,9 @@ void mem_init(void)
fp = (struct free_arena_header *)__lowmem_heap;
fp->a.attrs = ARENA_TYPE_USED | (HEAP_LOWMEM << ARENA_HEAP_POS);
ARENA_SIZE_SET(fp->a.attrs, (*bios_free_mem << 10) - (uintptr_t)fp);
+#ifdef DEBUG_MALLOC
+ fp->a.magic = ARENA_MAGIC;
+#endif
__inject_free_block(fp);
/* Initialize the main heap */
diff --git a/core/mem/malloc.c b/core/mem/malloc.c
index c439dcbb..b40c2f21 100644
--- a/core/mem/malloc.c
+++ b/core/mem/malloc.c
@@ -13,6 +13,9 @@
#include <minmax.h>
#include "malloc.h"
+#include "thread.h"
+
+DECLARE_INIT_SEMAPHORE(__malloc_semaphore, 1);
static void *__malloc_from_block(struct free_arena_header *fp,
size_t size, malloc_tag_t tag)
@@ -33,6 +36,9 @@ static void *__malloc_from_block(struct free_arena_header *fp,
ARENA_HEAP_SET(nfp->a.attrs, heap);
ARENA_SIZE_SET(nfp->a.attrs, fsize-size);
nfp->a.tag = MALLOC_FREE;
+#ifdef DEBUG_MALLOC
+ nfp->a.magic = ARENA_MAGIC;
+#endif
ARENA_TYPE_SET(fp->a.attrs, ARENA_TYPE_USED);
ARENA_SIZE_SET(fp->a.attrs, size);
fp->a.tag = tag;
@@ -90,7 +96,9 @@ static void *_malloc(size_t size, enum heap heap, malloc_tag_t tag)
dprintf("_malloc(%zu, %u, %u) @ %p = ",
size, heap, tag, __builtin_return_address(0));
+ sem_down(&__malloc_semaphore, 0);
p = firmware->mem->malloc(size, heap, tag);
+ sem_up(&__malloc_semaphore);
dprintf("%p\n", p);
return p;
@@ -137,6 +145,11 @@ void *bios_realloc(void *ptr, size_t size)
head = &__core_malloc_head[ARENA_HEAP_GET(ah->a.attrs)];
+#ifdef DEBUG_MALLOC
+ if (ah->a.magic != ARENA_MAGIC)
+ dprintf("failed realloc() magic check: %p\n", ptr);
+#endif
+
/* Actual size of the old block */
//oldsize = ah->a.size;
oldsize = ARENA_SIZE_GET(ah->a.attrs);
@@ -177,6 +190,10 @@ void *bios_realloc(void *ptr, size_t size)
ARENA_SIZE_SET(ah->a.attrs, newsize);
ARENA_HEAP_SET(nah->a.attrs, ARENA_HEAP_GET(ah->a.attrs));
+#ifdef DEBUG_MALLOC
+ nah->a.magic = ARENA_MAGIC;
+#endif
+
//nah->a.type = ARENA_TYPE_FREE;
//nah->a.size = xsize - newsize;
//ah->a.size = newsize;
diff --git a/core/mem/malloc.h b/core/mem/malloc.h
index 3291cc25..4611a306 100644
--- a/core/mem/malloc.h
+++ b/core/mem/malloc.h
@@ -7,6 +7,9 @@
#include <stdint.h>
#include <stddef.h>
#include "core.h"
+#include "thread.h"
+
+extern struct semaphore __malloc_semaphore;
/*
* This is a temporary hack. In Syslinux 5 this will be a pointer to
@@ -32,6 +35,8 @@ enum heap {
NHEAP
};
+#define ARENA_MAGIC 0x20130117
+
struct free_arena_header;
/*
@@ -44,8 +49,19 @@ struct arena_header {
2..3: Heap,
4..31: MSB of the size */
struct free_arena_header *next, *prev;
+
+#ifdef DEBUG_MALLOC
+ unsigned long _pad[3];
+ unsigned int magic;
+#endif
};
+/* Pad to 2*sizeof(struct arena_header) */
+#define ARENA_PADDING ((2 * sizeof(struct arena_header)) - \
+ (sizeof(struct arena_header) + \
+ sizeof(struct free_arena_header *) + \
+ sizeof(struct free_arena_header *)))
+
/*
* This structure should be no more than twice the size of the
* previous structure.
@@ -53,7 +69,7 @@ struct arena_header {
struct free_arena_header {
struct arena_header a;
struct free_arena_header *next_free, *prev_free;
- size_t _pad[2]; /* Pad to 2*sizeof(struct arena_header) */
+ size_t _pad[ARENA_PADDING];
};
#define ARENA_SIZE_MASK (~(uintptr_t)(sizeof(struct arena_header)-1))