浏览代码

Support to coalesce after splitting

Ioannis Koutras 13 年之前
父节点
当前提交
50359f36df
共有 4 个文件被更改,包括 58 次插入2 次删除
  1. 3 0
      CMakeLists.txt
  2. 13 2
      DefineOptions.cmake
  3. 2 0
      dmm_config.h.in
  4. 40 0
      src/split.c

+ 3 - 0
CMakeLists.txt

@@ -88,6 +88,9 @@ if(MIN_SPLITTING_SIZE)
     message(STATUS "  with initial min. spliting size: "
       ${MIN_SPLITTING_SIZE} " bytes")
   endif(WITH_SPLITTING STREQUAL "fixed")
+  if(COALESCE_AFTER_SPLIT)
+    message(STATUS "Coalesce after split: " ${COALESCE_AFTER_SPLIT})
+  endif(COALESCE_AFTER_SPLIT)
 endif(MIN_SPLITTING_SIZE)
 message(STATUS "Adaptivity: " ${WITH_ADAPTIVITY})
 message(STATUS "Support for realloc(): " ${WITH_REALLOC})

+ 13 - 2
DefineOptions.cmake

@@ -11,6 +11,7 @@ option(WITH_ADAPTIVITY "Build with adaptivity" 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)
+option(COALESCE_AFTER_SPLIT "Try to coalesce blocks after split" OFF)
 
 option(WITH_SYSTEM_CALLS "Choose what system calls can be used, options are: none, sbrk, mmap" "none")
 option(SORT_POLICY "Choose the block sorting policy, options are: lifo, fifo, size, address")
@@ -76,10 +77,11 @@ if (LINUXTEST)
   set(FIT_PERCENTAGE 0.6f)
   set(HAVE_LOCKS ON)
   set(WITH_EXAMPLES ON)
-  set(WITH_COALESCING "never")
+  set(WITH_COALESCING "fixed")
   set(MAX_COALESCE_SIZE 60000)
-  set(WITH_SPLITTING "never")
+  set(WITH_SPLITTING "fixed")
   set(MIN_SPLITTING_SIZE 300)
+  set(COALESCE_AFTER_SPLIT ON)
   set(WITH_SHARED_LIB ON)
   set(WITH_STATIC_LIB ON)
   set(WITH_REALLOC ON)
@@ -87,6 +89,15 @@ if (LINUXTEST)
   set(WITH_DOC ON)
 endif (LINUXTEST)
 
+if(COALESCE_AFTER_SPLIT)
+  if(WITH_SPLITTING STREQUAL "never")
+         message(FATAL_ERROR "You have to set WITH_SPLITTING to fixed or variable if you want to coalesce after split.")
+  endif(WITH_SPLITTING STREQUAL "never")
+  if(WITH_COALESCING STREQUAL "never")
+    message(FATAL_ERROR "You have to set WITH_COALESCING to fixed or variable if you want to coalesce after split.")
+  endif(WITH_COALESCING STREQUAL "never")
+endif(COALESCE_AFTER_SPLIT)
+
 if(BLOCKS_ORGANIZATION STREQUAL "dll")
 	set(BLOCKS_IN_DLL ON)
 else(BLOCKS_ORGANIZATION STREQUAL "dll")

+ 2 - 0
dmm_config.h.in

@@ -47,6 +47,8 @@
 
 #cmakedefine MIN_SPLITTING_SIZE @MIN_SPLITTING_SIZE@
 
+#cmakedefine COALESCE_AFTER_SPLIT
+
 #cmakedefine REQUEST_SIZE_INFO
 
 #cmakedefine WITH_STATS

+ 40 - 0
src/split.c

@@ -24,6 +24,11 @@ void split(allocator_t *allocator, heap_t *heap, void *ptr,
         size_t req_size) {
     void *new_block;
     size_t new_block_size;
+#ifdef COALESCE_AFTER_SPLIT
+    size_t max_coal_size;
+    void *next_block;
+    size_t current_next_size;
+#endif /* COALESCE_AFTER_SPLIT */
 #ifdef WITH_FIXED_LISTS
     int fixed_list_id, i;
     maptable_node_t *current_maptable_node;
@@ -35,6 +40,41 @@ void split(allocator_t *allocator, heap_t *heap, void *ptr,
     /* Resize the previous, to be used block */
     set_size_and_used(allocator, ptr, req_size);
 
+#ifdef COALESCE_AFTER_SPLIT
+    /* Try to coalesce with the next block if it is free */
+#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 */
+
+    next_block = get_dlnext(allocator, ptr);
+    if(next_block != NULL) {
+        if(is_free(next_block) == true) {
+#ifdef WITH_OWNERSHIP
+            if(get_owner(next_block) == get_owner(ptr)) {
+#endif /* WITH_OWNERSHIP */
+                current_next_size = new_block_size + get_size(next_block) +
+                    HEADER_SIZE;
+                if(current_next_size <= max_coal_size) {
+                    /* it's ok to coalesce the new split block with the next
+                     * free block
+                     */
+                    remove_block_from_lists(&next_block, heap);
+                    if(allocator->border_ptr == next_block) {
+                        allocator->border_ptr = ptr;
+                    }
+                    new_block_size = current_next_size;
+                }
+#ifdef WITH_OWNERSHIP
+            }
+#endif /* WITH_OWNERSHIP */
+        }
+    }
+
+#endif /* COALESCE_AFTER_SPLIT */
+
     set_size_and_free(allocator, new_block, new_block_size);
     set_previous_size_availability(new_block, get_size_availability(ptr));