Przeglądaj źródła

Initial support for coalescing three blocks.

Ioannis Koutras 13 lat temu
rodzic
commit
d6e611f46c
3 zmienionych plików z 70 dodań i 19 usunięć
  1. 1 1
      private-include/coalesce.h
  2. 4 2
      src/coalesce.c
  3. 65 16
      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(void *ptr, heap_t *heap, allocator_t *allocator);
+void * coalesce(allocator_t *allocator, heap_t *heap, void *ptr, size_t size);
 
 #endif /* COALESCE_H */
 

+ 4 - 2
src/coalesce.c

@@ -20,9 +20,11 @@
 #include "other.h"
 #include "dmm_config.h"
 
-void * coalesce(void *ptr, heap_t *heap, allocator_t *allocator) {
+void * coalesce(allocator_t *allocator, heap_t *heap, void *ptr, size_t size) {
     void *prev;
+#ifdef WITH_FIXED_LISTS
     int fixed_list_id, i;
+#endif /* WITH_FIXED_LISTS */
     maptable_node_t *current_maptable_node;
 
     prev = get_dlprevious(ptr);
@@ -44,7 +46,7 @@ void * coalesce(void *ptr, heap_t *heap, allocator_t *allocator) {
 
     // Set the new size
     // Note: the rest of the header variables will be set on free().
-    set_size_and_free(allocator, prev, get_size(prev) + get_size(ptr) + HEADER_SIZE);
+    set_size_and_free(allocator, prev, size);
 
     /* If the current block is the allocator's border pointer, update the
      * latter to point to the previous block.

+ 65 - 16
src/custom_free.c

@@ -15,6 +15,7 @@
  *
  */
 
+#include <stdio.h>
 #include <dmmlib/dmmlib.h>
 #include "other.h"
 #ifdef HAVE_LOCKS
@@ -37,6 +38,10 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 #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 */
 
 #ifndef WITH_MEMORY_SPACE_AWARENESS
@@ -71,33 +76,77 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 
 #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
     coalesced = false;
-    if(is_previous_free(ptr)) {
-#ifdef WITH_OWNERSHIP
-        if(get_owner(ptr) == get_owner(get_dlprevious(ptr))) {
-#endif /* WITH_OWNERSHIP */
-
 #ifdef COALESCING_FIXED
-            max_coal_size = MAX_COALESCE_SIZE;
+    max_coal_size = MAX_COALESCE_SIZE;
 #endif /* COALESCING_FIXED */
 #ifdef COALESCING_VARIABLE
-            max_coal_size = heap->dmm_knobs.max_coalesce_size;
+    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(allocator, ptr);
+    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 {
-#endif /* COALESCING_FIXED || COALESCING_VARIABLE */
-        mark_free(allocator, ptr);
-#if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
+        previous_current_size = (size_t) -1; /* SIZE_MAX */
+    }
+
+    if(next_block != NULL && is_previous_free(ptr)) {
+#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);
+        // TODO Remove next_block from fixed / free list
+        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);
+                // TODO Remove next_block from fixed / free list
+            } else {
+                mark_free(allocator, ptr);
+            }
+        }
+    }
+#else
+    mark_free(allocator, ptr);
 #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
 
 #ifdef WITH_FIXED_LISTS