Browse Source

some more refactoring; keeping better tracking of big blocks during debug mode

Ioannis Koutras 12 years ago
parent
commit
a86dc08071
8 changed files with 164 additions and 113 deletions
  1. 2 1
      private-include/debug.h
  2. 33 0
      private-include/other.h
  3. 1 0
      src/CMakeLists.txt
  4. 22 20
      src/debug.c
  5. 17 45
      src/free.c
  6. 10 15
      src/malloc.c
  7. 48 0
      src/other.c
  8. 31 32
      src/realloc.c

+ 2 - 1
private-include/debug.h

@@ -31,6 +31,7 @@
 
 void get_raw_blocks(allocator_t *allocator);
 
-raw_block_header_t *find_raw_block_owner(void *ptr);
+void add_to_big_rb_list(raw_block_header_t *rb);
+void remove_from_big_rb_list(raw_block_header_t *rb);
 
 #endif /* DEBUG_H */

+ 33 - 0
private-include/other.h

@@ -0,0 +1,33 @@
+/*
+ *   Copyright Institute of Communication and Computer Systems (ICCS) 
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * @file   other.h
+ * @author Ioannis Koutras (joko@microlab.ntua.gr)
+ * @date   October 2012
+ * @brief  Auxiliary functions
+ */
+
+#ifndef OTHER_H
+#define OTHER_H
+#include "dmm_config.h"
+
+#include "dmmlib/raw_block.h"
+
+raw_block_header_t * find_raw_block_owner(raw_block_header_t *head, void* ptr);
+
+#endif /* OTHER_H */

+ 1 - 0
src/CMakeLists.txt

@@ -40,6 +40,7 @@ if(NOT WITH_SYSTEM_CALLS STREQUAL "none")
     realloc.c
     calloc.c
     release_memory.c
+    other.c
     )
 endif(NOT WITH_SYSTEM_CALLS STREQUAL "none")
 

+ 22 - 20
src/debug.c

@@ -27,6 +27,7 @@
 #include "trace.h"
 #include <stdbool.h>
 #include "dmmlib/dmmlib.h"
