Forráskód Böngészése

Proper support of coalescing for both fixed and variable max coalesced block size.

Ioannis Koutras 13 éve
szülő
commit
31bdfa0120
7 módosított fájl, 78 hozzáadás és 56 törlés
  1. 12 2
      DefineOptions.cmake
  2. 7 1
      dmm_config.h.in
  3. 2 2
      include/dmmlib/heap.h
  4. 3 2
      src/CMakeLists.txt
  5. 22 30
      src/coalesce.c
  6. 27 18
      src/custom_free.c
  7. 5 1
      src/initialize_allocator.c

+ 12 - 2
DefineOptions.cmake

@@ -1,13 +1,15 @@
 option(HAVE_LOCKS "Build with POSIX locking mechanisms" ON)
 option(WITH_EXAMPLES "Build with examples" OFF)
 option(WITH_MEMORY_SPACE_AWARENESS "Build with memory space awareness" OFF)
-option(WITH_COALESCING "Build with coalescing support" OFF)
+option(WITH_KNOBS "Build with knobs support" OFF)
 option(WITH_STATIC_LIB "Build a static library" OFF)
 option(WITH_SHARED_LIB "Build a shared library" OFF)
 option(WITH_DOC "Build with documentation" OFF)
 
 set(NUM_HEAPS '0')
 
+set(WITH_COALESCING "never" "Build with coalescing support")
+
 option(P2012 "Build for P2012 runtime" OFF)
 option(LINUXTEST "Build a case for Linux" ON) 
 
@@ -22,8 +24,16 @@ endif (P2012)
 if (LINUXTEST)
   set(HAVE_LOCKS OFF)
   set(WITH_EXAMPLES ON)
-  set(WITH_COALESCING ON)
+  set(WITH_COALESCING "variable")
+  set(MAX_COALESCE_SIZE 60000)
   set(WITH_SHARED_LIB ON)
   set(WITH_DOC ON)
 endif (LINUXTEST)
 
+if(WITH_COALESCING STREQUAL "fixed")
+  set(COALESCING_FIXED ON)
+elseif(WITH_COALESCING STREQUAL "variable")
+  set(WITH_KNOBS ON)
+  set(COALESCING_VARIABLE ON)
+endif(WITH_COALESCING STREQUAL "fixed")
+

+ 7 - 1
dmm_config.h.in

@@ -9,9 +9,15 @@
  */
 #cmakedefine NUM_HEAPS @NUM_HEAPS@
 
+#cmakedefine COALESCING_FIXED
+#cmakedefine COALESCING_VARIABLE
+
+#cmakedefine WITH_KNOBS
+
+#cmakedefine MAX_COALESCE_SIZE @MAX_COALESCE_SIZE@
+
 #define MIN_FRAG_THRESHOLD 0.05
 
-#cmakedefine WITH_COALESCING
 
 #endif /* DMM_CONFIG_H */
 

+ 2 - 2
include/dmmlib/heap.h

@@ -53,10 +53,10 @@ typedef struct dmmknobs_s {
 	float frag_threshold; /**< Fragmentation threshold to enable coalescing
 				or not. */ 
 	uint32_t mem_threshold; /**< Memory size threshold. */
-#ifdef COALESCING
+#ifdef COALESCING_VARIABLE
 	size_t max_coalesce_size; /**< Maximum coalesce size; -1 if coalescing
 				     is not supported */
-#endif /* COALESCING */
+#endif /* COALESCING_VARIABLE */
 	uint32_t min_split_size; /**< Minimum split size. */
 	/* FIXME Need to find explanation */
 	float empty_threshold; /**< Empty Threshold */

+ 3 - 2
src/CMakeLists.txt

@@ -36,6 +36,7 @@ set(dmmlib_SRCS
   initialize_allocator.c
   sys_alloc.c
   split.c
+  dmm_adaptor.c
 )
 
 if (HAVE_LOCKS)
@@ -46,12 +47,12 @@ if (HAVE_LOCKS)
   )
 endif (HAVE_LOCKS)
 
-if (WITH_COALESCING)
+if (COALESCING_FIXED OR COALESCING_VARIABLE)
   set(dmmlib_SRCS
     ${dmmlib_SRCS}
     coalesce.c
   )
