소스 검색

Added exact-, first- and best-Fit search algorithms for singly linked freelist.

Ioannis Koutras 13 년 전
부모
커밋
3c1f4804f1

+ 9 - 0
private-include/sll/best_fit_on_freelist.h

@@ -0,0 +1,9 @@
+#ifndef BEST_FIT_ON_FREELIST_H
+#define BEST_FIT_ON_FREELIST_H
+
+#include <dmmlib/heap.h>
+
+void * best_fit_on_freelist(heap_t *heap, size_t requested_size);
+
+#endif /* BEST_FIT_ON_FREELIST_H */
+

+ 9 - 0
private-include/sll/exact_fit_on_freelist.h

@@ -0,0 +1,9 @@
+#ifndef EXACT_FIT_ON_FREELIST_H
+#define EXACT_FIT_ON_FREELIST_H
+
+#include <dmmlib/heap.h>
+
+void * exact_fit_on_freelist(heap_t *heap, size_t requested_size);
+
+#endif /* EXACT_FIT_ON_FREELIST_H */
+

+ 9 - 0
private-include/sll/first_fit_on_freelist.h

@@ -0,0 +1,9 @@
+#ifndef FIRST_FIT_ON_FREELIST_H
+#define FIRST_FIT_ON_FREELIST_H
+
+#include <dmmlib/heap.h>
+
+void * first_fit_on_freelist(heap_t *heap, size_t requested_size);
+
+#endif /* FIRST_FIT_ON_FREELIST_H */
+

+ 1 - 0
src/CMakeLists.txt

@@ -31,6 +31,7 @@ endif (WITH_STATIC_LIB)
 set(dmmlib_SRCS
   block_header.c
   sll/search_on_fixed.c
+  sll/best_fit_on_freelist.c
   custom_free.c
   custom_malloc.c
   other.c

+ 2 - 17
src/custom_malloc.c

@@ -9,6 +9,7 @@
 #include <dmmlib/initialize_allocator.h>
 #include "other.h"
 #include "sll/search_on_fixed.h"
+#include "sll/best_fit_on_freelist.h"
 #include "sys_alloc.h"
 #include "block_header.h"
 #include "dmm_adaptor.h"
@@ -16,7 +17,6 @@
 void * custom_ahmalloc(allocator_t* allocator, heap_t* heap, size_t size) {
     void *ptr;
     int heap_id;
-    void *current_block, *previous_block;
 #if defined (SPLITTING_FIXED) || defined (SPLITTING_VARIABLE)
     size_t new_size;
     size_t min_split_size;
@@ -40,7 +40,6 @@ void * custom_ahmalloc(allocator_t* allocator, heap_t* heap, size_t size) {
 #endif /* WITH_MEMORY_SPACE_AWARENESS */
 
     ptr = NULL;
-    previous_block = NULL;
 
 #ifdef HAVE_LOCKS
     posix_lock(heap);
@@ -49,21 +48,7 @@ void * custom_ahmalloc(allocator_t* allocator, heap_t* heap, size_t size) {
     ptr = search_on_fixed(heap, req_padding(size));
 
     if(ptr == NULL) {
-
-        /* first fit from free list */
-        for(current_block = heap->free_list_head; current_block != NULL;
-                current_block = get_next(current_block)) {
-            if(get_size(current_block) >= size) {
-                if(current_block == heap->free_list_head) {
-                    heap->free_list_head = get_next(current_block);
-                } else {
-                    set_next(previous_block, get_next(current_block));
-                }
-                ptr = current_block;
-                break;
-            }
-            previous_block = current_block;
-        }
+       ptr = best_fit_on_freelist(heap, size);
     }
 
     if(ptr != NULL) {

+ 49 - 0
src/sll/best_fit_on_freelist.c

@@ -0,0 +1,49 @@
+#include "sll/best_fit_on_freelist.h"
+#include "block_header.h"
+
+/**
+ * \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
+ * the current block's next block once the current one is removed.
+ * Normally the best fit search alogrithm would have to traverse the whole list
+ * in order to find the best block. However, a check is being performed each
+ * time a new best candidate is found, so that we stop once a perfect block is
+ * found.
+ */
+void * best_fit_on_freelist(heap_t *heap, size_t requested_size) {
+    void *current_block, *previous_block, *ptr;
+    void *best_block, *best_previous_block;
+    size_t best_size;
+
+    ptr = NULL;
+    best_block = NULL;
+    best_size = (size_t) -1; /* SIZE_MAX */
+
+    for(current_block = heap->free_list_head; current_block != NULL;
+            current_block = get_next(current_block)) {
+        if(get_size(current_block) >= requested_size) {
+            if(get_size(current_block) < best_size) {
+                best_block = current_block;
+                best_size = get_size(current_block);
+                best_previous_block = previous_block;
+                if(best_size == requested_size) {
+                    break;
+                }
+            }
+        }
+        previous_block = current_block;
+    } 
+
+    /* Remove the block from the list */
+    if(best_block != NULL) {
+        if(best_block == heap->free_list_head) {
+            heap->free_list_head = get_next(best_block);
+        } else {
+            set_next(best_previous_block, get_next(best_block));
+        }
+        ptr = best_block;
+    }
+
+    return ptr;
+}
+

+ 30 - 0
src/sll/exact_fit_on_freelist.c

@@ -0,0 +1,30 @@
+#include "sll/exact_fit_on_freelist.h"
+#include "block_header.h"
+
+/**
+ * \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
+ * the current block's next block once the current one is removed.
+ */
+void * exact_fit_on_freelist(heap_t *heap, size_t requested_size) {
+    void *current_block, *previous_block, *ptr;
+
+    ptr = NULL;
+
+    for(current_block = heap->free_list_head; current_block != NULL;
+            current_block = get_next(current_block)) {
+        if(get_size(current_block) == requested_size) {
+            if(current_block == heap->free_list_head) {
+                heap->free_list_head = get_next(current_block);
+            } else {
+                set_next(previous_block, get_next(current_block));
+            }
+            ptr = current_block;
+            break;
+        }
+        previous_block = current_block;
+    } 
+
+    return ptr;
+}
+

+ 30 - 0
src/sll/first_fit_on_freelist.c

@@ -0,0 +1,30 @@
+#include "sll/first_fit_on_freelist.h"
+#include "block_header.h"
+
+/**
+ * \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
+ * the current block's next block once the current one is removed.
+ */
+void * first_fit_on_freelist(heap_t *heap, size_t requested_size) {
+    void *current_block, *previous_block, *ptr;
+
+    ptr = NULL;
+
+    for(current_block = heap->free_list_head; current_block != NULL;
+            current_block = get_next(current_block)) {
+        if(get_size(current_block) >= requested_size) {
+            if(current_block == heap->free_list_head) {
+                heap->free_list_head = get_next(current_block);
+            } else {
+                set_next(previous_block, get_next(current_block));
+            }
+            ptr = current_block;
+            break;
+        }
+        previous_block = current_block;
+    } 
+
+    return ptr;
+}
+