|
@@ -15,12 +15,13 @@
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
+#include <stdio.h>
|
|
|
#include "coalesce.h"
|
|
|
#include "block_header.h"
|
|
|
#include "other.h"
|
|
|
#include "dmm_config.h"
|
|
|
|
|
|
-bool coalesce(allocator_t *allocator, heap_t *heap, void *ptr) {
|
|
|
+bool coalesce(allocator_t **allocator, heap_t *heap, void **ptr) {
|
|
|
size_t max_coal_size;
|
|
|
size_t size;
|
|
|
size_t current_next_size;
|
|
@@ -39,10 +40,10 @@ bool coalesce(allocator_t *allocator, heap_t *heap, void *ptr) {
|
|
|
max_coal_size = heap->dmm_knobs.max_coalesce_size;
|
|
|
#endif /* COALESCING_VARIABLE */
|
|
|
|
|
|
- size = get_size(ptr);
|
|
|
+ size = get_size(*ptr);
|
|
|
|
|
|
- previous_block = get_dlprevious(ptr);
|
|
|
- next_block = get_dlnext(allocator, ptr);
|
|
|
+ previous_block = get_dlprevious(*ptr);
|
|
|
+ next_block = get_dlnext(*allocator, *ptr);
|
|
|
|
|
|
/* Find out the sizes of all possible combinations */
|
|
|
|
|
@@ -50,10 +51,12 @@ bool coalesce(allocator_t *allocator, heap_t *heap, void *ptr) {
|
|
|
if(next_block != NULL) {
|
|
|
if(is_free(next_block) == true) {
|
|
|
#ifdef WITH_OWNERSHIP
|
|
|
- if(get_owner(next_block) == get_owner(ptr)) {
|
|
|
+ if(get_owner(next_block) == get_owner(*ptr)) {
|
|
|
#endif /* WITH_OWNERSHIP */
|
|
|
current_next_size = size + get_size(next_block) + HEADER_SIZE;
|
|
|
#ifdef WITH_OWNERSHIP
|
|
|
+ } else {
|
|
|
+ current_next_size = (size_t) -1; /* SIZE_MAX */
|
|
|
}
|
|
|
#endif /* WITH_OWNERSHIP */
|
|
|
} else {
|
|
@@ -64,12 +67,14 @@ bool coalesce(allocator_t *allocator, heap_t *heap, void *ptr) {
|
|
|
}
|
|
|
|
|
|
/* Previous + Current */
|
|
|
- if(is_previous_free(ptr) == true) {
|
|
|
+ if(is_previous_free(*ptr) == true) {
|
|
|
#ifdef WITH_OWNERSHIP
|
|
|
- if(get_owner(ptr) == get_owner(previous_block)) {
|
|
|
+ if(get_owner(*ptr) == get_owner(previous_block)) {
|
|
|
#endif /* WITH_OWNERSHIP */
|
|
|
- previous_current_size = size + get_previous_size(ptr) + HEADER_SIZE;
|
|
|
+ previous_current_size = size + get_previous_size(*ptr) + HEADER_SIZE;
|
|
|
#ifdef WITH_OWNERSHIP
|
|
|
+ } else {
|
|
|
+ current_next_size = (size_t) -1; /* SIZE_MAX */
|
|
|
}
|
|
|
#endif /* WITH_OWNERSHIP */
|
|
|
} else {
|
|
@@ -78,14 +83,16 @@ bool coalesce(allocator_t *allocator, heap_t *heap, void *ptr) {
|
|
|
|
|
|
/* Previous + Current + Next */
|
|
|
if(next_block != NULL) {
|
|
|
- if(is_previous_free(ptr) && is_free(next_block)) {
|
|
|
+ if(is_previous_free(*ptr) && is_free(next_block)) {
|
|
|
#ifdef WITH_OWNERSHIP
|
|
|
- if(get_owner(ptr) == get_owner(previous_block) &&
|
|
|
- get_owner(ptr) == get_owner(next_block)) {
|
|
|
+ if(get_owner(*ptr) == get_owner(previous_block) &&
|
|
|
+ get_owner(*ptr) == get_owner(next_block)) {
|
|
|
#endif /* WITH_OWNERSHIP */
|
|
|
- three_blocks_size = get_previous_size(ptr) + size +
|
|
|
+ three_blocks_size = get_previous_size(*ptr) + size +
|
|
|
get_size(next_block) + 2 * HEADER_SIZE;
|
|
|
#ifdef WITH_OWNERSHIP
|
|
|
+ } else {
|
|
|
+ current_next_size = (size_t) -1; /* SIZE_MAX */
|
|
|
}
|
|
|
#endif /* WITH_OWNERSHIP */
|
|
|
}
|
|
@@ -93,79 +100,83 @@ bool coalesce(allocator_t *allocator, heap_t *heap, void *ptr) {
|
|
|
three_blocks_size = (size_t) -1; /* SIZE_MAX */
|
|
|
}
|
|
|
|
|
|
- /* Check if Previous + Current + Next is ok */
|
|
|
- if(three_blocks_size <= max_coal_size) {
|
|
|
- /* If previous block is on a fixed list, remove it */
|
|
|
-#ifdef WITH_FIXED_LISTS
|
|
|
- /* Check if it is a block of a fixed list */
|
|
|
- fixed_list_id = map_size_to_list(heap, get_size(previous_block));
|
|
|
- if(fixed_list_id != -1) {
|
|
|
- /* If it is, find the fixed list and remove the block */
|
|
|
- current_maptable_node = heap->maptable_head;
|
|
|
- if(fixed_list_id != 0) {
|
|
|
- for(i = 1; i < fixed_list_id; i++) {
|
|
|
- current_maptable_node = current_maptable_node->next;
|
|
|
- }
|
|
|
- }
|
|
|
-#ifdef COUNT_HOPS
|
|
|
- remove_block(heap, &ptr, ¤t_maptable_node->fixed_list_head);
|
|
|
-#else
|
|
|
- remove_block(&ptr, ¤t_maptable_node->fixed_list_head);
|
|
|
-#endif /* COUNT_HOPS */
|
|
|
- }
|
|
|
-#endif /* WITH_FIXED_LISTS */
|
|
|
- /* Remove the next block from any freelist */
|
|
|
- remove_block_from_lists(&next_block, heap);
|
|
|
- /* Update border pointer if the next block was the border pointer */
|
|
|
- if(allocator->border_ptr == next_block) {
|
|
|
- allocator->border_ptr = previous_block;
|
|
|
- }
|
|
|
- /* Reset the previous block size */
|
|
|
- set_size_and_free(allocator, previous_block, three_blocks_size);
|
|
|
- return true;
|
|
|
- }
|
|
|
+ /* /1* Check if Previous + Current + Next is ok *1/ */
|
|
|
+ /* if(three_blocks_size <= max_coal_size) { */
|
|
|
+ /* /1* If previous block is on a fixed list, remove it *1/ */
|
|
|
+/* #ifdef WITH_FIXED_LISTS */
|
|
|
+ /* /1* Check if it is a block of a fixed list *1/ */
|
|
|
+ /* fixed_list_id = map_size_to_list(heap, get_size(previous_block)); */
|
|
|
+ /* if(fixed_list_id != -1) { */
|
|
|
+ /* /1* If it is, find the fixed list and remove the block *1/ */
|
|
|
+ /* current_maptable_node = heap->maptable_head; */
|
|
|
+ /* if(fixed_list_id != 0) { */
|
|
|
+ /* for(i = 1; i < fixed_list_id; i++) { */
|
|
|
+ /* current_maptable_node = current_maptable_node->next; */
|
|
|
+ /* } */
|
|
|
+ /* } */
|
|
|
+/* #ifdef COUNT_HOPS */
|
|
|
+ /* remove_block(heap, ptr, ¤t_maptable_node->fixed_list_head); */
|
|
|
+/* #else */
|
|
|
+ /* remove_block(ptr, ¤t_maptable_node->fixed_list_head); */
|
|
|
+/* #endif /1* COUNT_HOPS *1/ */
|
|
|
+ /* } */
|
|
|
+/* #endif /1* WITH_FIXED_LISTS *1/ */
|
|
|
+ /* /1* Remove the next block from any freelist *1/ */
|
|
|
+ /* remove_block_from_lists(&next_block, heap); */
|
|
|
+ /* /1* Update border pointer if the next block was the border pointer *1/ */
|
|
|
+ /* if(allocator->border_ptr == next_block) { */
|
|
|
+ /* allocator->border_ptr = previous_block; */
|
|
|
+ /* } */
|
|
|
+ /* /1* Reset the previous block size *1/ */
|
|
|
+ /* set_size_and_free(allocator, previous_block, three_blocks_size); */
|
|
|
+ /* return true; */
|
|
|
+ /* } */
|
|
|
|
|
|
- /* Check if Previous + Current is ok */
|
|
|
- if(previous_current_size <= max_coal_size) {
|
|
|
- /* If previous block is on a fixed list, remove it */
|
|
|
-#ifdef WITH_FIXED_LISTS
|
|
|
- /* Check if it is a block of a fixed list */
|
|
|
- fixed_list_id = map_size_to_list(heap, get_size(previous_block));
|
|
|
- if(fixed_list_id != -1) {
|
|
|
- /* If it is, find the fixed list and remove the block */
|
|
|
- current_maptable_node = heap->maptable_head;
|
|
|
- if(fixed_list_id != 0) {
|
|
|
- for(i = 1; i < fixed_list_id; i++) {
|
|
|
- current_maptable_node = current_maptable_node->next;
|
|
|
- }
|
|
|
- }
|
|
|
-#ifdef COUNT_HOPS
|
|
|
- remove_block(heap, &ptr, ¤t_maptable_node->fixed_list_head);
|
|
|
-#else
|
|
|
- remove_block(&ptr, ¤t_maptable_node->fixed_list_head);
|
|
|
-#endif /* COUNT_HOPS */
|
|
|
- }
|
|
|
-#endif /* WITH_FIXED_LISTS */
|
|
|
- /* Update border pointer if the current block was the border pointer */
|
|
|
- if(allocator->border_ptr == ptr) {
|
|
|
- allocator->border_ptr = previous_block;
|
|
|
- }
|
|
|
- /* Reset the previous block size */
|
|
|
- set_size_and_free(allocator, ptr, previous_current_size);
|
|
|
- return true;
|
|
|
- }
|
|
|
+ /* /1* Check if Previous + Current is ok *1/ */
|
|
|
+ /* if(previous_current_size <= max_coal_size) { */
|
|
|
+ /* /1* If previous block is on a fixed list, remove it *1/ */
|
|
|
+/* #ifdef WITH_FIXED_LISTS */
|
|
|
+ /* /1* Check if it is a block of a fixed list *1/ */
|
|
|
+ /* fixed_list_id = map_size_to_list(heap, get_size(previous_block)); */
|
|
|
+ /* if(fixed_list_id != -1) { */
|
|
|
+ /* /1* If it is, find the fixed list and remove the block *1/ */
|
|
|
+ /* current_maptable_node = heap->maptable_head; */
|
|
|
+ /* if(fixed_list_id != 0) { */
|
|
|
+ /* for(i = 1; i < fixed_list_id; i++) { */
|
|
|
+ /* current_maptable_node = current_maptable_node->next; */
|
|
|
+ /* } */
|
|
|
+ /* } */
|
|
|
+/* #ifdef COUNT_HOPS */
|
|
|
+ /* remove_block(heap, ptr, ¤t_maptable_node->fixed_list_head); */
|
|
|
+/* #else */
|
|
|
+ /* remove_block(ptr, ¤t_maptable_node->fixed_list_head); */
|
|
|
+/* #endif /1* COUNT_HOPS *1/ */
|
|
|
+ /* } */
|
|
|
+/* #endif /1* WITH_FIXED_LISTS *1/ */
|
|
|
+ /* /1* Update border pointer if the current block was the border pointer *1/ */
|
|
|
+ /* if((allocator)->border_ptr == *ptr) { */
|
|
|
+ /* (allocator)->border_ptr = previous_block; */
|
|
|
+ /* } */
|
|
|
+ /* /1* Reset the previous block size *1/ */
|
|
|
+ /* set_size_and_free(allocator, *ptr, previous_current_size); */
|
|
|
+ /* return true; */
|
|
|
+ /* } */
|
|
|
|
|
|
/* Check if Current + Next is ok */
|
|
|
if(current_next_size <= max_coal_size) {
|
|
|
+ printf("cnsize = %zu\n", current_next_size);
|
|
|
+ if(get_size(next_block) == 0) {
|
|
|
+ printf("danger!\n");
|
|
|
+ }
|
|
|
remove_block_from_lists(&next_block, heap);
|
|
|
- if(allocator->border_ptr == next_block) {
|
|
|
- allocator->border_ptr = ptr;
|
|
|
+ if((*allocator)->border_ptr == next_block) {
|
|
|
+ (*allocator)->border_ptr = *ptr;
|
|
|
}
|
|
|
- set_size_and_free(allocator, ptr, current_next_size);
|
|
|
+ set_size_and_free(*allocator, *ptr, current_next_size);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/* If everything fails, just mark the block free */
|
|
|
- mark_free(allocator, ptr);
|
|
|
+ mark_free(*allocator, *ptr);
|
|
|
return false;
|
|
|
}
|