Browse Source

Initial support for doubly linked lists, unified linked lists source files.

Ioannis Koutras 13 years ago
parent
commit
969a004a64

+ 12 - 3
DefineOptions.cmake

@@ -6,11 +6,13 @@ option(WITH_STATIC_LIB "Build a static library" OFF)
 option(WITH_SHARED_LIB "Build a shared library" OFF)
 option(WITH_DOC "Build with documentation" OFF)
 
-set(NUM_HEAPS '1')
+set(NUM_HEAPS 1)
 
 set(WITH_COALESCING "never" "Build with coalescing support")
 set(WITH_SPLITTING "never" "Build with splitting support")
 
+set(BLOCKS_ORGANIZATION "sll" "Blocks organized in singly linked lists")
+
 option(WITH_OWNERSHIP "Build with ownership information in blocks" OFF)
 
 option(P2012 "Build for P2012 runtime" OFF)
@@ -20,12 +22,12 @@ if (P2012)
   set(HAVE_LOCKS OFF)
   set(WITH_MEMORY_SPACE_AWARENESS ON)
   set(WITH_STATIC_LIB ON)
-  set(NUM_HEAPS '0')
+  set(NUM_HEAPS 0)
   set(LINUXTEST OFF)
 endif (P2012)
 
 if (LINUXTEST)
-  set(HAVE_LOCKS OFF)
+  set(HAVE_LOCKS ON)
   set(WITH_EXAMPLES ON)
   set(WITH_COALESCING "variable")
   set(MAX_COALESCE_SIZE 60000)
@@ -33,8 +35,15 @@ if (LINUXTEST)
   set(MIN_SPLITTING_SIZE 300)
   set(WITH_SHARED_LIB ON)
   set(WITH_DOC ON)
+  set(BLOCKS_ORGANIZATION "dll")
 endif (LINUXTEST)
 
+if(BLOCKS_ORGANIZATION STREQUAL "dll")
+	set(BLOCKS_IN_DLL ON)
+else(BLOCKS_ORGANIZATION STREQUAL "dll")
+	set(BLOCKS_IN_SLL ON)
+endif(BLOCKS_ORGANIZATION STREQUAL "dll")
+
 if(WITH_COALESCING STREQUAL "fixed")
   set(WITH_OWNERSHIP ON)
   set(COALESCING_FIXED ON)

+ 4 - 3
dmm_config.h.in

@@ -4,9 +4,7 @@
 #cmakedefine HAVE_LOCKS
 #cmakedefine WITH_MEMORY_SPACE_AWARENESS
 
-/**
- * \brief The number of the heaps.
- */
+/** The number of the heaps. */
 #cmakedefine NUM_HEAPS @NUM_HEAPS@
 
 #cmakedefine COALESCING_FIXED
@@ -21,6 +19,9 @@
 
 #cmakedefine WITH_KNOBS
 
+#cmakedefine BLOCKS_IN_SLL
+#cmakedefine BLOCKS_IN_DLL
+
 #cmakedefine WITH_OWNERSHIP
 
 #define MIN_FRAG_THRESHOLD 0.05

+ 19 - 35
private-include/block_header.h

@@ -30,19 +30,23 @@
 #include <stdbool.h>
 #include <dmmlib/heap.h>
 
+/* TODO Add an ifndef guard in case we have other block organizations */
+#include "linked_lists/linked_lists.h"
+
 /** The header structure of every memory block inside a heap. */
 typedef struct block_header_s {
-	size_t size; /**< The LSB represents the availability of the block (1
-		       for used, 0 for free), the rest the size of the data
-		       part. */
-	size_t requested_size; /**< The requested size of the data part */
-	size_t previous_size; /**< The LSB represents the availability of the
-				previous block, the rest the size of the data
-				part of the previous block in the memory space */
-	void *next; /**< The next memory block in the list that the current
-		      block belongs to */
+    size_t size; /**< The LSB represents the availability of the block (1
+                   for used, 0 for free), the rest the size of the data
+                   part. */
+    size_t requested_size; /**< The requested size of the data part */
+    size_t previous_size; /**< The LSB represents the availability of the
+                            previous block, the rest the size of the data
+                            part of the previous block in the memory space */
+    /* TODO Add an ifndef guard in case we have other block organizations */
+    list_node_header_t pointers; /**< The necessary pointers for block
+                                   organization. */
 #ifdef WITH_OWNERSHIP
-	heap_t *heap_owner; /** < A pointer to the heap the current block belongs to */
+    heap_t *heap_owner; /** < A pointer to the heap the current block belongs to */
 #endif /* WITH_OWNERSHIP */
 } block_header_t;
 
