Bläddra i källkod

Proper support of splitting for both fixed and variable min splitting block size.

Ioannis Koutras 13 år sedan
förälder
incheckning
7861af6e17
10 ändrade filer med 98 tillägg och 51 borttagningar
  1. 10 0
      DefineOptions.cmake
  2. 7 1
      dmm_config.h.in
  3. 5 3
      examples/test.c
  4. 3 1
      include/dmmlib/heap.h
  5. 2 1
      private-include/split.h
  6. 7 1
      src/CMakeLists.txt
  7. 23 3
      src/custom_malloc.c
  8. 1 1
      src/dmm_adaptor.c
  9. 4 0
      src/initialize_allocator.c
  10. 36 40
      src/split.c

+ 10 - 0
DefineOptions.cmake

@@ -9,6 +9,7 @@ option(WITH_DOC "Build with documentation" OFF)
 set(NUM_HEAPS '0')
 
 set(WITH_COALESCING "never" "Build with coalescing support")
+set(WITH_SPLITTING "never" "Build with splitting support")
 
 option(P2012 "Build for P2012 runtime" OFF)
 option(LINUXTEST "Build a case for Linux" ON) 
@@ -26,6 +27,8 @@ if (LINUXTEST)
   set(WITH_EXAMPLES ON)
   set(WITH_COALESCING "variable")
   set(MAX_COALESCE_SIZE 60000)
+  set(WITH_SPLITTING "variable")
+  set(MIN_SPLITTING_SIZE 300)
   set(WITH_SHARED_LIB ON)
   set(WITH_DOC ON)
 endif (LINUXTEST)
@@ -37,3 +40,10 @@ elseif(WITH_COALESCING STREQUAL "variable")
   set(COALESCING_VARIABLE ON)
 endif(WITH_COALESCING STREQUAL "fixed")
 
+if(WITH_SPLITTING STREQUAL "fixed")
+	set(SPLITTING_FIXED ON)
+elseif(WITH_SPLITTING STREQUAL "variable")
+  set(WITH_KNOBS ON)
+  set(SPLITTING_VARIABLE ON)
+endif(WITH_SPLITTING STREQUAL "fixed")
+

+ 7 - 1
dmm_config.h.in

@@ -12,9 +12,15 @@
 #cmakedefine COALESCING_FIXED
 #cmakedefine COALESCING_VARIABLE
 
+#cmakedefine MAX_COALESCE_SIZE @MAX_COALESCE_SIZE@
+
+#cmakedefine SPLITTING_FIXED
+#cmakedefine SPLITTING_VARIABLE
+
+#cmakedefine MIN_SPLITTING_SIZE @MIN_SPLITTING_SIZE@
+
 #cmakedefine WITH_KNOBS
 
-#cmakedefine MAX_COALESCE_SIZE @MAX_COALESCE_SIZE@
 
 #define MIN_FRAG_THRESHOLD 0.05
 

+ 5 - 3
examples/test.c

@@ -4,10 +4,12 @@
 int main(void) {
     void *p1, *p2, *p3;
 
-    p1 = custom_malloc((size_t) 1001);
+    p1 = custom_malloc((size_t) 1024);
     custom_free(p1);
-    p2 = custom_malloc((size_t) 1900);
+    p2 = custom_malloc((size_t) 512);
+    p3 = custom_malloc((size_t) 394);
     custom_free(p2);
-    p3 = custom_malloc((size_t) 3018);
     custom_free(p3);
+
+    return 0;
 }

+ 3 - 1
include/dmmlib/heap.h

