Explorar o código

fix the memory block splitting issue

Bernard Xiong %!s(int64=11) %!d(string=hai) anos
pai
achega
2c33678aac
Modificáronse 1 ficheiros con 22 adicións e 14 borrados
  1. 22 14
      src/memheap.c

+ 22 - 14
src/memheap.c

@@ -25,6 +25,7 @@
  *                             change mutex lock to semaphore lock.
  * 2013-04-10     Bernard      add rt_memheap_realloc function.
  * 2013-05-24     Bernard      fix the rt_memheap_realloc issue.
+ * 2013-07-11     Grissiom     fix the memory block splitting issue.
  */
 
 #include <rthw.h>
@@ -122,7 +123,7 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap,
     rt_sem_init(&(memheap->lock), name, 1, RT_IPC_FLAG_FIFO);
 
     RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
-                 ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x",
+                 ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x\n",
                   start_addr, size, &(memheap->free_header)));
 
     return RT_EOK;
@@ -199,7 +200,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size)
                           (((rt_uint8_t *)header_ptr) + size + RT_MEMHEAP_SIZE);
 
                 RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
-                             ("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]",
+                             ("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]\n",
                               header_ptr,
                               header_ptr->next,
                               header_ptr->prev,
@@ -228,7 +229,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size)
                 new_ptr->prev_free = heap->free_list;
                 heap->free_list->next_free->prev_free = new_ptr;
                 heap->free_list->next_free            = new_ptr;
-                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: next_free 0x%08x, prev_free 0x%08x",
+                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: next_free 0x%08x, prev_free 0x%08x\n",
                                                 new_ptr->next_free,
                                                 new_ptr->prev_free));
 
@@ -248,7 +249,7 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size)
 
                 /* remove header_ptr from free list */
                 RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
-                             ("one block: block[0x%08x], next_free 0x%08x, prev_free 0x%08x",
+                             ("one block: block[0x%08x], next_free 0x%08x, prev_free 0x%08x\n",
                               header_ptr,
                               header_ptr->next_free,
                               header_ptr->prev_free));
@@ -267,12 +268,12 @@ void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size)
 
             /* Return a memory address to the caller.  */
             RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
-                         ("alloc mem: memory[0x%08x], heap[0x%08x], size: %d",
+                         ("alloc mem: memory[0x%08x], heap[0x%08x], size: %d\n",
                           (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE),
                           header_ptr,
-                          size);
+                          size));
 
-            return (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE));
+            return (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE);
         }
 
         /* release lock */
@@ -328,6 +329,10 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
         return new_ptr;
     }
 
+    /* don't split when there is less than one node space left */
+    if (newsize + RT_MEMHEAP_SIZE + RT_MEMHEAP_MINIALLOC >= oldsize)
+        return ptr;
+
     /* lock memheap */
     result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
     if (result != RT_EOK)
@@ -342,7 +347,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
               (((rt_uint8_t *)header_ptr) + newsize + RT_MEMHEAP_SIZE);
 
     RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
-                 ("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]",
+                 ("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]\n",
                   header_ptr,
                   header_ptr->next,
                   header_ptr->prev,
@@ -369,7 +374,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
         heap->available_size = heap->available_size - MEMITEM_SIZE(free_ptr);
 
         RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
-                     ("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x",
+                     ("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x\n",
                       header_ptr, header_ptr->next_free, header_ptr->prev_free));
 
         free_ptr->next->prev = new_ptr;
@@ -385,7 +390,7 @@ void *rt_memheap_realloc(struct rt_memheap *heap, void *ptr, rt_size_t newsize)
     new_ptr->prev_free = heap->free_list;
     heap->free_list->next_free->prev_free = new_ptr;
     heap->free_list->next_free            = new_ptr;
-    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new free ptr: next_free 0x%08x, prev_free 0x%08x",
+    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new free ptr: next_free 0x%08x, prev_free 0x%08x\n",
                                     new_ptr->next_free,
                                     new_ptr->prev_free));
 
@@ -407,13 +412,16 @@ void rt_memheap_free(void *ptr)
     struct rt_memheap_item *header_ptr, *new_ptr;
     rt_uint32_t insert_header;
 
+	/* NULL check */
+	if (ptr == RT_NULL) return;
+
     /* set initial status as OK */
     insert_header = 1;
     new_ptr       = RT_NULL;
     header_ptr    = (struct rt_memheap_item *)
                     ((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);
 
-    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: memory[0x%08x], block[0x%08x]",
+    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: memory[0x%08x], block[0x%08x]\n",
                                     ptr, header_ptr));
 
     /* check magic */
@@ -439,7 +447,7 @@ void rt_memheap_free(void *ptr)
     /* Determine if the block can be merged with the previous neighbor. */
     if (!RT_MEMHEAP_IS_USED(header_ptr->prev))
     {
-        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x",
+        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x\n",
                                         header_ptr->prev));
 
         /* adjust the available number of bytes. */
@@ -465,7 +473,7 @@ void rt_memheap_free(void *ptr)
         new_ptr = header_ptr->next;
 
         RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
-                     ("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x",
+                     ("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x\n",
                       new_ptr, new_ptr->next_free, new_ptr->prev_free));
 
         new_ptr->next->prev = header_ptr;
@@ -485,7 +493,7 @@ void rt_memheap_free(void *ptr)
         heap->free_list->next_free            = header_ptr;
 
         RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
-                     ("insert to free list: next_free 0x%08x, prev_free 0x%08x",
+                     ("insert to free list: next_free 0x%08x, prev_free 0x%08x\n",
                       header_ptr->next_free, header_ptr->prev_free));
     }