Bläddra i källkod

Proper knobs update during malloc() and free() calls.

Ioannis Koutras 13 år sedan
förälder
incheckning
c3b445d008
5 ändrade filer med 118 tillägg och 40 borttagningar
  1. 8 0
      custom_free.c
  2. 1 1
      custom_malloc.c
  3. 90 30
      dmm_adaptor.c
  4. 9 6
      include/dmmlib/heap.h
  5. 10 3
      private-include/dmm_adaptor.h

+ 8 - 0
custom_free.c

@@ -28,6 +28,7 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 
     remove_block(ptr, heap->used_blocks_head);
 
+    // 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) {
@@ -54,6 +55,13 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 
     // 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
+    if(heap->dmm_stats.num_free % 100) {
+        free_state_refresh(heap);
+    }
+
 #ifdef HAVE_LOCKS
     posix_unlock(heap);
 #endif /* HAVE_LOCKS */

+ 1 - 1
custom_malloc.c

@@ -92,7 +92,7 @@ void * custom_ahmalloc(allocator_t* allocator, heap_t* heap, size_t size) {
     // malloc's has been served already
     // TODO Define 50 as a constant
     if(heap->dmm_stats.num_malloc % 50) {
-        state_refresh(heap);
+        malloc_state_refresh(heap);
     }
 
 #ifdef HAVE_LOCKS

+ 90 - 30
dmm_adaptor.c

@@ -1,51 +1,111 @@
 #include "dmm_adaptor.h"
 
-void state_refresh(heap_t *heap) {
-    float fragmentation;
-    knob_state_t state;
-
-    fragmentation = (float) heap->dmm_stats.mem_allocated / 
-        (float)	heap->dmm_stats.mem_requested - 1.0;
-
-    // TODO Constant for the threshold, contraints for the memory threshold
-    if(fragmentation <= 0.05) {
-        state = 0;
-        set_fragmentation_params(heap, state);
-    }
-}
-
-void set_fragmentation_params(heap_t *heap, knob_state_t state) {
-    switch(state) {
+void update_frag_params(heap_t *heap) {
+    switch(heap->dmm_knobs.frag_state) {
         default :
+            heap->dmm_knobs.percentage = 0;
             heap->dmm_knobs.max_coalesce_size = -1;
             heap->dmm_knobs.min_split_size = 0;
             heap->dmm_knobs.empty_threshold = 1.5;
             break;
         case 1 :
-            heap->dmm_knobs.max_coalesce_size = 20;
-            heap->dmm_knobs.min_split_size = 400;
-            heap->dmm_knobs.empty_threshold = 1200;
+            heap->dmm_knobs.percentage = 20;
+            heap->dmm_knobs.max_coalesce_size = 400;
+            heap->dmm_knobs.min_split_size = 1200;
             break;
         case 2 :
-            heap->dmm_knobs.max_coalesce_size = 40;
+            heap->dmm_knobs.percentage = 40;
+            heap->dmm_knobs.max_coalesce_size = 800;
+            heap->dmm_knobs.min_split_size = 1000;
+            break;
+        case 3 :
+            heap->dmm_knobs.percentage = 60;
+            heap->dmm_knobs.max_coalesce_size = 1200;
             heap->dmm_knobs.min_split_size = 800;
-            heap->dmm_knobs.empty_threshold = 1000;
+            break;
+        case 4 :
+            heap->dmm_knobs.percentage = 80;
+            heap->dmm_knobs.max_coalesce_size = 1600;
+            heap->dmm_knobs.min_split_size = 600;
+            break;
+        case 5 :
+            heap->dmm_knobs.percentage = 100;
+            heap->dmm_knobs.max_coalesce_size = 2000;
+            heap->dmm_knobs.min_split_size = 300;
+            break;
+    }
+}
+
+void update_foot_params(heap_t *heap) {
+    switch(heap->dmm_knobs.foot_state) {
+        default :
+            heap->dmm_knobs.empty_threshold = 0.8;
+            break;
+        case 2 :
+            heap->dmm_knobs.empty_threshold = 0.6;
             break;
         case 3 :
-            heap->dmm_knobs.max_coalesce_size = 60;
-            heap->dmm_knobs.min_split_size = 1200;
-            heap->dmm_knobs.empty_threshold = 800;
+            heap->dmm_knobs.empty_threshold = 0.4;
             break;
         case 4 :
-            heap->dmm_knobs.max_coalesce_size = 80;
-            heap->dmm_knobs.min_split_size = 1600;
-            heap->dmm_knobs.empty_threshold = 600;
+            heap->dmm_knobs.empty_threshold = 0.2;
             break;
         case 5 :
-            heap->dmm_knobs.max_coalesce_size = 100;
-            heap->dmm_knobs.min_split_size = 2000;
-            heap->dmm_knobs.empty_threshold = 300;
+            heap->dmm_knobs.empty_threshold = 0.0;
             break;
     }
 }
 
+float get_current_fragmentation(heap_t *heap) {
+    float fragmentation;
+
+    fragmentation = (float) heap->dmm_stats.mem_allocated / 
+        (float)	heap->dmm_stats.mem_requested - 1.0;
+
+    if(fragmentation <= MIN_FRAG_THRESHOLD &&
+            heap->dmm_stats.mem_reserved < heap->dmm_knobs.mem_threshold) {
+        heap->dmm_knobs.frag_state = 0;
+        heap->dmm_knobs.foot_state = 0;
+        update_frag_params(heap);
+    }
+
+    return fragmentation;
+}
+
+void check_footprint(heap_t *heap) {
+    if(heap->dmm_stats.mem_allocated > heap->dmm_knobs.mem_threshold) {
+        if(heap->dmm_knobs.frag_state > heap->dmm_knobs.foot_state) {
+            heap->dmm_knobs.foot_state = heap->dmm_knobs.frag_state;
+        } else {
+            heap->dmm_knobs.foot_state++;
+        }
+        update_foot_params(heap);
+    }
+}
+
+void malloc_state_refresh(heap_t *heap) {
+    float fragmentation;
+
+    fragmentation = get_current_fragmentation(heap); 
+
+    /* Check fragmentation */
+    if(fragmentation >= heap->dmm_knobs.frag_threshold &&
+            heap->dmm_stats.mem_requested != 0) {
+        if(heap->dmm_knobs.foot_state > heap->dmm_knobs.frag_state) {
+            heap->dmm_knobs.frag_state = heap->dmm_knobs.foot_state;
+        } else {
+            heap->dmm_knobs.frag_state++;
+        }
+        update_frag_params(heap);
+    }
+
+    check_footprint(heap);
+}
+
+void free_state_refresh(heap_t *heap) {
+    float fragmentation;
+
+    fragmentation = get_current_fragmentation(heap);
+
+    check_footprint(heap);
+}

+ 9 - 6
include/dmmlib/heap.h

@@ -23,6 +23,10 @@
  */
 #define NUM_HEAPS 4
 
+#define MIN_FRAG_THRESHOLD 0.05
+
+typedef uint8_t knob_state_t;
+
 /**
  * \brief A structure to represent a maptable node.
  */
@@ -60,18 +64,17 @@ typedef struct dmmstats_s {
  * \brief A structure to represent tunable parameters of a heap
  */
 typedef struct dmmknobs_s {
-	/** \brief Maximum coalesce size; -1 If coalescing is not supported */
-	int32_t max_coalesce_size;
 	float frag_threshold; /**< \brief Fragmentation threshold to enable
 				coalescing or not. */ 
 	uint32_t mem_threshold; /**< \brief Memory size threshold. */
+	/** \brief Maximum coalesce size; -1 If coalescing is not supported */
+	int32_t max_coalesce_size;
 	uint32_t min_split_size; /**< \brief Minimum split size. */
 	float empty_threshold; /**< FIXME Need to find explanation \brief Empty
 				 Threshold */
-	/*
-	uint32_t percentage; // FIXME to be investigated if needed
-	char frag_state; //FIXME It was in the old code to refresh the frag check
-	*/
+	uint32_t percentage; // FIXME to be investigated what it is
+	knob_state_t frag_state;
+	knob_state_t foot_state;	
 } dmmknobs_t;
 
 /**

+ 10 - 3
private-include/dmm_adaptor.h

@@ -1,7 +1,14 @@
+#ifndef DMM_ADAPTOR_H
+#define DMM_ADAPTOR_H
+
 #include <dmmlib/heap.h>
 
-typedef uint8_t knob_state_t;
+void set_frag_params(heap_t *heap);
+void set_foot_params(heap_t *heap);
 
-void state_refresh(heap_t *heap);
-void set_fragmentation_params(heap_t *heap, knob_state_t state);
+float get_current_fragmentation(heap_t *heap);
+void check_footprint(heap_t *heap);
+void malloc_state_refresh(heap_t *heap);
+void free_state_refresh(heap_t *heap);
 
+#endif /* DMM_ADAPTOR_H */