custom_free.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright 2011 Institute of Communication and Computer Systems (ICCS)
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. #include <stdio.h>
  18. #include <dmmlib/dmmlib.h>
  19. #include "other.h"
  20. #ifdef HAVE_LOCKS
  21. #include "posix_lock.h"
  22. #endif /* HAVE_LOCKS */
  23. #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
  24. #include "coalesce.h"
  25. #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
  26. #ifdef WITH_ADAPTIVITY
  27. #include "dmm_adaptor.h"
  28. #endif /* WITH_ADAPTIVITY */
  29. #include "block_header.h"
  30. void custom_ahfree(allocator_t *allocator, heap_t* heap, void *ptr) {
  31. size_t size;
  32. #ifdef WITH_FIXED_LISTS
  33. int fixed_list_id, i;
  34. maptable_node_t *current_maptable_node;
  35. #endif /* WITH_FIXED_LISTS */
  36. #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
  37. bool coalesced;
  38. size_t max_coal_size;
  39. void *next_block;
  40. size_t current_next_size;
  41. size_t previous_current_size;
  42. size_t three_blocks_size;
  43. #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
  44. #ifndef WITH_MEMORY_SPACE_AWARENESS
  45. int heap_id;
  46. /* Currently all the memory space aware allocators are pre-initialized */
  47. if(allocator == NULL) {
  48. allocator = &systemallocator;
  49. }
  50. if(heap == NULL) {
  51. heap_id = map_thread_heap();
  52. heap = &allocator->heaps[heap_id];
  53. }
  54. #endif /* WITH_MEMORY_SPACE_AWARENESS */
  55. size = get_size(ptr);
  56. #ifdef HAVE_LOCKS
  57. posix_lock(heap);
  58. #endif /* HAVE_LOCKS */
  59. #ifdef FUTURE_FEATURES
  60. remove_block(&ptr, &heap->used_blocks_head);
  61. #endif /* FUTURE_FEATURES */
  62. #ifdef WITH_STATS
  63. heap->dmm_stats.mem_allocated -= size;
  64. #ifdef FUTURE_FEATURES
  65. heap->dmm_stats.mem_requested -= get_requested_size(ptr);
  66. #endif /* FUTURE_FEATURES */
  67. #endif /* WITH_STATS */
  68. #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
  69. coalesced = false;
  70. #ifdef COALESCING_FIXED
  71. max_coal_size = MAX_COALESCE_SIZE;
  72. #endif /* COALESCING_FIXED */
  73. #ifdef COALESCING_VARIABLE
  74. max_coal_size = heap->dmm_knobs.max_coalesce_size;
  75. #endif /* COALESCING_VARIABLE */
  76. next_block = get_dlnext(allocator, ptr);
  77. if(next_block != NULL) {
  78. if(is_free(next_block) == true) {
  79. #ifdef WITH_OWNERSHIP
  80. if(get_owner(next_block) == get_owner(ptr)) {
  81. #endif /* WITH_OWNERSHIP */
  82. current_next_size = size + get_size(next_block) + HEADER_SIZE;
  83. #ifdef WITH_OWNERSHIP
  84. }
  85. #endif /* WITH_OWNERSHIP */
  86. } else {
  87. current_next_size = (size_t) -1; /* SIZE_MAX */
  88. }
  89. } else {
  90. current_next_size = (size_t) -1; /* SIZE_MAX */
  91. }
  92. if(is_previous_free(ptr) == true) {
  93. #ifdef WITH_OWNERSHIP
  94. if(get_owner(ptr) == get_owner(get_dlprevious(ptr))) {
  95. #endif /* WITH_OWNERSHIP */
  96. previous_current_size = size + get_previous_size(ptr) + HEADER_SIZE;
  97. #ifdef WITH_OWNERSHIP
  98. }
  99. #endif /* WITH_OWNERSHIP */
  100. } else {
  101. previous_current_size = (size_t) -1; /* SIZE_MAX */
  102. }
  103. if(next_block != NULL && is_previous_free(ptr)) {
  104. #ifdef WITH_OWNERSHIP
  105. if(get_owner(ptr) == get_owner(get_dlprevious(ptr) &&
  106. get_owner(ptr) == get_owner(next_block))) {
  107. #endif /* WITH_OWNERSHIP */
  108. three_blocks_size = get_previous_size(ptr) + size +
  109. get_size(next_block) + 2 * HEADER_SIZE;
  110. #ifdef WITH_OWNERSHIP
  111. }
  112. #endif /* WITH_OWNERSHIP */
  113. } else {
  114. three_blocks_size = (size_t) -1; /* SIZE_MAX */
  115. }
  116. if(three_blocks_size <= max_coal_size) {
  117. ptr = coalesce(allocator, heap, ptr, three_blocks_size);
  118. remove_block_from_lists(&next_block, heap);
  119. if(allocator->border_ptr == next_block) {
  120. allocator->border_ptr = ptr;
  121. }
  122. coalesced = true;
  123. size = three_blocks_size;
  124. } else {
  125. if(previous_current_size <= max_coal_size) {
  126. ptr = coalesce(allocator, heap, ptr, previous_current_size);
  127. coalesced = true;
  128. size = previous_current_size;
  129. } else {
  130. if(current_next_size <= max_coal_size) {
  131. set_size_and_free(allocator, ptr, current_next_size);
  132. remove_block_from_lists(&next_block, heap);
  133. if(allocator->border_ptr == next_block) {
  134. allocator->border_ptr = ptr;
  135. }
  136. } else {
  137. mark_free(allocator, ptr);
  138. }
  139. }
  140. }
  141. #else
  142. mark_free(allocator, ptr);
  143. #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
  144. #ifdef WITH_FIXED_LISTS
  145. /* Check if the block could be put in a fixed list */
  146. fixed_list_id = map_size_to_list(heap, size);
  147. if(fixed_list_id != -1) {
  148. current_maptable_node = heap->maptable_head;
  149. if(fixed_list_id != 0) {
  150. for(i = 1; i < fixed_list_id; i++) {
  151. current_maptable_node = current_maptable_node->next;
  152. }
  153. }
  154. push_block(&ptr, &current_maptable_node->fixed_list_head);
  155. } else { /* put it in the free list */
  156. #endif /* WITH_FIXED_LISTS */
  157. #if defined (COALESCING_FIXED) || defined (COALESCING_VARIABLE)
  158. /* The block should be added to the free list only if it is not
  159. * coalesced
  160. */
  161. if(!coalesced) {
  162. push_block(&ptr, &heap->free_list_head);
  163. }
  164. #else
  165. push_block(&ptr, &heap->free_list_head);
  166. #endif /* COALESCING_FIXED || COALESCING_VARIABLE */
  167. #ifdef WITH_FIXED_LISTS
  168. }
  169. #endif /* WITH_FIXED_LISTS */
  170. #ifdef WITH_STATS
  171. /* Update Stats */
  172. heap->dmm_stats.live_objects -= 1;
  173. heap->dmm_stats.num_free += 1;
  174. /* End of Stats */
  175. #endif /* WITH_STATS */
  176. #ifdef WITH_ADAPTIVITY
  177. /* Refresh the state of the heap allocator if a certain number of
  178. * free's has been served already
  179. */
  180. /* TODO Define 100 as a constant */
  181. if(heap->dmm_stats.num_free % 100) {
  182. free_state_refresh(heap);
  183. }
  184. #endif /* WITH_ADAPTIVITY */
  185. #ifdef HAVE_LOCKS
  186. posix_unlock(heap);
  187. #endif /* HAVE_LOCKS */
  188. }
  189. /* Currently all the memory space aware allocators are pre-initialized, so
  190. * we do not expect any custom_ahmalloc call without knowing which allocator
  191. * and heap are to be used.
  192. */
  193. #ifndef WITH_MEMORY_SPACE_AWARENESS
  194. void custom_free(void *ptr) {
  195. custom_ahfree(NULL, NULL, ptr);
  196. }
  197. #endif /* WITH_MEMORY_SPACE_AWARENESS */