+#include "locks.h"
 
 /** Gets the number of raw blocks that are currently managed by an allocator.
  *
@@ -63,28 +64,29 @@ void get_raw_blocks(allocator_t *allocator) {
     TRACE_3("dmmlib - there are %d big blocks\n", counter);
 }
 
-/** Tries to find the raw block owner of a memory allocation.
- *
- * @param ptr The pointer of the memory allocation.
- */
-raw_block_header_t *find_raw_block_owner(void *ptr) {
-    raw_block_header_t *current_raw_block;
-    bool found;
+/** Add a big block to the list */
+void add_to_big_rb_list(raw_block_header_t *rb) {
+    rb->next_raw_block = systemallocator.big_blocks_head;
+    systemallocator.big_blocks_head = rb;
+}
 
-    for(current_raw_block = systemallocator.raw_block_head;
-            current_raw_block != NULL;
-            current_raw_block = current_raw_block->next_raw_block) {
-        if(((char *)ptr > (char *)current_raw_block) &&
-                ((char *)ptr < (char *)current_raw_block +
-                 current_raw_block->size)) {
-            found = true;
-            break;
-        }
-    }
+/** Removes a big block from the list */
+void remove_from_big_rb_list(raw_block_header_t *rb) {
+    raw_block_header_t *previous_block = NULL;
 
-    if(found) {
-        return current_raw_block;
+    lock_global();
+    if(systemallocator.big_blocks_head == rb) {
+        systemallocator.big_blocks_head = rb->next_raw_block;
     } else {
-        return NULL;
+        for(raw_block_header_t *current_block = systemallocator.big_blocks_head;
+            current_block != NULL;
+            current_block = current_block->next_raw_block
+       ) {
+            if(current_block == rb) {
+                previous_block->next_raw_block = current_block->next_raw_block;
+            }
+            previous_block = current_block;
+        }
     }
+    unlock_global();
 }

+ 17 - 45
src/free.c

@@ -26,23 +26,26 @@
 #include "dmmlib/dmmlib.h"
 
 #include <inttypes.h>
-#include <stdbool.h>
 
 #include "locks.h"
 
 #include "default_rb.h"
+#include "other.h"
 
 #ifdef WITH_ALLOCATOR_STATS
 #include "statistics.h"
 #endif /* WITH_ALLOCATOR_STATS */
 
+#ifdef WITH_DEBUG
+#include "debug.h"
+#endif /* WITH_DEBUG */
+
 #include "release_memory.h"
 
 #include "trace.h"
 
 void free(void *ptr) {
-    raw_block_header_t *current_raw_block;
-    bool found;
+    raw_block_header_t *owner_raw_block;
 
     if(ptr == NULL) {
         return;
@@ -50,66 +53,35 @@ void free(void *ptr) {
 
     TRACE_1("dmmlib - f %p\n", ptr);
 
-    found = false;
-
-    current_raw_block = systemallocator.raw_block_head;
-    while(current_raw_block) {
-        if(((uintptr_t) ptr > (uintptr_t) current_raw_block) &&
-                ((uintptr_t) ptr < (uintptr_t) current_raw_block +
-                 current_raw_block->size)) {
-            found = true;
-            break;
-        }
-        current_raw_block = current_raw_block->next_raw_block;
-    }
+    owner_raw_block = find_raw_block_owner(systemallocator.raw_block_head,
+            ptr);
 
-    if(found == true) {
+    if(owner_raw_block != NULL) {
 
         DEFAULT_RB_T *encapsulated_rb = (DEFAULT_RB_T *)
-            ((uintptr_t) current_raw_block + sizeof(raw_block_header_t));
+            ((uintptr_t) owner_raw_block + sizeof(raw_block_header_t));
 
-        lock_raw_block(current_raw_block);
+        lock_raw_block(owner_raw_block);
         dmmlib_free(encapsulated_rb, ptr);
-        unlock_raw_block(current_raw_block);
+        unlock_raw_block(owner_raw_block);
 
     } else { // It has to be a BIGBLOCK, just munmap it
-
-        current_raw_block = (raw_block_header_t *)
+        owner_raw_block = (raw_block_header_t *)
             ((uintptr_t) ptr - sizeof(raw_block_header_t));
 
-        /* Remove big block from the list of big blocks that exists when debug
-         * mode is on */
 #ifdef WITH_DEBUG
-        raw_block_header_t *previous_raw_block = NULL;
-
-        for(raw_block_header_t *block_in_list =
-                systemallocator.big_blocks_head;
-                block_in_list != NULL;
-                block_in_list = block_in_list->next_raw_block
-                ) {
-            if(block_in_list == current_raw_block) {
-                if(systemallocator.big_blocks_head == current_raw_block) {
-                    lock_global();
-                    systemallocator.big_blocks_head =
-                        current_raw_block->next_raw_block;
-                    unlock_global();
-                } else {
-                    previous_raw_block->next_raw_block =
-                        current_raw_block->next_raw_block;
-                }
-            }
-        }
+        remove_from_big_rb_list(owner_raw_block);
 #endif /* WITH_DEBUG */
 
 #ifdef WITH_ALLOCATOR_STATS
         update_stats(&systemallocator.dmm_stats,
                 FREE,
 #ifdef REQUEST_SIZE_INFO
-                current_raw_block->size - sizeof(raw_block_header_t),
+                owner_raw_block->size - sizeof(raw_block_header_t),
 #endif /* REQUEST_SIZE_INFO */
-                current_raw_block->size);
+                owner_raw_block->size);
 #endif /* WITH_ALLOCATOR_STATS */
 
-        release_memory(current_raw_block);
+        release_memory(owner_raw_block);
     }
 }

+ 10 - 15
src/malloc.c

@@ -35,17 +35,15 @@
 #include "statistics.h"
 #endif /* WITH_ALLOCATOR_STATS */
 
+#ifdef WITH_DEBUG
+#include "debug.h"
+#endif /* WITH_DEBUG */
+
 #include "trace.h"
 
 void * malloc(size_t size) {
     raw_block_header_t *raw_block, *new_raw_block;
-#ifdef BITMAP_RB_ONLY
-    bitmap_rb_t
-#endif /* BITMAP_RB_ONLY */
-#ifdef FL_RB_ONLY
-    freelist_rb_t
-#endif /* FL_RB_ONLY */
-        *encapsulated_rb;
+    DEFAULT_RB_T *encapsulated_rb;
     void *ptr;
 
     raw_block = systemallocator.raw_block_head;
@@ -91,18 +89,13 @@ void * malloc(size_t size) {
                 sizeof(freelist_rb_t)) {
 #endif /* FL_RB_ONLY */
 
+            lock_global();
             ptr = (void *)create_raw_block(size +
                     sizeof(raw_block_header_t), BIGBLOCK);
             if(ptr != NULL) {
 
-                /* When debugging is enabled, the big blocks are also stored on
-                 * a list. */
 #ifdef WITH_DEBUG
-                lock_global();
-                ((raw_block_header_t *)ptr)->next_raw_block = 
-                    systemallocator.big_blocks_head;
-                systemallocator.big_blocks_head = (raw_block_header_t *)ptr;
-                unlock_global();
+                add_to_big_rb_list((raw_block_header_t *)ptr);
 #endif /* WITH_DEBUG */
 
 #ifdef WITH_ALLOCATOR_STATS
@@ -114,6 +107,8 @@ void * malloc(size_t size) {
                         size + sizeof(raw_block_header_t));
 #endif /* WITH_ALLOCATOR_STATS */
 
+                unlock_global();
+
                 ptr = (void *)((uintptr_t) ptr + sizeof(raw_block_header_t));
             }
 
@@ -123,11 +118,11 @@ void * malloc(size_t size) {
             new_raw_block = create_raw_block((size_t) SYS_ALLOC_SIZE,
                     DEFAULT_RB_TYPE);
             if(new_raw_block != NULL) {
+                lock_raw_block(new_raw_block);
                 new_raw_block->next_raw_block = systemallocator.raw_block_head;
                 systemallocator.raw_block_head = new_raw_block;
                 unlock_global();
 
-                lock_raw_block(new_raw_block);
                 encapsulated_rb = (DEFAULT_RB_T *)
                     ((uintptr_t) new_raw_block + sizeof(raw_block_header_t));
                 ptr = dmmlib_malloc(encapsulated_rb, size);

+ 48 - 0
src/other.c

@@ -0,0 +1,48 @@
+/*
+ *   Copyright Institute of Communication and Computer Systems (ICCS) 
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * @file   other.c
+ * @author Ioannis Koutras (joko@microlab.ntua.gr)
+ * @date   October 2012
+ *
+ * @brief  Implementation of auxiliary calls.
+ */
+
+#include "other.h"
+
+#include <inttypes.h>
+
+/** Finds the raw block owner of a certain pointer */
+raw_block_header_t * find_raw_block_owner(raw_block_header_t *head, void* ptr) {
+    raw_block_header_t *owner = NULL;
+
+    for(raw_block_header_t *current_block = head;
+            current_block != NULL;
+            current_block = current_block->next_raw_block
+       ) {
+        if(((uintptr_t) current_block < (uintptr_t) ptr) &&
+                ((uintptr_t) ptr < (uintptr_t) current_block +
+                 current_block->size)
+          ) {
+            owner = current_block;
+            break;
+        }
+    }
+
+    return owner;
+}

+ 31 - 32
src/realloc.c

@@ -25,21 +25,24 @@
 
 #include "dmmlib/dmmlib.h"
 
-#include <stdbool.h>
-
+#include "locks.h"
 #include "default_rb.h"
+#include "other.h"
 
 #include "release_memory.h"
 #include <sys/mman.h>
 
 #include <string.h>
 
+#ifdef WITH_DEBUG
+#include "debug.h"
+#endif /* WITH_DEBUG */
+
 #include "trace.h"
 
 void * realloc(void *ptr, size_t size) {
-    raw_block_header_t *current_raw_block;
-    bool found;
-    void *return_ptr;
+    raw_block_header_t *owner_raw_block;
+    void *return_ptr = NULL;
 
     if(ptr == NULL) {
         return malloc(size);
@@ -47,27 +50,16 @@ void * realloc(void *ptr, size_t size) {
 
     if(size == 0) {
         free(ptr);
-        return_ptr = malloc((size_t) 32); // FIXME 32 <- minimum size
         goto done;
     }
 
-    current_raw_block = systemallocator.raw_block_head;
-    found = false;
-
-    while(current_raw_block) {
-        if(((char *)ptr > (char *)current_raw_block) &&
-                ((char *)ptr < (char *)(current_raw_block) +
-                 current_raw_block->size)) {
-            found = true;
-            break;
-        }
-        current_raw_block = current_raw_block->next_raw_block;
-    }
+    owner_raw_block = find_raw_block_owner(systemallocator.raw_block_head,
+            ptr);
 
-    if(found == true) {
+    if(owner_raw_block != NULL) {
 
         DEFAULT_RB_T *encapsulated_rb = (DEFAULT_RB_T *)
-            ((uintptr_t) current_raw_block + sizeof(raw_block_header_t));
+            ((uintptr_t) owner_raw_block + sizeof(raw_block_header_t));
         
         return_ptr = dmmlib_realloc(encapsulated_rb, ptr, size);
         goto done;
@@ -79,19 +71,19 @@ void * realloc(void *ptr, size_t size) {
         // greater, a new big block is initialized, data is copied there and the
         // old big block gets de-allocated.
 
-        current_raw_block = (raw_block_header_t *)
+        owner_raw_block = (raw_block_header_t *)
             ((uintptr_t) ptr - sizeof(raw_block_header_t));
 
         size_t full_size = sizeof(raw_block_header_t) + size;
 
-        if(full_size <= current_raw_block->size) {
+        if(full_size <= owner_raw_block->size) {
 
-            size_t remaining_size = current_raw_block->size - full_size;
-            current_raw_block->size = full_size;
+            size_t remaining_size = owner_raw_block->size - full_size;
+            owner_raw_block->size = full_size;
 
             // FIXME This is mmap-specific
-            munmap((void *)((uintptr_t) current_raw_block +
-                        current_raw_block->size), remaining_size);
+            munmap((void *)((uintptr_t) owner_raw_block +
+                        owner_raw_block->size), remaining_size);
 
 #ifdef WITH_ALLOCATOR_STATS
             systemallocator.dmm_stats.total_mem_allocated -=
@@ -110,9 +102,9 @@ void * realloc(void *ptr, size_t size) {
             return_ptr = ptr;
             goto done;
 
-        } else {
+        } else { /* We have to create a new big block */
 
-            size_t size_diff = full_size - current_raw_block->size;
+            size_t size_diff = full_size - owner_raw_block->size;
 
             raw_block_header_t *new_block = create_raw_block(full_size,
                     BIGBLOCK);
@@ -126,11 +118,17 @@ void * realloc(void *ptr, size_t size) {
 
                 memcpy((void *)((uintptr_t) new_block +
                             sizeof(raw_block_header_t)), ptr,
-                        current_raw_block->size - sizeof(raw_block_header_t));
+                        owner_raw_block->size - sizeof(raw_block_header_t));
+
+#ifdef WITH_DEBUG
+                remove_from_big_rb_list(owner_raw_block);
+                add_to_big_rb_list(new_block);
+#endif /* WITH_DEBUG */
 
-                release_memory(current_raw_block);
+                release_memory(owner_raw_block);
 
 #ifdef WITH_ALLOCATOR_STATS
+                lock_global();
                 systemallocator.dmm_stats.total_mem_allocated +=
                     size_diff;
                 TRACE_2("dmmlib - ms all %zu\n",
@@ -142,10 +140,11 @@ void * realloc(void *ptr, size_t size) {
                         systemallocator.dmm_stats.total_mem_requested);
 #endif /* REQUEST_SIZE_INFO */
                 systemallocator.dmm_stats.num_realloc++;
+                unlock_global();
 #endif /* WITH_ALLOCATOR_STATS */
 
-                return_ptr = (void *)((char *)new_block +
-                        sizeof(raw_block_header_t));
+                return_ptr = (void *)
+                    ((uintptr_t) new_block + sizeof(raw_block_header_t));
                 goto done;
             }
         }