dmmlib.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * Copyright 2012 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. /**
  18. * @file dmmlib.c
  19. * @author Ioannis Koutras (joko@microlab.ntua.gr)
  20. * @date September 2012
  21. *
  22. * @brief Implementations of malloc(), free() and calloc() calls.
  23. */
  24. #include "dmmlib/dmmlib.h"
  25. #ifdef FL_RB_ONLY
  26. #include "freelist/freelist.h"
  27. #include "freelist/freelist_rb.h"
  28. #endif /* FL_RB_ONLY */
  29. #ifdef BITMAP_RB_ONLY
  30. #include "bitmap/bitmap.h"
  31. #include "bitmap/bitmap_rb.h"
  32. #endif /* BITMAP_RB_ONLY */
  33. #include "release_memory.h"
  34. #include <stdbool.h>
  35. #include <string.h> /* for memset() */
  36. #include "trace.h"
  37. #ifdef WITH_DEBUG
  38. #include "debug.h"
  39. #endif /* WITH_DEBUG */
  40. void * malloc(size_t size) {
  41. raw_block_header_t *raw_block, *new_raw_block;
  42. size_t allocation_size;
  43. void *ptr;
  44. raw_block = systemallocator.raw_block_head;
  45. ptr = NULL;
  46. if(size == 0) {
  47. return NULL;
  48. }
  49. TRACE_1("dmmlib - malloc - request %zu bytes\n", size);
  50. /* Try to find a raw block available for allocation */
  51. while(raw_block != NULL) {
  52. ptr = dmmlib_malloc(raw_block, size);
  53. if(ptr != NULL) {
  54. break;
  55. }
  56. raw_block = raw_block->next_raw_block;
  57. }
  58. if(ptr == NULL) {
  59. #ifdef FL_RB_ONLY
  60. allocation_size = size + sizeof(raw_block_header_t) +
  61. sizeof(freelist_rb_t);
  62. #endif /* FL_RB_ONLY */
  63. #ifdef BITMAP_RB_ONLY
  64. allocation_size = size + sizeof(raw_block_header_t) +
  65. sizeof(bitmap_rb_t);
  66. #endif /* BITMAP_RB_ONLY */
  67. if(allocation_size < SYS_ALLOC_SIZE / 2) {
  68. allocation_size = SYS_ALLOC_SIZE;
  69. } else {
  70. ptr = (void *)create_new_raw_block(size +
  71. sizeof(raw_block_header_t), BIGBLOCK);
  72. if(ptr != NULL) {
  73. TRACE_1("dmmlib - malloc - allocated a whole raw block of %zu"
  74. " bytes at %p\n", size + sizeof(raw_block_header_t),
  75. (void *)ptr);
  76. #ifdef WITH_ALLOCATOR_STATS
  77. systemallocator.dmm_stats.total_mem_allocated +=
  78. size + sizeof(raw_block_header_t);
  79. systemallocator.dmm_stats.live_objects++;
  80. systemallocator.dmm_stats.num_malloc++;
  81. TRACE_1("dmmlib - global allocated memory: %zu bytes\n",
  82. systemallocator.dmm_stats.total_mem_allocated);
  83. #ifdef REQUEST_SIZE_INFO
  84. systemallocator.dmm_stats.total_mem_requested += size;
  85. TRACE_1("dmmlib - global requested memory: %zu bytes\n",
  86. systemallocator.dmm_stats.total_mem_requested);
  87. #endif /* REQUEST_SIZE_INFO */
  88. #endif /* WITH_ALLOCATOR_STATS */
  89. ptr = (void *)((char *)ptr + sizeof(raw_block_header_t));
  90. }
  91. return ptr;
  92. }
  93. pthread_mutex_lock(&systemallocator.creation_mutex);
  94. #ifdef FL_RB_ONLY
  95. new_raw_block = create_new_raw_block(allocation_size, FREELIST);
  96. #endif /* FL_RB_ONLY */
  97. #ifdef BITMAP_RB_ONLY
  98. new_raw_block = create_new_raw_block(allocation_size, BITMAP);
  99. #endif /* BITMAP_RB_ONLY */
  100. if(new_raw_block != NULL) {
  101. new_raw_block->next_raw_block = systemallocator.raw_block_head;
  102. systemallocator.raw_block_head = new_raw_block;
  103. pthread_mutex_unlock(&systemallocator.creation_mutex);
  104. ptr = dmmlib_malloc(new_raw_block, size);
  105. #ifdef BITMAP_RB_ONLY
  106. // FIXME If ptr is still NULL, then make a last try to allocate a
  107. // big block. This has to do with the current limitation of checking
  108. // max. two bitmap vector elements.
  109. if(ptr == NULL) {
  110. ptr = (void *) create_new_raw_block(size +
  111. sizeof(raw_block_header_t), BIGBLOCK);
  112. if(ptr != NULL) {
  113. TRACE_1("dmmlib - malloc - allocated a whole raw block of %zu"
  114. " bytes at %p\n", size + sizeof(raw_block_header_t),
  115. (void *)ptr);
  116. #ifdef WITH_ALLOCATOR_STATS
  117. systemallocator.dmm_stats.total_mem_allocated +=
  118. size + sizeof(raw_block_header_t);
  119. systemallocator.dmm_stats.live_objects++;
  120. systemallocator.dmm_stats.num_malloc++;
  121. TRACE_1("dmmlib - global allocated memory: %zu bytes\n",
  122. systemallocator.dmm_stats.total_mem_allocated);
  123. #ifdef REQUEST_SIZE_INFO
  124. systemallocator.dmm_stats.total_mem_requested += size;
  125. TRACE_1("dmmlib - global requested memory: %zu bytes\n",
  126. systemallocator.dmm_stats.total_mem_requested);
  127. #endif /* REQUEST_SIZE_INFO */
  128. #endif /* WITH_ALLOCATOR_STATS */
  129. ptr = (void *)((char *)ptr + sizeof(raw_block_header_t));
  130. }
  131. }
  132. #endif /* BITMAP_RB_ONLY */
  133. }
  134. }
  135. #ifdef WITH_DEBUG
  136. get_raw_blocks(&systemallocator);
  137. #endif /* WITH_DEBUG */
  138. return ptr;
  139. }
  140. void free(void *ptr) {
  141. raw_block_header_t *current_raw_block;
  142. bool found;
  143. if(ptr == NULL) {
  144. return;
  145. }
  146. found = false;
  147. current_raw_block = systemallocator.raw_block_head;
  148. while(current_raw_block) {
  149. if((char *)ptr - (char *)(current_raw_block) -
  150. sizeof(raw_block_header_t) < current_raw_block->size) {
  151. found = true;
  152. break;
  153. }
  154. current_raw_block = current_raw_block->next_raw_block;
  155. }
  156. if(found == true) {
  157. dmmlib_free(current_raw_block, ptr);
  158. } else { // It has to be a BIGBLOCK, just munmap it
  159. current_raw_block = (raw_block_header_t *)((char *)ptr -
  160. sizeof(raw_block_header_t));
  161. TRACE_1("dmmlib - free - free'ing %zu bytes from raw block %p\n",
  162. current_raw_block->size, (void *)current_raw_block);
  163. #ifdef WITH_ALLOCATOR_STATS
  164. systemallocator.dmm_stats.total_mem_allocated -=
  165. current_raw_block->size;
  166. TRACE_1("dmmlib - global allocated memory: %zu bytes\n",
  167. systemallocator.dmm_stats.total_mem_allocated);
  168. #ifdef REQUEST_SIZE_INFO
  169. systemallocator.dmm_stats.total_mem_requested -=
  170. current_raw_block->size - sizeof(raw_block_header_t);
  171. TRACE_1("dmmlib - global requested memory: %zu bytes\n",
  172. systemallocator.dmm_stats.total_mem_requested);
  173. #endif /* REQUEST_SIZE_INFO */
  174. systemallocator.dmm_stats.live_objects--;
  175. systemallocator.dmm_stats.num_free++;
  176. #endif /* WITH_ALLOCATOR_STATS */
  177. release_memory(current_raw_block);
  178. }
  179. }
  180. void * realloc(void *ptr, size_t size) {
  181. raw_block_header_t *current_raw_block;
  182. bool found;
  183. if(ptr == NULL) {
  184. return malloc(size);
  185. }
  186. if(size == 0) {
  187. free(ptr);
  188. #ifdef BITMAP_RB_ONLY
  189. return malloc(CHUNK_HDR_SIZE + 32); // FIXME 32 <- minimum size
  190. #endif /* BITMAP_RB_ONLY */
  191. #ifdef FL_RB_ONLY
  192. return malloc((size_t) 32); // FIXME 32 <- minimum size
  193. #endif /* FL_RB_ONLY */
  194. }
  195. found = false;
  196. current_raw_block = systemallocator.raw_block_head;
  197. while(current_raw_block) {
  198. if((char *)ptr - (char *)(current_raw_block) -
  199. sizeof(raw_block_header_t) < current_raw_block->size) {
  200. found = true;
  201. break;
  202. }
  203. current_raw_block = current_raw_block->next_raw_block;
  204. }
  205. if(found == true) {
  206. #ifdef BITMAP_RB_ONLY
  207. return bitmap_realloc(current_raw_block, ptr, size);
  208. #endif /* BITMAP_RB_ONLY */
  209. #ifdef FL_RB_ONLY
  210. return freelist_realloc(current_raw_block, ptr, size);
  211. #endif /* FL_RB_ONLY */
  212. } else {
  213. return NULL;
  214. }
  215. }
  216. void * calloc(size_t nmemb, size_t size) {
  217. size_t i;
  218. char *buf[nmemb];
  219. if(nmemb == 0 || size == 0) {
  220. return NULL;
  221. }
  222. i = 0;
  223. while(i < nmemb) {
  224. buf[i] = (char*)malloc(size);
  225. memset(buf[i], '\0', size);
  226. i++;
  227. }
  228. return buf[0];
  229. }