@@ -52,14 +56,11 @@ typedef struct block_header_s {
 #define HEADER_SIZE sizeof(block_header_t)
 
 /**
- * Get the next memory block.
- *
- * \param ptr The pointer to the data part of the current memory block.
+ * \brief Get the address of the block header of a memory block.
  *
- * \return The pointer of the data part of the next (in list) memory block.
- * \retval NULL There is no next memory block in the list.
+ * \param ptr The data part of the memory block.
  */
-void * get_next(void *ptr);
+block_header_t * get_header(void *ptr);
 
 /**
  * Get the size of the memory block's data
@@ -130,15 +131,6 @@ void mark_free(void *ptr);
  */
 void set_previous_size_availability(void *ptr, size_t previous_size_availability);
 
-/**
- * Set the next memory block of a block
- *
- * \param block 	The pointer to the data part of the current memory
- * block.
- * \param next_block 	The pointer to the data part of the next memory block.
- */
-void set_next(void *block, void *next_block);
-
 #ifdef WITH_OWNERSHIP
 
 /**
@@ -180,18 +172,10 @@ size_t get_previous_size(void *ptr);
 size_t get_previous_size_availability(void *ptr);
 
 /**
- * Get the previous memory block (in the memory space)
+ * Get the previous memory block on data layout level
  *
  * \param ptr 	The pointer to the data part of the current memory block.
  */
-void * get_previous(void *ptr);
-
-/**
- * Removes a memory block from a singly linked list of memory blocks.
- *
- * \param *block The block to be removed.
- * \param *starting_node The starting memory block of the list.
- */
-void remove_block(void *block, void *starting_node);
+void * get_dlprevious(void *ptr);
 
 #endif /* BLOCK_HEADER_H */

+ 94 - 0
private-include/linked_lists/linked_lists.h

@@ -0,0 +1,94 @@
+/*
+ *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * \file 	linked_lists.h
+ * \author 	Ioannis Koutras (joko@microlab.ntua.gr)
+ * \date 	September, 2011
+ *  
+ * \brief Linked list node header structure and functions.
+ */
+
+#ifndef LINKED_LISTS_H
+#define LINKED_LISTS_H
+
+#include <stdint.h>
+#include "dmm_config.h"
+
+/** The type of the pointer to a list node */
+typedef uintptr_t list_node_ptr;
+
+/** The header structure of a linked list node */
+typedef struct list_node_header_s {
+    list_node_ptr next; /**< The pointer to the next node in the list */
+#ifdef BLOCKS_IN_DLL
+    list_node_ptr previous; /**< The pointer to the previous node in the list */
+#endif /* BLOCKS_IN_DLL */
+} list_node_header_t;
+
+/**
+ * Set the next memory block of a block in a linked list.
+ *
+ * \param block 	The pointer to the data part of the current memory
+ * block.
+ * \param next_block 	The pointer to the data part of the next memory block.
+ */
+void set_next(void *block, void *next_block);
+
+/**
+ * Get the next memory block in a linked list.
+ *
+ * \param ptr The pointer to the data part of the current memory block.
+ *
+ * \return The pointer of the data part of the next (in list) memory block.
+ * \retval NULL There is no next memory block in the list.
+ */
+void * get_next(void *ptr);
+
+#ifdef BLOCKS_IN_DLL
+
+/**
+ * Set the previous memory block of a block in a linked list.
+ *
+ * \param block             The pointer to the data part of the current memory
+ * block.
+ * \param previous_block    The pointer to the data part of the previous memory
+ * block.
+ */
+void set_previous(void *previous, void *previous_block);
+
+/**
+ * Get the previous memory block in a linked list.
+ *
+ * \param ptr The pointer to the data part of the current memory block.
+ *
+ * \return The pointer of the data part of the previous (in list) memory block.
+ * \retval NULL There is no previous memory block in the list.
+ */
+void * get_previous(void *ptr);
+
+#endif /* BLOCKS_IN_DLL */
+
+/**
+ * Removes a memory block from a linked list of memory blocks.
+ *
+ * \param *block The block to be removed.
+ * \param *starting_node The starting memory block of the list.
+ */
+void remove_block(void *block, void *starting_node);
+
+#endif /* LINKED_LISTS_H */

+ 9 - 5
private-include/sll/search_on_fixed.h

@@ -16,15 +16,15 @@
  */
 
 /**
- * \file 	search_on_fixed.h
+ * \file 	search_algorithms.h
  * \author 	Ioannis Koutras (joko@microlab.ntua.gr)
  * \date 	September, 2011
  *  
- * \brief Exact-fit search on fixed lists
+ * \brief Various search algorithms for linked list structures used on DMMLib.
  */
 
-#ifndef SEARCH_ON_FIXED_H
-#define SEARCH_ON_FIXED_H
+#ifndef LINKED_LISTS_SEARCH_ALGORITHMS_H
+#define LINKED_LISTS_SEARCH_ALGORITHMS_H
 
 #include <dmmlib/heap.h>
 
@@ -39,5 +39,9 @@
  */
 void * search_on_fixed(heap_t * heap, size_t requested_size);
 
-#endif /* SEARCH_ON_FIXED_H */
+void * best_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);
+
+#endif /* LINKED_LISTS_SEARCH_ALGORITHMS_H */
 

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