@@ -57,7 +57,9 @@ typedef struct dmmknobs_s {
 	size_t max_coalesce_size; /**< Maximum coalesce size; -1 if coalescing
 				     is not supported */
 #endif /* COALESCING_VARIABLE */
-	uint32_t min_split_size; /**< Minimum split size. */
+#ifdef SPLITTING_VARIABLE
+	size_t min_split_size; /**< Minimum split size. */
+#endif /* SPLITTING_VARIABLE */
 	/* FIXME Need to find explanation */
 	float empty_threshold; /**< Empty Threshold */
 	uint32_t percentage; /**< Percentage value */

+ 2 - 1
private-include/split.h

@@ -1,3 +1,4 @@
 #include <dmmlib/heap.h>
 
-void split(allocator_t *allocator, heap_t *heap, void *ptr);
+void split(allocator_t *allocator, heap_t *heap, void *ptr,
+		size_t new_block_size);

+ 7 - 1
src/CMakeLists.txt

@@ -35,7 +35,6 @@ set(dmmlib_SRCS
   other.c
   initialize_allocator.c
   sys_alloc.c
-  split.c
   dmm_adaptor.c
 )
 
@@ -54,6 +53,13 @@ if (COALESCING_FIXED OR COALESCING_VARIABLE)
   )
 endif (COALESCING_FIXED OR COALESCING_VARIABLE)
 