-endif (WITH_COALESCING)
+endif (COALESCING_FIXED OR COALESCING_VARIABLE)
 
 include_directories(
   ${DMMLIB_PUBLIC_INCLUDE_DIRS}

+ 22 - 30
src/coalesce.c

@@ -8,41 +8,33 @@ void * coalesce(void *ptr, heap_t *heap, allocator_t *allocator) {
     int fixed_list_id, i;
     maptable_node_t *current_maptable_node;
 
-    // Try to coalesce with the previous memory block
-    // FIXME What happens if we have multiple heaps and we don't know the
-    // owner of the blocks?
-    if(is_previous_free(ptr)) {
-        prev = get_previous(ptr);
+    prev = get_previous(ptr);
 
-        // Check if it is a block of a fixed list
-        fixed_list_id = map_size_to_list(heap, get_size(prev));
-        if(fixed_list_id != -1) {
-            // If it is, find the fixed list and remove the block
-            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;
-                }
+    // Check if it is a block of a fixed list
+    fixed_list_id = map_size_to_list(heap, get_size(prev));
+    if(fixed_list_id != -1) {
+        // If it is, find the fixed list and remove the block
+        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;
             }
-            remove_block(ptr, current_maptable_node->fixed_list_head);
         }
+        remove_block(ptr, current_maptable_node->fixed_list_head);
+    }
 
-        // Set the new size
-        // Note: the rest of the header variables will be set on free().
-        set_size(prev, get_size(prev) + get_size(ptr) + HEADER_SIZE);
-
-        /* If the current block is the allocator's border pointer, update the
-         * latter to point to the previous block.
-         */
-        if(allocator->border_ptr == ptr)
-        {
-            allocator->border_ptr = prev;
-        }
+    // Set the new size
+    // Note: the rest of the header variables will be set on free().
+    set_size(prev, get_size(prev) + get_size(ptr) + HEADER_SIZE);
 
-        return prev;
-    } else {
-        mark_free(ptr);
-        return ptr;
+    /* If the current block is the allocator's border pointer, update the
+     * latter to point to the previous block.
+     */
+    if(allocator->border_ptr == ptr)
+    {
+        allocator->border_ptr = prev;
     }
+
+    return prev;
 }
 

+ 27 - 18
src/custom_free.c

@@ -4,9 +4,9 @@
 #ifdef HAVE_LOCKS
 #include "posix_lock.h"
 #endif /* HAVE_LOCKS */
-#ifdef WITH_COALESCING
+#if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
 #include "coalesce.h"
-#endif /* WITH_COALESCING */
+#endif /* COALESCING_FIXED || COALESCING_VARIABLE */
 #include "dmm_adaptor.h"
 #include "block_header.h"
 
@@ -14,10 +14,10 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
     size_t size;
     int heap_id, fixed_list_id, i;
     maptable_node_t *current_maptable_node;
-#ifdef WITH_COALESCING
-    void *coalesced_ptr;
+#if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
     bool coalesced;
-#endif /* WITH_COALESCING */
+    size_t max_coal_size;
+#endif /* COALESCING_FIXED || COALESCING_VARIABLE */
 
 #ifndef WITH_MEMORY_SPACE_AWARENESS
     /* Currently all the memory space aware allocators are pre-initialized */
@@ -39,15 +39,29 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 
     remove_block(ptr, heap->used_blocks_head);
 
-#ifdef WITH_COALESCING
-    coalesced_ptr = coalesce(ptr, heap, allocator); 
-    if(coalesced_ptr != ptr) {
-        ptr = coalesced_ptr;
-        coalesced = true;
+#if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
+    if(is_previous_free(ptr)) {
+
+#ifdef COALESCING_FIXED
+        max_coal_size = MAX_COALESCE_SIZE;
+#endif /* COALESCING_FIXED */
+#ifdef COALESCING_VARIABLE
+        max_coal_size = heap->dmm_knobs.max_coalesce_size;
+#endif /* COALESCING_VARIABLE */
+
+        if(get_previous_size(ptr) + get_size(ptr) + HEADER_SIZE <=
+                max_coal_size) {
+            ptr = coalesce(ptr, heap, allocator);
+            coalesced = true;
+        } else {
+            mark_free(ptr);
+            coalesced = false;
+        }
     } else {
+        mark_free(ptr);
         coalesced = false;
     }
-#endif /* WITH_COALESCING */
+#endif /* COALESCING_FIXED || COALESCING_VARIABLE */
 
     /* Check if the block could be put in a fixed list */
     fixed_list_id = map_size_to_list(heap, size);
@@ -62,7 +76,7 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
         set_next(ptr, current_maptable_node->fixed_list_head);
         current_maptable_node->fixed_list_head = ptr;
     } else { /* put it in the free list */
-#ifdef WITH_COALESCING
+#if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
         /* If the block is coalesced, there is no need to add it to the free
          * list as there is already an entry of the old block
          */
@@ -73,14 +87,9 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 #else
         set_next(ptr, heap->free_list_head);
         heap->free_list_head = ptr;
-#endif /* WITH_COALESCING */
+#endif /* COALESCING_FIXED || COALESCING_VARIABLE */
     }
 
-    /* A coalesced block is already free */
-#ifndef WITH_COALESCING
-    mark_free(ptr);
-#endif /* WITH_COALESCING */
-
     /* Begin of Stats */
 
     heap->dmm_stats.live_objects -= 1;

+ 5 - 1
src/initialize_allocator.c

@@ -35,7 +35,11 @@ void initialize_allocator(allocator_t *allocator) {
 
 #ifdef WITH_KNOBS
         /* Knobs initialization */
-        allocator->heaps[i].dmm_knobs.max_coalesce_size = -1;
+
+#ifdef COALESCING_VARIABLE
+        allocator->heaps[i].dmm_knobs.max_coalesce_size = MAX_COALESCE_SIZE;
+#endif /* COALESCING_VARIABLE */
+
         /* FIXME Create a constant for the initial value of the next
          * variables
          */