@@ -1,26 +0,0 @@
-/*
- *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-
-#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 */
-

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

@@ -1,26 +0,0 @@
-/*
- *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-
-#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 */
-

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

@@ -1,26 +0,0 @@
-/*
- *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-
-#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 */
-

+ 2 - 2
src/CMakeLists.txt

@@ -30,8 +30,8 @@ endif (WITH_STATIC_LIB)
 
 set(dmmlib_SRCS
   block_header.c
-  sll/search_on_fixed.c
-  sll/best_fit_on_freelist.c
+  linked_lists/linked_lists.c
+  linked_lists/search_algorithms.c
   custom_free.c
   custom_malloc.c
   other.c

+ 2 - 36
src/block_header.c

@@ -17,21 +17,10 @@
 
 #include "block_header.h"
 
-/**
- * \brief Get the address of the block header of a memory block.
- *
- * \param ptr The data part of the memory block.
- */
-static block_header_t * get_header(void *ptr);
-
-static block_header_t * get_header(void *ptr) {
+block_header_t * get_header(void *ptr) {
     return (block_header_t *) ((char *) ptr - HEADER_SIZE);
 }
 
-void * get_next(void *ptr) {
-    return get_header(ptr)->next;
-}
-
 size_t get_size(void *ptr) {
     return get_header(ptr)->size >> 1;
 }
@@ -60,10 +49,6 @@ void mark_free(void *ptr) {
     get_header(ptr)->size &= (~ 0x1);
 }
 
-void set_next(void *ptr, void *next_block) {
-    get_header(ptr)->next = next_block;
-}
-
 #ifdef WITH_OWNERSHIP
 
 void set_owner(void *ptr, heap_t *heap_owner) {
@@ -96,26 +81,7 @@ size_t get_previous_size_availability(void *ptr) {
     return get_header(ptr)->previous_size;
 }
 
-void * get_previous(void *ptr) {
+void * get_dlprevious(void *ptr) {
     return (void *) ((char *) ptr - HEADER_SIZE - get_previous_size(ptr));
 }
 
-void remove_block(void *block, void *starting_node) {
-
-    void *current_node, *previous_node;
-
-    /* Traverse a list starting from the starting node until block is found. */
-    for(current_node = starting_node; current_node != NULL; 
-            current_node = get_next(current_node)) {
-        if(current_node == block) {
-            if(current_node == starting_node) {
-                starting_node = get_next(block);
-            } else {
-                set_next(previous_node, get_next(block));
-            }
-            break;
-        }
-        previous_node = current_node;
-    }
-}
-

+ 1 - 1
src/coalesce.c

@@ -25,7 +25,7 @@ void * coalesce(void *ptr, heap_t *heap, allocator_t *allocator) {
     int fixed_list_id, i;
     maptable_node_t *current_maptable_node;
 
-    prev = get_previous(ptr);
+    prev = get_dlprevious(ptr);
 
     // Check if it is a block of a fixed list
     fixed_list_id = map_size_to_list(heap, get_size(prev));

+ 13 - 1
src/custom_free.c

@@ -58,7 +58,7 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
 
 #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
     if(is_previous_free(ptr)) {
-        if(get_owner(ptr) == get_owner(get_previous(ptr))) {
+        if(get_owner(ptr) == get_owner(get_dlprevious(ptr))) {
 
 #ifdef COALESCING_FIXED
             max_coal_size = MAX_COALESCE_SIZE;
@@ -92,6 +92,10 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
                 current_maptable_node = current_maptable_node->next;
             }
         }
+#ifdef BLOCKS_IN_DLL
+        set_previous(ptr, NULL);
+        set_previous(current_maptable_node->fixed_list_head, ptr);
+#endif /* BLOCKS_IN_DLL */
         set_next(ptr, current_maptable_node->fixed_list_head);
         current_maptable_node->fixed_list_head = ptr;
     } else { /* put it in the free list */
@@ -100,10 +104,18 @@ void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
          * list as there is already an entry of the old block
          */
         if(!coalesced) {
+#ifdef BLOCKS_IN_DLL
+            set_previous(heap->free_list_head, ptr);
+            set_previous(ptr, NULL);
+#endif /* BLOCKS_IN_DLL */
             set_next(ptr, heap->free_list_head);
             heap->free_list_head = ptr;
         }
 #else
+#ifdef BLOCKS_IN_DLL
+        set_previous(heap->free_list_head, ptr);
+        set_previous(ptr, NULL);
+#endif /* BLOCKS_IN_DLL */
         set_next(ptr, heap->free_list_head);
         heap->free_list_head = ptr;
 #endif /* COALESCING_FIXED || COALESCING_VARIABLE */

+ 5 - 2
src/custom_malloc.c

@@ -25,8 +25,7 @@
 #endif /* SPLITTING_FIXED || SPLITTING_VARIABLE */
 #include <dmmlib/initialize_allocator.h>
 #include "other.h"
-#include "sll/search_on_fixed.h"
-#include "sll/best_fit_on_freelist.h"
+#include "linked_lists/search_algorithms.h"
 #include "sys_alloc.h"
 #include "block_header.h"
 #include "dmm_adaptor.h"
@@ -92,6 +91,10 @@ void * custom_ahmalloc(allocator_t* allocator, heap_t* heap, size_t size) {
 #endif /* (SPLITTING_FIXED) || (SPLITTING_VARIABLE) */
 
         /* Update the used blocks list */
+#ifdef BLOCKS_IN_DLL
+        set_previous(heap->used_blocks_head, ptr);
+        set_previous(ptr, NULL);
+#endif /* BLOCKS_IN_DLL */
         set_next(ptr, heap->used_blocks_head);
         heap->used_blocks_head = ptr;
 

+ 12 - 3
src/initialize_allocator.c

@@ -15,18 +15,19 @@
  *
  */
 
+#include "dmm_config.h"
 #ifndef WITH_MEMORY_SPACE_AWARENESS
 #include <unistd.h>
 #endif /* WITH_MEMORY_SPACE_AWARENESS */
 #ifdef HAVE_LOCKS
-#include <pthread.h>
+#include "posix_lock.h"
 #endif /* HAVE_LOCKS */
 #include <dmmlib/initialize_allocator.h>
-#include "dmm_config.h"
 #include "sys_alloc.h"
 
 #ifdef WITH_MEMORY_SPACE_AWARENESS
-void initialize_allocator(allocator_t *allocator, void *starting_address, size_t size) {
+void initialize_allocator(allocator_t *allocator, void *starting_address, 
+        size_t size) {
 #else
 void initialize_allocator(allocator_t *allocator) {
 #endif /* WITH_MEMORY_SPACE_AWARENESS */
@@ -86,8 +87,16 @@ void initialize_allocator(allocator_t *allocator) {
      */
     current_heap = &allocator->heaps[0];
 
+#ifdef HAVE_LOCKS
+    sbrk_unlock();
+#endif /* HAVE_LOCKS */
+ 
     maptablenode = (maptable_node_t *) sys_alloc(allocator, &allocator->heaps[0], 12*(sizeof(maptable_node_t)));
 
+#ifdef HAVE_LOCKS
+    sbrk_lock();
+#endif /* HAVE_LOCKS */
+ 
     maptablenode->size = 32;
     maptablenode->fixed_list_head = NULL;
     maptablenode->next = maptablenode+1;

+ 66 - 0
src/linked_lists/linked_lists.c

@@ -0,0 +1,66 @@
+/*
+ *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "linked_lists/linked_lists.h"
+#include "block_header.h"
+
+void set_next(void *ptr, void *next_block) {
+    get_header(ptr)->pointers.next = (list_node_ptr) next_block;
+}
+
+void * get_next(void *ptr) {
+    return (void *) get_header(ptr)->pointers.next;
+}
+
+#ifdef BLOCKS_IN_DLL
+
+void set_previous(void *ptr, void *previous_block) {
+    if( ptr != NULL) {
+        get_header(ptr)->pointers.previous = (list_node_ptr) previous_block;
+    }
+}
+
+void * get_previous(void *ptr) {
+    return (void *) get_header(ptr)->pointers.previous;
+}
+
+#endif /* BLOCKS_IN_DLL */
+
+void remove_block(void *block, void *starting_node) {
+
+    void *current_node, *previous_node;
+
+    /* Traverse a list starting from the starting node until block is found. */
+    for(current_node = starting_node; current_node != NULL; 
+            current_node = get_next(current_node)) {
+        if(current_node == block) {
+            if(current_node == starting_node) {
+                starting_node = get_next(block);
+#ifdef BLOCKS_IN_DLL
+                set_previous(starting_node, NULL);
+#endif /* BLOCKS_IN_DLL */
+            } else {
+                set_next(previous_node, get_next(block));
+#ifdef BLOCKS_IN_DLL
+                set_previous(get_next(block), previous_node);
+#endif /* BLOCKS_IN_DLL */
+            }
+            break;
+        }
+        previous_node = current_node;
+    }
+}

+ 167 - 0
src/linked_lists/search_algorithms.c

@@ -0,0 +1,167 @@
+/*
+ *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "linked_lists/search_algorithms.h"
+#include "block_header.h"
+
+/**
+ * \details The maptable of the heap is being traversed sequentially while
+ * searching for a size equal of the requested size. If one is found, then we
+ * return the head of this list and set the next block as the new head.
+ */
+void * search_on_fixed(heap_t * heap, size_t requested_size) {
+    maptable_node_t *node;
+    void *ptr;
+
+    node = heap->maptable_head;
+    ptr = NULL;
+
+    while(node) {
+        if(node->size == requested_size) {
+            ptr = node->fixed_list_head;
+            if(ptr != NULL) {
+                node->fixed_list_head = get_next(ptr);
+#ifdef BLOCKS_IN_DLL
+                set_previous(node->fixed_list_head, NULL);
+#endif /* BLOCKS_IN_DLL */
+            }
+            break;
+        }
+        node = node->next;
+    }
+
+    return ptr;
+}
+
+/**
+ * \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);
+#ifdef BLOCKS_IN_DLL
+            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
+            set_previous(get_next(best_block), best_previous_block);
+#endif /* BLOCKS_IN_DLL */
+        }
+        ptr = best_block;
+    }
+
+    return ptr;
+}
+
+/**
+ * \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);
+#ifdef BLOCKS_IN_DLL
+                set_previous(heap->free_list_head, NULL);
+#endif /* BLOCKS_IN_DLL */
+            } else {
+                set_next(previous_block, get_next(current_block));
+#ifdef BLOCKS_IN_DLL
+                set_previous(get_next(current_block), previous_block);
+#endif /* BLOCKS_IN_DLL */
+            }
+            ptr = current_block;
+            break;
+        }
+        previous_block = current_block;
+    } 
+
+    return ptr;
+}
+
+/**
+ * \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);
+#ifdef BLOCKS_IN_DLL
+                set_previous(heap->free_list_head, NULL);
+#endif /* BLOCKS_IN_DLL */
+            } else {
+                set_next(previous_block, get_next(current_block));
+#ifdef BLOCKS_IN_DLL
+                set_previous(get_next(current_block), previous_block);
+#endif /* BLOCKS_IN_DLL */
+            }
+            ptr = current_block;
+            break;
+        }
+        previous_block = current_block;
+    } 
+
+    return ptr;
+}
+

