ソースを参照

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

Ioannis Koutras 13 年 前
コミット
7861af6e17
共有10 個のファイルを変更した98 個の追加51 個の削除を含む
  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;
     }
+
 }