1 /* Copyright (c) 2010. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
7 /* Redefine the classical malloc/free/realloc functions so that they fit well in the mmalloc framework */
10 #include "gras_config.h"
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_mm_legacy, xbt,
14 "Logging specific to mm_legacy in mmalloc");
16 /* The mmalloc() package can use a single implicit malloc descriptor
17 for mmalloc/mrealloc/mfree operations which do not supply an explicit
18 descriptor. This allows mmalloc() to provide
19 backwards compatibility with the non-mmap'd version. */
20 xbt_mheap_t __mmalloc_default_mdp = NULL;
23 static xbt_mheap_t __mmalloc_current_heap = NULL; /* The heap we are currently using. */
25 xbt_mheap_t mmalloc_get_current_heap(void)
27 return __mmalloc_current_heap;
30 void mmalloc_set_current_heap(xbt_mheap_t new_heap)
32 __mmalloc_current_heap = new_heap;
35 #ifdef MMALLOC_WANT_OVERIDE_LEGACY
36 void *malloc(size_t n)
38 xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
41 void *ret = mmalloc(mdp, n);
47 void *calloc(size_t nmemb, size_t size)
49 xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
52 void *ret = mcalloc(mdp, nmemb,size);
58 void *realloc(void *p, size_t s)
61 xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
64 ret = mrealloc(mdp, p, s);
72 xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
81 int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr){
83 if(mdp1 == NULL && mdp2 == NULL){
84 XBT_DEBUG("Malloc descriptors null");
90 int errors = mmalloc_compare_mdesc(mdp1, mdp2, std_heap_addr);
96 int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr){
100 if(mdp1->headersize != mdp2->headersize){
101 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
102 XBT_DEBUG("Different size of the file header for the mapped files");
109 if(mdp1->refcount != mdp2->refcount){
110 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
111 XBT_DEBUG("Different number of processes that attached the heap");
118 if(strcmp(mdp1->magic, mdp2->magic) != 0){
119 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
120 XBT_DEBUG("Different magic number");
127 if(mdp1->flags != mdp2->flags){
128 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
129 XBT_DEBUG("Different flags");
136 if(mdp1->heapsize != mdp2->heapsize){
137 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
138 XBT_DEBUG("Different number of info entries");
145 //XBT_DEBUG("Heap size : %zu", mdp1->heapsize);
147 if(mdp1->heapbase != mdp2->heapbase){
148 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
149 XBT_DEBUG("Different first block of the heap");
157 if(mdp1->heapindex != mdp2->heapindex){
158 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
159 XBT_DEBUG("Different index for the heap table : %zu - %zu", mdp1->heapindex, mdp2->heapindex);
166 //XBT_DEBUG("Heap index : %zu", mdp1->heapindex);
168 if(mdp1->base != mdp2->base){
169 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
170 XBT_DEBUG("Different base address of the memory region");
177 if(mdp1->breakval != mdp2->breakval){
178 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
179 XBT_DEBUG("Different current location in the memory region");
186 if(mdp1->top != mdp2->top){
187 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
188 XBT_DEBUG("Different end of the current location in the memory region");
195 if(mdp1->heaplimit != mdp2->heaplimit){
196 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
197 XBT_DEBUG("Different limit of valid info table indices");
204 if(mdp1->fd != mdp2->fd){
205 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
206 XBT_DEBUG("Different file descriptor for the file to which this malloc heap is mapped");
213 if(mdp1->version != mdp2->version){
214 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
215 XBT_DEBUG("Different version of the mmalloc package");
223 size_t block_free1, block_free2 , next_block_free, first_block_free, block_free ;
225 void *addr_block1, *addr_block2;
229 /* Search index of the first free block */
231 block_free1 = mdp1->heapindex;
232 block_free2 = mdp2->heapindex;
234 while(mdp1->heapinfo[block_free1].free_block.prev != 0){
235 block_free1 = mdp1->heapinfo[block_free1].free_block.prev;
238 while(mdp2->heapinfo[block_free2].free_block.prev != 0){
239 block_free2 = mdp1->heapinfo[block_free2].free_block.prev;
242 if(block_free1 != block_free2){
243 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
244 XBT_DEBUG("Different first free block");
251 first_block_free = block_free1;
253 if(mdp1->heapinfo[first_block_free].free_block.size != mdp2->heapinfo[first_block_free].free_block.size){
254 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
255 XBT_DEBUG("Different size (in blocks) of the first free cluster");
262 /* Check busy blocks (circular checking)*/
264 i = first_block_free + mdp1->heapinfo[first_block_free].free_block.size;
266 if(mdp1->heapinfo[first_block_free].free_block.next != mdp2->heapinfo[first_block_free].free_block.next){
267 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
268 XBT_DEBUG("Different next block free");
275 block_free = first_block_free;
276 next_block_free = mdp1->heapinfo[first_block_free].free_block.next;
278 if(next_block_free == 0)
279 next_block_free = mdp1->heaplimit;
281 while(i != first_block_free){
283 while(i<next_block_free){
285 if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
286 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
287 XBT_DEBUG("Different type of busy block");
294 addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
295 addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
297 switch(mdp1->heapinfo[i].type){ //FIXME deal with type<0 == free
299 if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
300 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
301 XBT_DEBUG("Different size of a large cluster");
307 if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
308 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
309 XBT_DEBUG("Different data in block %zu (size = %zu) (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, mdp1->heapinfo[i].busy_block.size, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
316 i = i+mdp1->heapinfo[i].busy_block.size;
320 if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
321 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
322 XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
328 if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
329 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
330 XBT_DEBUG("Different first free fragments in the block %zu", i);
336 frag_size = pow(2,mdp1->heapinfo[i].type);
337 for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
338 if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
339 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
340 XBT_DEBUG("Different data in fragment %zu (addr_frag1 = %p - addr_frag2 = %p) of block %zu", j + 1, (char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), i);
358 if( i != first_block_free){
360 if(mdp1->heapinfo[block_free].free_block.next != mdp2->heapinfo[block_free].free_block.next){
361 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
362 XBT_DEBUG("Different next block free");
369 block_free = mdp1->heapinfo[block_free].free_block.next;
370 next_block_free = mdp1->heapinfo[block_free].free_block.next;
372 i = block_free + mdp1->heapinfo[block_free].free_block.size;
374 if((next_block_free == 0) && (i != mdp1->heaplimit)){
376 while(i < mdp1->heaplimit){
378 if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
379 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
380 XBT_DEBUG("Different type of busy block");
387 addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
388 addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
390 switch(mdp1->heapinfo[i].type){
392 if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
393 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
394 XBT_DEBUG("Different size of a large cluster");
400 if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
401 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
402 XBT_DEBUG("Different data in block %zu (addr_block1 = %p (current = %p) - addr_block2 = %p)", i, addr_block1, (char *)std_heap_addr + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE), addr_block2);
410 i = i+mdp1->heapinfo[i].busy_block.size;
414 if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
415 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
416 XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
422 if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
423 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
424 XBT_DEBUG("Different first free fragments in the block %zu", i);
430 frag_size = pow(2,mdp1->heapinfo[i].type);
431 for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
432 if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
433 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
434 XBT_DEBUG("Different data in fragment %zu (addr_frag1 = %p - addr_frag2 = %p) of block %zu", j + 1, (char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), i);
460 void mmalloc_display_info_heap(xbt_mheap_t h){