+ 0 - 66
src/sll/best_fit_on_freelist.c

@@ -1,66 +0,0 @@
-/*
- *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-
-#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;
-}
-

+ 0 - 47
src/sll/exact_fit_on_freelist.c

@@ -1,47 +0,0 @@
-/*
- *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-
-#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;
-}
-

+ 0 - 30
src/sll/first_fit_on_freelist.c

@@ -1,30 +0,0 @@
-#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;
-}
-

+ 0 - 45
src/sll/search_on_fixed.c

@@ -1,45 +0,0 @@
-/*
- *   Copyright 2011 Institute of Communication and Computer Systems (ICCS) 
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-
-#include "sll/search_on_fixed.h"
-#include "block_header.h"
-
-/**
- * \details The maptable of the heap is being traversed sequentially while
- * searching for a size equal of the requested size. If one is found, then we
- * return the head of this list and set the next block as the new head.
- */
-void * search_on_fixed(heap_t * heap, size_t requested_size) {
-    maptable_node_t *node;
-    void *ptr;
-
-    node = heap->maptable_head;
-    ptr = NULL;
-
-    while(node) {
-        if(node->size == requested_size) {
-            ptr = node->fixed_list_head;
-            if(ptr != NULL) {
-                node->fixed_list_head = get_next(ptr);
-            }
-            break;
-        }
-        node = node->next;
-    }
-
-    return ptr;
-}

