| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- /*
- * 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 <stdio.h>
- #include <dmmlib/dmmlib.h>
- #include "other.h"
- #ifdef HAVE_LOCKS
- #include "posix_lock.h"
- #endif /* HAVE_LOCKS */
- #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
- #include "coalesce.h"
- #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
- #ifdef WITH_ADAPTIVITY
- #include "dmm_adaptor.h"
- #endif /* WITH_ADAPTIVITY */
- #include "block_header.h"
- void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
- size_t size;
- #ifdef WITH_FIXED_LISTS
- int fixed_list_id, i;
- maptable_node_t *current_maptable_node;
- #endif /* WITH_FIXED_LISTS */
- #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
- bool coalesced;
- size_t max_coal_size;
- void *next_block;
- size_t current_next_size;
- size_t previous_current_size;
- size_t three_blocks_size;
- #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
- #ifndef WITH_MEMORY_SPACE_AWARENESS
- int heap_id;
- /* Currently all the memory space aware allocators are pre-initialized */
- if(allocator == NULL) {
- allocator = &systemallocator;
- }
- if(heap == NULL) {
- heap_id = map_thread_heap();
- heap = &allocator->heaps[heap_id];
- }
- #endif /* WITH_MEMORY_SPACE_AWARENESS */
- size = get_size(ptr);
- #ifdef HAVE_LOCKS
- posix_lock(heap);
- #endif /* HAVE_LOCKS */
- #ifdef FUTURE_FEATURES
- remove_block(&ptr, &heap->used_blocks_head);
- #endif /* FUTURE_FEATURES */
- #ifdef WITH_STATS
- heap->dmm_stats.mem_allocated -= size;
- #ifdef FUTURE_FEATURES
- heap->dmm_stats.mem_requested -= get_requested_size(ptr);
- #endif /* FUTURE_FEATURES */
- #endif /* WITH_STATS */
- #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
- coalesced = false;
- #ifdef COALESCING_FIXED
- max_coal_size = MAX_COALESCE_SIZE;
- #endif /* COALESCING_FIXED */
- #ifdef COALESCING_VARIABLE
- max_coal_size = heap->dmm_knobs.max_coalesce_size;
- #endif /* COALESCING_VARIABLE */
- next_block = get_dlnext(allocator, ptr);
- if(next_block != NULL) {
- if(is_free(next_block) == true) {
- #ifdef WITH_OWNERSHIP
- if(get_owner(next_block) == get_owner(ptr)) {
- #endif /* WITH_OWNERSHIP */
- current_next_size = size + get_size(next_block) + HEADER_SIZE;
- #ifdef WITH_OWNERSHIP
- }
- #endif /* WITH_OWNERSHIP */
- } else {
- current_next_size = (size_t) -1; /* SIZE_MAX */
- }
- } else {
- current_next_size = (size_t) -1; /* SIZE_MAX */
- }
- if(is_previous_free(ptr) == true) {
- #ifdef WITH_OWNERSHIP
- if(get_owner(ptr) == get_owner(get_dlprevious(ptr))) {
- #endif /* WITH_OWNERSHIP */
- previous_current_size = size + get_previous_size(ptr) + HEADER_SIZE;
- #ifdef WITH_OWNERSHIP
- }
- #endif /* WITH_OWNERSHIP */
- } else {
- previous_current_size = (size_t) -1; /* SIZE_MAX */
- }
- if(next_block != NULL && is_previous_free(ptr)) {
- #ifdef WITH_OWNERSHIP
- if(get_owner(ptr) == get_owner(get_dlprevious(ptr) &&
- get_owner(ptr) == get_owner(next_block))) {
- #endif /* WITH_OWNERSHIP */
- three_blocks_size = get_previous_size(ptr) + size +
- get_size(next_block) + 2 * HEADER_SIZE;
- #ifdef WITH_OWNERSHIP
- }
- #endif /* WITH_OWNERSHIP */
- } else {
- three_blocks_size = (size_t) -1; /* SIZE_MAX */
- }
- if(three_blocks_size <= max_coal_size) {
- ptr = coalesce(allocator, heap, ptr, three_blocks_size);
- remove_block_from_lists(&next_block, heap);
- if(allocator->border_ptr == next_block) {
- allocator->border_ptr = ptr;
- }
- coalesced = true;
- size = three_blocks_size;
- } else {
- if(previous_current_size <= max_coal_size) {
- ptr = coalesce(allocator, heap, ptr, previous_current_size);
- coalesced = true;
- size = previous_current_size;
- } else {
- if(current_next_size <= max_coal_size) {
- set_size_and_free(allocator, ptr, current_next_size);
- remove_block_from_lists(&next_block, heap);
- if(allocator->border_ptr == next_block) {
- allocator->border_ptr = ptr;
- }
- } else {
- mark_free(allocator, ptr);
- }
- }
- }
- #else
- mark_free(allocator, ptr);
- #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
- #ifdef WITH_FIXED_LISTS
- /* 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) {
- 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;
- }
- }
- push_block(&ptr, ¤t_maptable_node->fixed_list_head);
- } else { /* put it in the free list */
- #endif /* WITH_FIXED_LISTS */
- #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
- /* The block should be added to the free list only if it is not
- * coalesced
- */
- if(!coalesced) {
- push_block(&ptr, &heap->free_list_head);
- }
- #else
- push_block(&ptr, &heap->free_list_head);
- #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
- #ifdef WITH_FIXED_LISTS
- }
- #endif /* WITH_FIXED_LISTS */
- #ifdef WITH_STATS
- /* Update Stats */
- heap->dmm_stats.live_objects -= 1;
- heap->dmm_stats.num_free += 1;
- /* End of Stats */
- #endif /* WITH_STATS */
- #ifdef WITH_ADAPTIVITY
- /* 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);
- }
- #endif /* WITH_ADAPTIVITY */
- #ifdef HAVE_LOCKS
- posix_unlock(heap);
- #endif /* HAVE_LOCKS */
- }
- /* Currently all the memory space aware allocators are pre-initialized, so
- * we do not expect any custom_ahmalloc call without knowing which allocator
- * and heap are to be used.
- */
- #ifndef WITH_MEMORY_SPACE_AWARENESS
- void custom_free(void *ptr) {
- custom_ahfree(NULL, NULL, ptr);
- }
- #endif /* WITH_MEMORY_SPACE_AWARENESS */
|