[syslinux:lwip] core: Make the core malloc and free thread safe.

syslinux-bot for Eric W. Biederman ebiederm at xmission.com
Fri Apr 22 20:05:10 PDT 2011


Commit-ID:  a100261df05a228f8590328c12d60ca0c7a03198
Gitweb:     http://syslinux.zytor.com/commit/a100261df05a228f8590328c12d60ca0c7a03198
Author:     Eric W. Biederman <ebiederm at xmission.com>
AuthorDate: Sat, 9 Apr 2011 05:42:22 -0700
Committer:  Eric W. Biederman <ebiederm at xmission.com>
CommitDate: Sat, 9 Apr 2011 18:27:07 -0700

core: Make the core malloc and free thread safe.

Add a single semaphore to make malloc and free thread safe.

This is code I extracted from hpa's earlier effort at
importing lwip into syslinux.

Signed-off-by: Eric W. Biederman <ebiederm at xmission.com>


---
 core/mem/free.c   |   10 ++++++++++
 core/mem/malloc.c |    7 +++++++
 core/mem/malloc.h |    3 +++
 3 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/core/mem/free.c b/core/mem/free.c
index 384f10e..6052333 100644
--- a/core/mem/free.c
+++ b/core/mem/free.c
@@ -80,7 +80,9 @@ void free(void *ptr)
     assert( ARENA_TYPE_GET(ah->a.attrs) == ARENA_TYPE_USED );
 #endif
 
+    sem_down(&__malloc_semaphore, 0);
     __free_block(ah);
+    sem_up(&__malloc_semaphore);
 
   /* Here we could insert code to return memory to the system. */
 }
@@ -102,6 +104,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);
 
@@ -114,6 +118,7 @@ void __inject_free_block(struct free_arena_header *ah)
             continue;
 
         /* Otherwise we have some sort of overlap - reject this block */
+	sem_up(&__malloc_semaphore);
         return;
     }
 
@@ -124,6 +129,8 @@ void __inject_free_block(struct free_arena_header *ah)
     ah->a.prev->a.next = ah;
 
     __free_block(ah);
+
+    sem_up(&__malloc_semaphore);
 }
 
 /*
@@ -133,6 +140,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 = &__malloc_head[i];
@@ -143,6 +152,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/malloc.c b/core/mem/malloc.c
index 78f7b41..48fdcc7 100644
--- a/core/mem/malloc.c
+++ b/core/mem/malloc.c
@@ -9,6 +9,9 @@
 #include <string.h>
 #include <dprintf.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)
@@ -66,6 +69,8 @@ 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);
+
     if (size) {
 	/* Add the obligatory arena header, and round up */
 	size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
@@ -79,6 +84,8 @@ static void *_malloc(size_t size, enum heap heap, malloc_tag_t tag)
         }
     }
 
+    sem_up(&__malloc_semaphore);
+
     dprintf("%p\n", p);
     return p;
 }
diff --git a/core/mem/malloc.h b/core/mem/malloc.h
index b8ec44d..66b9b2b 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



More information about the Syslinux-commits mailing list