Procházet zdrojové kódy

Proper coalescing support.

Ioannis Koutras před 13 roky
rodič
revize
1430f129bc
3 změnil soubory, kde provedl 58 přidání a 24 odebrání
  1. 1 1
      private-include/coalesce.h
  2. 18 8
      src/coalesce.c
  3. 39 15
      src/custom_free.c

+ 1 - 1
private-include/coalesce.h

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

+ 18 - 8
src/coalesce.c

@@ -1,8 +1,9 @@
+#include <stdio.h>
 #include "coalesce.h"
 #include "block_header.h"
 #include "other.h"
 
-void * coalesce(void *ptr, heap_t *heap) {
+void * coalesce(void *ptr, heap_t *heap, allocator_t *allocator) {
     void *prev;
     int fixed_list_id, i;
     maptable_node_t *current_maptable_node;
@@ -10,13 +11,14 @@ void * coalesce(void *ptr, heap_t *heap) {
     // If there is a negative value on max_coalesce_size, then don't do
     // anything.
     // FIXME To be moved in custom_free()
-    if(heap->dmm_knobs.max_coalesce_size < 0) {
-        return ptr;
-    }
+    //if(heap->dmm_knobs.max_coalesce_size < 0) {
+    //    return ptr;
+    //}
 
     // 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?
+    printf("previous %zu\n", get_previous_size(ptr));
     if(is_previous_free(ptr)) {
         prev = get_previous(ptr);
 
@@ -31,18 +33,26 @@ void * coalesce(void *ptr, heap_t *heap) {
                 }
             }
             remove_block(ptr, current_maptable_node->fixed_list_head);
-        } else {
-            // Or it is a block from the free list, so remove it
-            // from there
-            remove_block(ptr, heap->free_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;
+        }
+
+        printf("Coalesced!\n");
+
         return prev;
     } else {
+        printf("Not Coalesced!\n");
+        mark_free(ptr);
         return ptr;
     }
 }

+ 39 - 15
src/custom_free.c

@@ -7,15 +7,20 @@
 #ifdef WITH_COALESCING
 #include "coalesce.h"
 #endif /* WITH_COALESCING */
+#include "dmm_adaptor.h"
 #include "block_header.h"
 
 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;
+    bool coalesced;
+#endif /* WITH_COALESCING */
 
 #ifndef WITH_MEMORY_SPACE_AWARENESS
-    // Currently all the memory space aware allocators are pre-initialized
+    /* Currently all the memory space aware allocators are pre-initialized */
     if(allocator == NULL) {
         allocator = &systemallocator;
     }
@@ -35,39 +40,58 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
     remove_block(ptr, heap->used_blocks_head);
 
 #ifdef WITH_COALESCING
-    ptr = coalesce(ptr, heap); 
+    coalesced_ptr = coalesce(ptr, heap, allocator); 
+    if(coalesced_ptr != ptr) {
+        ptr = coalesced_ptr;
+        coalesced = true;
+    } else {
+        coalesced = false;
+    }
 #endif /* WITH_COALESCING */
 
-    // Check if the block could be put in a fixed list
+    /* Check if the block could be put in a fixed list */
     fixed_list_id = map_size_to_list(heap, size);
 
     if(fixed_list_id != -1) {
         current_maptable_node = heap->maptable_head;		
-        if(fixed_list_id == 0) {
-            set_next(ptr, current_maptable_node->fixed_list_head);
-            current_maptable_node->fixed_list_head = ptr;
-        } else {
+        if(fixed_list_id != 0) {
             for(i = 1; i < fixed_list_id; i++) {
                 current_maptable_node = current_maptable_node->next;
             }
-            set_next(ptr, current_maptable_node->fixed_list_head);
-            current_maptable_node->fixed_list_head = ptr;
         }
-    } else { // put it in the free list
+        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 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
+         */
+        if(!coalesced) {
+            set_next(ptr, heap->free_list_head);
+            heap->free_list_head = ptr;
+        }
+#else
         set_next(ptr, heap->free_list_head);
         heap->free_list_head = ptr;
+#endif /* WITH_COALESCING */
     }
 
-    // Begin of Stats
+    /* A coalesced block is already free */
+#ifndef WITH_COALESCING
+    mark_free(ptr);
+#endif /* WITH_COALESCING */
+
+    /* Begin of Stats */
 
     heap->dmm_stats.live_objects -= 1;
     heap->dmm_stats.num_free += 1;
 
-    // End of Stats
+    /* End of Stats */
 
-    // Refresh the state of the heap allocator if a certain number of
-    // free's has been served already
-    // TODO Define 100 as a constant
+    /* Refresh the state of the heap allocator if a certain number of
+     * free's has been served already
+     */
+    /* TODO Define 100 as a constant */
     if(heap->dmm_stats.num_free % 100) {
         free_state_refresh(heap);
     }