mm: fix memory overhead when realloc fallbacks to malloc
authorEunBong Song <eunb.song@samsung.com>
Wed, 29 Mar 2017 01:35:33 +0000 (10:35 +0900)
committerHeesub Shin <heesub.shin@samsung.com>
Tue, 18 Apr 2017 03:02:03 +0000 (12:02 +0900)
When realloc() has to fall back to calling malloc(), size including
overhead was being provided to malloc(), causing a slightly larger
allocation than needed. Noted by initialkjc@yahoo.com

Change-Id: Ic9cb32d8e7ef82f431447e1a58b3e86f8bf9a789
Signed-off-by: Gregory Nutt <gnutt@nuttx.org>
[Song: back-ported 0064dc52e from the NuttX upstream]
Signed-off-by: EunBong Song <eunb.song@samsung.com>
os/mm/mm_heap/mm_realloc.c

index 950a8e7..8071d93 100644 (file)
@@ -109,7 +109,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
        FAR struct mm_allocnode_s *oldnode;
        FAR struct mm_freenode_s  *prev;
        FAR struct mm_freenode_s  *next;
-       size_t origsize;
+       size_t newsize;
        size_t oldsize;
        size_t prevsize = 0;
        size_t nextsize = 0;
@@ -132,12 +132,11 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
                return NULL;
        }
 
-       origsize = size;
        /* Adjust the size to account for (1) the size of the allocated node and
         * (2) to make sure that it is an even multiple of our granule size.
         */
 
-       size = MM_ALIGN_UP(size + SIZEOF_MM_ALLOCNODE);
+       newsize = MM_ALIGN_UP(size + SIZEOF_MM_ALLOCNODE);
 
        /* Map the memory chunk into an allocated node structure */
 
@@ -152,19 +151,19 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
        oldsize = oldnode->size;
 
 #ifndef CONFIG_DISABLE_REALLOC_NEIGHBOR_EXTENTION
-       if (size <= oldsize) {
+       if (newsize <= oldsize) {
                /* Handle the special case where we are not going to change the size
                 * of the allocation.
                 */
 
-               if (size < oldsize) {
+               if (newsize < oldsize) {
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
                        /* modify the current allocated size of old node */
                        heapinfo_subtract_size(oldnode->pid, oldsize);
                        heapinfo_update_total_size(heap, (-1) * oldsize);
 #endif
 
-                       mm_shrinkchunk(heap, oldnode, size);
+                       mm_shrinkchunk(heap, oldnode, newsize);
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
                        /* update the chunk to realloc task information */
                        heapinfo_update_node(oldnode, caller_retaddr);
@@ -197,8 +196,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
 
        /* Now, check if we can extend the current allocation or not */
 
-       if (nextsize + prevsize + oldsize >= size) {
-               size_t needed   = size - oldsize;
+       if (nextsize + prevsize + oldsize >= newsize) {
+               size_t needed   = newsize - oldsize;
                size_t takeprev = 0;
                size_t takenext = 0;
 
@@ -373,9 +372,9 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, size_t size)
                 */
                mm_givesemaphore(heap);
 #ifdef CONFIG_DEBUG_MM_HEAPINFO
-               newmem = (FAR void *)mm_malloc(heap, origsize, caller_retaddr);
+               newmem = (FAR void *)mm_malloc(heap, size, caller_retaddr);
 #else
-               newmem = (FAR void *)mm_malloc(heap, origsize);
+               newmem = (FAR void *)mm_malloc(heap, size);
 #endif
                if (newmem) {
                        memcpy(newmem, oldmem, oldsize);