瀏覽代碼

Refactor coalesce()

Ioannis Koutras 13 年之前
父節點
當前提交
4c9e7a3cb3
共有 3 個文件被更改,包括 130 次插入108 次删除
  1. 1 1
      private-include/coalesce.h
  2. 128 26
      src/coalesce.c
  3. 1 81
      src/custom_free.c

+ 1 - 1
private-include/coalesce.h

@@ -26,7 +26,7 @@
  * @param ptr The memory block to be checked.
  * @param heap The heap of the memory block.
  */
-void * coalesce(allocator_t *allocator, heap_t *heap, void *ptr, size_t size);
+bool coalesce(allocator_t *allocator, heap_t *heap, void *ptr);
 
 #endif /* COALESCE_H */
 

+ 128 - 26
src/coalesce.c

@@ -20,46 +20,148 @@
 #include "other.h"
 #include "dmm_config.h"
 
-void * coalesce(allocator_t *allocator, heap_t *heap, void *ptr, size_t size) {
-    void *prev;
+bool coalesce(allocator_t *allocator, heap_t *heap, void *ptr) {
+    size_t max_coal_size;
+    size_t size;
+    size_t current_next_size;
+    size_t previous_current_size;
+    size_t three_blocks_size;
+    void *previous_block, *next_block;
 #ifdef WITH_FIXED_LISTS
     int fixed_list_id, i;
     maptable_node_t *current_maptable_node;
 #endif /* WITH_FIXED_LISTS */
 
-    prev = get_dlprevious(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 */
 
-#ifdef WITH_FIXED_LISTS
-    /* 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;
+    size = get_size(ptr);
+
+    previous_block = get_dlprevious(ptr);
+    next_block = get_dlnext(allocator, ptr);
+
+    /* Find out the sizes of all possible combinations */
+
+    /* Current + Next */
+    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 = size + get_size(next_block) + HEADER_SIZE;
+#ifdef WITH_OWNERSHIP
             }
+#endif /* WITH_OWNERSHIP */
+        } else {
+            current_next_size = (size_t) -1; /* SIZE_MAX */
         }
+    } else {
+        current_next_size = (size_t) -1; /* SIZE_MAX */
+    }
+
+    /* Previous + Current */
+    if(is_previous_free(ptr) == true) {
+#ifdef WITH_OWNERSHIP
+        if(get_owner(ptr) == get_owner(previous_block)) {
+#endif /* WITH_OWNERSHIP */
+            previous_current_size = size + get_previous_size(ptr) + HEADER_SIZE;
+#ifdef WITH_OWNERSHIP
+        }
+#endif /* WITH_OWNERSHIP */
+    } else {
+        previous_current_size = (size_t) -1; /* SIZE_MAX */
+    }
+
+    /* Previous + Current + Next */
+    if(next_block != NULL && is_previous_free(ptr) && is_free(next_block)) {
+#ifdef WITH_OWNERSHIP
+        if(get_owner(ptr) == get_owner(previous_block) &&
+            get_owner(ptr) == get_owner(next_block)) {
+#endif /* WITH_OWNERSHIP */
+                three_blocks_size = get_previous_size(ptr) + size +
+                    get_size(next_block) + 2 * HEADER_SIZE;
+#ifdef WITH_OWNERSHIP
+        }
+#endif /* WITH_OWNERSHIP */
+    } else {
+        three_blocks_size = (size_t) -1; /* SIZE_MAX */
+    }
+
+    /* Check if Previous + Current + Next is ok */
+    if(three_blocks_size <= max_coal_size) {
+        /* If previous block is on a fixed list, remove it */
+#ifdef WITH_FIXED_LISTS
+        /* Check if it is a block of a fixed list */
+        fixed_list_id = map_size_to_list(heap, get_size(previous_block));
+        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;
+                }
+            }
 #ifdef COUNT_HOPS
-        remove_block(heap, &ptr, &current_maptable_node->fixed_list_head);
+            remove_block(heap, &ptr, &current_maptable_node->fixed_list_head);
 #else
-        remove_block(&ptr, &current_maptable_node->fixed_list_head);
+            remove_block(&ptr, &current_maptable_node->fixed_list_head);
 #endif /* COUNT_HOPS */
-    }
+        }
 #endif /* WITH_FIXED_LISTS */
+        /* Reset the previous block size */
+        set_size_and_free(allocator, previous_block, three_blocks_size);
+        /* Remove the next block from any freelist */
+        remove_block_from_lists(&next_block, heap);
+        /* Update border pointer if the next block was the border pointer */
+        if(allocator->border_ptr == next_block) {
+            allocator->border_ptr = ptr;
+        }
+        return true;
+    }
 
