diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-03-20 17:14:21 +0000 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-03-22 13:57:44 +0000 |
commit | 37d43cf9dd5dd2d2cef1e86aa651097473fd0b48 (patch) | |
tree | 07a7df546f178c4e1576f4cbcc0bb4db3a8e18b4 /core/mem | |
parent | bf20364b582c383b4927f898de213b1cc0981a80 (diff) | |
parent | a107cb3b6fa219cf5f65bef366c9b00b108e9a3a (diff) | |
download | syslinux-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.c | 16 | ||||
-rw-r--r-- | core/mem/init.c | 6 | ||||
-rw-r--r-- | core/mem/malloc.c | 17 | ||||
-rw-r--r-- | core/mem/malloc.h | 18 |
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)) |