Browse Source

Good-fit initial implementation.

Ioannis Koutras 14 years ago
parent
commit
96947a5b50

+ 1 - 0
DefineOptions.cmake

@@ -64,6 +64,7 @@ if (LINUXTEST)
   set(WITH_STATIC_LIB ON)
   set(WITH_STATIC_LIB ON)
   set(WITH_REALLOC ON)
   set(WITH_REALLOC ON)
   set(REPLACE_MALLOC ON)
   set(REPLACE_MALLOC ON)
+  set(WITH_DOC ON)
 endif (LINUXTEST)
 endif (LINUXTEST)
 
 
 if(BLOCKS_ORGANIZATION STREQUAL "dll")
 if(BLOCKS_ORGANIZATION STREQUAL "dll")

+ 13 - 0
private-include/linked_lists/search_algorithms.h

@@ -43,6 +43,19 @@ void * search_on_fixed(heap_t * heap, size_t requested_size);
 #endif /* WITH_FIXED_LISTS */
 #endif /* WITH_FIXED_LISTS */
 
 
 void * best_fit_on_freelist(heap_t *heap, size_t requested_size);
 void * best_fit_on_freelist(heap_t *heap, size_t requested_size);
+
+/**
+ * Perform a good-fit search on the free list
+ *
+ * \param heap The heap whose free list should be accessed.
+ * \param requested_size The desired size of the block.
+ * \param fit_percentage The lowest acceptable percentage of the block space to be filled.
+ *
+ * \return The pointer to the data part of the matched memory block.
+ * \retval NULL No block was found.
+ */
+void * good_fit_on_freelist(heap_t *heap, size_t requested_size, float fit_percentage);
+
 void * exact_fit_on_freelist(heap_t *heap, size_t requested_size);
 void * exact_fit_on_freelist(heap_t *heap, size_t requested_size);
 void * first_fit_on_freelist(heap_t *heap, size_t requested_size);
 void * first_fit_on_freelist(heap_t *heap, size_t requested_size);
 
 

+ 54 - 0
src/linked_lists/search_algorithms.c

@@ -112,6 +112,60 @@ void * best_fit_on_freelist(heap_t *heap, size_t requested_size) {
     return best_block;
     return best_block;
 }
 }
 
 
+void * good_fit_on_freelist(heap_t *heap, size_t requested_size, float fit_percentage) {
+    void *current_block, *previous_block;
+    void *best_block, *best_previous_block;
+    size_t best_size, block_size;
+
+    current_block = NULL;
+    previous_block = NULL;
+    best_previous_block = NULL;
+    best_block = NULL;
+    best_size = (size_t) -1; /* SIZE_MAX */
+    block_size = 0;
+
+    for(current_block = heap->free_list_head; current_block != NULL;
+            current_block = get_next(current_block)) {
+        block_size = get_size(current_block);
+        if(block_size >= requested_size) {
+            if(block_size < best_size) {
+                best_block = current_block;
+                best_size = get_size(current_block);
+                best_previous_block = previous_block;
+		/* If the block size fits the relaxed requirements, then there
+		 * is no need to keep searching for a better sized block */
+                if(fit_percentage * best_size <= requested_size) {
+                    break;
+                }
+            }
+        }
+        previous_block = current_block;
+    } 
+
+    /* Remove the block from the list */
+    /* Note: remove_block() is not used because the block is already found */
+    if(best_block != NULL) {
+        if(best_block == heap->free_list_head) {
+            heap->free_list_head = get_next(best_block);
+#ifdef BLOCKS_IN_DLL
+            if(heap->free_list_head != NULL) {
+                set_previous(heap->free_list_head, NULL);
+            }
+#endif /* BLOCKS_IN_DLL */
+        } else {
+            set_next(best_previous_block, get_next(best_block));
+#ifdef BLOCKS_IN_DLL
+            if(get_next(best_block) != NULL) {
+                set_previous(get_next(best_block), best_previous_block);
+            }
+#endif /* BLOCKS_IN_DLL */
+        }
+    }
+
+    return best_block;
+}
+
+
 /**
 /**
  * \details In order to remove a block from a singly linked list, we need to
  * \details In order to remove a block from a singly linked list, we need to
  * keep track of the previous block as well: The previous block must point to
  * keep track of the previous block as well: The previous block must point to