+if (SPLITTING_FIXED OR SPLITTING_VARIABLE)
+  set(dmmlib_SRCS
+    ${dmmlib_SRCS}
+    split.c
+  )
+endif (SPLITTING_FIXED OR SPLITTING_VARIABLE)
+
 include_directories(
   ${DMMLIB_PUBLIC_INCLUDE_DIRS}
   ${DMMLIB_PRIVATE_INCLUDE_DIRS}

+ 23 - 3
src/custom_malloc.c

@@ -3,6 +3,9 @@
 #ifdef HAVE_LOCKS
 #include "posix_lock.h"
 #endif /* HAVE_LOCKS */
+#if defined (SPLITTING_FIXED) || defined (SPLITTING_VARIABLE)
+#include "split.h"
+#endif /* SPLITTING_FIXED || SPLITTING_VARIABLE */
 #include <dmmlib/initialize_allocator.h>
 #include "other.h"
 #include "sys_alloc.h"
@@ -14,6 +17,10 @@ void * custom_ahmalloc(allocator_t* allocator, heap_t* heap, size_t size) {
     int heap_id, fixed_list_id, i;
     maptable_node_t *current_maptable_node;
     void *current_block, *previous_block;
+#if defined (SPLITTING_FIXED) || defined (SPLITTING_VARIABLE)
+    size_t new_size;
+    size_t min_split_size;
+#endif /* (SPLITTING_FIXED) || (SPLITTING_VARIABLE) */
 
 #ifndef WITH_MEMORY_SPACE_AWARENESS
 
@@ -82,6 +89,21 @@ void * custom_ahmalloc(allocator_t* allocator, heap_t* heap, size_t size) {
         mark_used(ptr);
 
         /* FIXME split to be put here */
+#if defined (SPLITTING_FIXED) || defined (SPLITTING_VARIABLE)
+        new_size = get_size(ptr) - get_requested_size(ptr) - HEADER_SIZE;
+
+#ifdef SPLITTING_FIXED
+        min_split_size = MIN_SPLITTING_SIZE;
+#endif /* SPLITTING_FIXED */
+#ifdef SPLITTING_VARIABLE
+        min_split_size = heap->dmm_knobs.min_split_size;
+#endif /* SPLITTING_VARIABLE */
+
+        if(new_size > min_split_size) {
+            split(allocator, heap, ptr, new_size);
+        }
+
+#endif /* (SPLITTING_FIXED) || (SPLITTING_VARIABLE) */
 
         /* Update the used blocks list */
         set_next(ptr, heap->used_blocks_head);
@@ -95,9 +117,7 @@ void * custom_ahmalloc(allocator_t* allocator, heap_t* heap, size_t size) {
         /* End of Stats */
         /* FIXME To be refactored - END */
 
-    }
-
-    if(ptr == NULL) {
+    } else {
         ptr = sys_alloc(allocator, heap, size);
     }
 

+ 1 - 1
src/dmm_adaptor.c

@@ -4,7 +4,7 @@ void update_frag_params(heap_t *heap) {
     switch(heap->dmm_knobs.frag_state) {
         default :
             heap->dmm_knobs.percentage = 0;
-            heap->dmm_knobs.max_coalesce_size = -1;
+            heap->dmm_knobs.max_coalesce_size = (size_t) -1;
             heap->dmm_knobs.min_split_size = 0;
             heap->dmm_knobs.empty_threshold = 1.5;
             break;

+ 4 - 0
src/initialize_allocator.c

@@ -40,6 +40,10 @@ void initialize_allocator(allocator_t *allocator) {
         allocator->heaps[i].dmm_knobs.max_coalesce_size = MAX_COALESCE_SIZE;
 #endif /* COALESCING_VARIABLE */
 
+#ifdef SPLITTING_VARIABLE
+        allocator->heaps[i].dmm_knobs.min_split_size = MIN_SPLITTING_SIZE;
+#endif /* SPLITTING_VARIABLE */
+
         /* FIXME Create a constant for the initial value of the next
          * variables
          */

+ 36 - 40
src/split.c

@@ -2,52 +2,48 @@
 #include "other.h"
 #include "split.h"
 
-void split(allocator_t *allocator, heap_t *heap, void *ptr) {
+void split(allocator_t *allocator, heap_t *heap, void *ptr,
+        size_t new_block_size) {
     void *new_block;
-    size_t new_size;
     int fixed_list_id, i;
     maptable_node_t *current_maptable_node;
-    
-    new_size = get_size(ptr) - get_requested_size(ptr) - HEADER_SIZE;
-
-    /* FIXME This check should be done one level above */
-    if(new_size > 0) {
-        new_block = (void *) ((char *) ptr + get_requested_size(ptr) + 
-                HEADER_SIZE);
-
-        set_size(ptr, get_requested_size(ptr));
-        /* set_size() resets the availability of the block */
-        mark_used(ptr);
-
-        set_size(new_block, new_size);
-        set_previous_size_availability(new_block, get_size_availability(ptr));
-
-        /* FIXME code from custom_free, some refactoring maybe?
-         * Be careful, custom_free also does coalescing, we don't need that
-         */
-
-        /* Check if the block could be put in a fixed list */
-        fixed_list_id = map_size_to_list(heap, new_size);
-
-        if(fixed_list_id != -1) {
-            current_maptable_node = heap->maptable_head;		
-            if(fixed_list_id != 0) {
-                for(i = 1; i < fixed_list_id; i++) {
-                    current_maptable_node = current_maptable_node->next;
-                }
+
+    new_block = (void *) ((char *) ptr + get_requested_size(ptr) + 
+            HEADER_SIZE);
+
+    /* Resize the previous, used block */
+    set_size(ptr, get_requested_size(ptr));
+    /* set_size() resets the availability of the block */
+    mark_used(ptr);
+
+    set_size(new_block, new_block_size);
+    set_previous_size_availability(new_block, get_size_availability(ptr));
+
+    /* FIXME code from custom_free, some refactoring maybe?
+     * Be careful, custom_free also does coalescing, we don't need that
+     */
+
+    /* Check if the block could be put in a fixed list */
+    fixed_list_id = map_size_to_list(heap, new_block_size);
+
+    if(fixed_list_id != -1) {
+        current_maptable_node = heap->maptable_head;		
+        if(fixed_list_id != 0) {
+            for(i = 1; i < fixed_list_id; i++) {
+                current_maptable_node = current_maptable_node->next;
             }
-            set_next(new_block, current_maptable_node->fixed_list_head);
-            current_maptable_node->fixed_list_head = new_block;
-        } else { /* put it in the free list */
-            set_next(new_block, heap->free_list_head);
-            heap->free_list_head = new_block;
         }
-        
-        mark_free(ptr);
+        set_next(new_block, current_maptable_node->fixed_list_head);
+        current_maptable_node->fixed_list_head = new_block;
+    } else { /* put it in the free list */
+        set_next(new_block, heap->free_list_head);
+        heap->free_list_head = new_block;
+    }
 
-        if(allocator->border_ptr == ptr) {
-            allocator->border_ptr = new_block;
-        }
+    mark_free(ptr);
 
+    if(allocator->border_ptr == ptr) {
+        allocator->border_ptr = new_block;
     }
+
 }