-    // Set the new size
-    // Note: the rest of the header variables will be set on free().
-    set_size_and_free(allocator, prev, size);
+    if(previous_current_size <= max_coal_size) {
+        /* If previous block is on a fixed list, remove it */
+#ifdef WITH_FIXED_LISTS
+        /* Check if it is a block of a fixed list */
+        fixed_list_id = map_size_to_list(heap, get_size(previous_block));
+        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;
+                }
+            }
+#ifdef COUNT_HOPS
+            remove_block(heap, &ptr, &current_maptable_node->fixed_list_head);
+#else
+            remove_block(&ptr, &current_maptable_node->fixed_list_head);
+#endif /* COUNT_HOPS */
+        }
+#endif /* WITH_FIXED_LISTS */
+        /* Reset the previous block size */
+        set_size_and_free(allocator, ptr, previous_current_size);
+        /* Update border pointer if the current block was the border pointer */
+        if(allocator->border_ptr == next_block) {
+            allocator->border_ptr = ptr;
+        }
+        return true;
+    }
 
-    /* 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;
+    if(current_next_size <= max_coal_size) {
+        set_size_and_free(allocator, ptr, current_next_size);
+        remove_block_from_lists(&next_block, heap);
+        if(allocator->border_ptr == next_block) {
+            allocator->border_ptr = ptr;
+        }
+        return false;
     }
 
-    return prev;
+    /* If everything fails, just mark the block free */
+    mark_free(allocator, ptr);
+    return false;
 }
-

+ 1 - 81
src/custom_free.c

@@ -38,11 +38,6 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 #endif /* WITH_FIXED_LISTS */
 #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
     bool coalesced;
-    size_t max_coal_size;
-    void *next_block;
-    size_t current_next_size;
-    size_t previous_current_size;
-    size_t three_blocks_size;
 #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
 
     if(ptr == NULL) {
@@ -80,82 +75,7 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 #endif /* FUTURE_FEATURES */
 
 #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
-    coalesced = false;
-#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 = size + get_size(next_block) + HEADER_SIZE;
-#ifdef WITH_OWNERSHIP
-            }
-#endif /* WITH_OWNERSHIP */
-        } else {
-            current_next_size = (size_t) -1; /* SIZE_MAX */
-        }
-    } else {
-        current_next_size = (size_t) -1; /* SIZE_MAX */
-    }
-
-    if(is_previous_free(ptr) == true) {
-#ifdef WITH_OWNERSHIP
-        if(get_owner(ptr) == get_owner(get_dlprevious(ptr))) {
-#endif /* WITH_OWNERSHIP */
-            previous_current_size = size + get_previous_size(ptr) + HEADER_SIZE;
-#ifdef WITH_OWNERSHIP
-        }
-#endif /* WITH_OWNERSHIP */
-    } else {
-        previous_current_size = (size_t) -1; /* SIZE_MAX */
-    }
-
-    if(next_block != NULL && is_previous_free(ptr) && is_free(next_block)) {
-#ifdef WITH_OWNERSHIP
-        if(get_owner(ptr) == get_owner(get_dlprevious(ptr) &&
-            get_owner(ptr) == get_owner(next_block))) {
-#endif /* WITH_OWNERSHIP */
-                three_blocks_size = get_previous_size(ptr) + size +
-                    get_size(next_block) + 2 * HEADER_SIZE;
-#ifdef WITH_OWNERSHIP
-        }
-#endif /* WITH_OWNERSHIP */
-    } else {
-        three_blocks_size = (size_t) -1; /* SIZE_MAX */
-    }
-
-    if(three_blocks_size <= max_coal_size) {
-        ptr = coalesce(allocator, heap, ptr, three_blocks_size);
-        remove_block_from_lists(&next_block, heap);
-        if(allocator->border_ptr == next_block) {
-            allocator->border_ptr = ptr;
-        }
-        coalesced = true;
-        size = three_blocks_size;
-    } else {
-        if(previous_current_size <= max_coal_size) {
-            ptr = coalesce(allocator, heap, ptr, previous_current_size);
-            coalesced = true;
-            size = previous_current_size;
-        } else {
-            if(current_next_size <= max_coal_size) {
-                set_size_and_free(allocator, ptr, current_next_size);
-                remove_block_from_lists(&next_block, heap);
-                if(allocator->border_ptr == next_block) {
-                    allocator->border_ptr = ptr;
-                }
-            } else {
-                mark_free(allocator, ptr);
-            }
-        }
-    }
+    coalesced = coalesce(allocator, heap, ptr);
 #else
     mark_free(allocator, ptr);
 #endif /* COALESCING_FIXED || COALESCING_VARIABLE */