+ 6 - 0
src/split.c

@@ -50,9 +50,15 @@ void split(allocator_t *allocator, heap_t *heap, void *ptr,
                 current_maptable_node = current_maptable_node->next;
             }
         }
+#ifdef BLOCKS_IN_DLL
+        set_previous(new_block, NULL);
+#endif /* BLOCKS_IN_DLL */
         set_next(new_block, current_maptable_node->fixed_list_head);
         current_maptable_node->fixed_list_head = new_block;
     } else { /* put it in the free list */
+#ifdef BLOCKS_IN_DLL
+        set_previous(new_block, NULL);
+#endif /* BLOCKS_IN_DLL */
         set_next(new_block, heap->free_list_head);
         heap->free_list_head = new_block;
     }

+ 3 - 1
src/sys_alloc.c

@@ -86,6 +86,9 @@ void *sys_alloc(allocator_t *allocator, heap_t *heap, size_t size) {
     mark_used(ptr);
 
     // Update the used blocks list
+#ifdef BLOCKS_IN_DLL
+    set_previous(ptr, NULL);
+#endif /* BLOCKS_IN_DLL */
     set_next(ptr, heap->used_blocks_head);
     heap->used_blocks_head = ptr;
 
@@ -98,7 +101,6 @@ void *sys_alloc(allocator_t *allocator, heap_t *heap, size_t size) {
 
     /* FIXME To be refactored - END */
 
-
 #ifdef HAVE_LOCKS
     sbrk_unlock();
 #endif /* HAVE_LOCKS */