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 = mmalloc(mdp, nmemb*size);
54 memset(ret, 0, nmemb * size);
60 void *realloc(void *p, size_t s)
63 xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
66 ret = mrealloc(mdp, p, s);
74 xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
83 int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr){
85 if(mdp1 == NULL && mdp2 == NULL){
86 XBT_DEBUG("Malloc descriptors null");
92 int errors = mmalloc_compare_mdesc(mdp1, mdp2, std_heap_addr);
98 int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr){
102 if(mdp1->headersize != mdp2->headersize){
103 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
104 XBT_DEBUG("Different size of the file header for the mapped files");
111 if(mdp1->refcount != mdp2->refcount){
112 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
113 XBT_DEBUG("Different number of processes that attached the heap");
120 if(strcmp(mdp1->magic, mdp2->magic) != 0){
121 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
122 XBT_DEBUG("Different magic number");
129 if(mdp1->flags != mdp2->flags){
130 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
131 XBT_DEBUG("Different flags");
138 if(mdp1->heapsize != mdp2->heapsize){
139 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
140 XBT_DEBUG("Different number of info entries");
147 //XBT_DEBUG("Heap size : %zu", mdp1->heapsize);
149 if(mdp1->heapbase != mdp2->heapbase){
150 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
151 XBT_DEBUG("Different first block of the heap");
159 if(mdp1->heapindex != mdp2->heapindex){
160 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
161 XBT_DEBUG("Different index for the heap table : %zu - %zu", mdp1->heapindex, mdp2->heapindex);
168 //XBT_DEBUG("Heap index : %zu", mdp1->heapindex);
170 if(mdp1->base != mdp2->base){
171 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
172 XBT_DEBUG("Different base address of the memory region");
179 if(mdp1->breakval != mdp2->breakval){
180 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
181 XBT_DEBUG("Different current location in the memory region");
188 if(mdp1->top != mdp2->top){
189 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
190 XBT_DEBUG("Different end of the current location in the memory region");
197 if(mdp1->heaplimit != mdp2->heaplimit){
198 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
199 XBT_DEBUG("Different limit of valid info table indices");
206 if(mdp1->fd != mdp2->fd){
207 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
208 XBT_DEBUG("Different file descriptor for the file to which this malloc heap is mapped");
215 if(mdp1->version != mdp2->version){
216 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
217 XBT_DEBUG("Different version of the mmalloc package");
225 size_t block_free1, block_free2 , next_block_free, first_block_free, block_free ;
227 void *addr_block1, *addr_block2;
231 /* Search index of the first free block */
233 block_free1 = mdp1->heapindex;
234 block_free2 = mdp2->heapindex;
236 while(mdp1->heapinfo[block_free1].free_block.prev != 0){
237 block_free1 = mdp1->heapinfo[block_free1].free_block.prev;
240 while(mdp2->heapinfo[block_free2].free_block.prev != 0){
241 block_free2 = mdp1->heapinfo[block_free2].free_block.prev;
244 if(block_free1 != block_free2){
245 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
246 XBT_DEBUG("Different first free block");
253 first_block_free = block_free1;
255 if(mdp1->heapinfo[first_block_free].free_block.size != mdp2->heapinfo[first_block_free].free_block.size){
256 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
257 XBT_DEBUG("Different size (in blocks) of the first free cluster");
264 /* Check busy blocks (circular checking)*/
266 i = first_block_free + mdp1->heapinfo[first_block_free].free_block.size;
268 if(mdp1->heapinfo[first_block_free].free_block.next != mdp2->heapinfo[first_block_free].free_block.next){
269 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
270 XBT_DEBUG("Different next block free");
277 block_free = first_block_free;
278 next_block_free = mdp1->heapinfo[first_block_free].free_block.next;
280 if(next_block_free == 0)
281 next_block_free = mdp1->heaplimit;
283 while(i != first_block_free){
285 while(i<next_block_free){
287 if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
288 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
289 XBT_DEBUG("Different type of busy block");
296 addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
297 addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
299 switch(mdp1->heapinfo[i].type){ //FIXME deal with type<0 == free
301 if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
302 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
303 XBT_DEBUG("Different size of a large cluster");
309 if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
310 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
311 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);
318 i = i+mdp1->heapinfo[i].busy_block.size;
322 if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
323 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
324 XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
330 if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
331 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
332 XBT_DEBUG("Different first free fragments in the block %zu", i);
338 frag_size = pow(2,mdp1->heapinfo[i].type);
339 for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
340 if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
341 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
342 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);
360 if( i != first_block_free){
362 if(mdp1->heapinfo[block_free].free_block.next != mdp2->heapinfo[block_free].free_block.next){
363 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
364 XBT_DEBUG("Different next block free");
371 block_free = mdp1->heapinfo[block_free].free_block.next;
372 next_block_free = mdp1->heapinfo[block_free].free_block.next;
374 i = block_free + mdp1->heapinfo[block_free].free_block.size;
376 if((next_block_free == 0) && (i != mdp1->heaplimit)){
378 while(i < mdp1->heaplimit){
380 if(mdp1->heapinfo[i].type != mdp2->heapinfo[i].type){
381 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
382 XBT_DEBUG("Different type of busy block");
389 addr_block1 = (char *)mdp1 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
390 addr_block2 = (char *)mdp2 + sizeof(struct mdesc) + ((i-1) * BLOCKSIZE);
392 switch(mdp1->heapinfo[i].type){
394 if(mdp1->heapinfo[i].busy_block.size != mdp2->heapinfo[i].busy_block.size){
395 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
396 XBT_DEBUG("Different size of a large cluster");
402 if(memcmp(addr_block1, addr_block2, (mdp1->heapinfo[i].busy_block.size * BLOCKSIZE)) != 0){
403 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
404 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);
412 i = i+mdp1->heapinfo[i].busy_block.size;
416 if(mdp1->heapinfo[i].busy_frag.nfree != mdp2->heapinfo[i].busy_frag.nfree){
417 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
418 XBT_DEBUG("Different free fragments in the fragmented block %zu", i);
424 if(mdp1->heapinfo[i].busy_frag.first != mdp2->heapinfo[i].busy_frag.first){
425 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
426 XBT_DEBUG("Different first free fragments in the block %zu", i);
432 frag_size = pow(2,mdp1->heapinfo[i].type);
433 for(j=0 ; j< (BLOCKSIZE/frag_size); j++){
434 if(memcmp((char *)addr_block1 + (j * frag_size), (char *)addr_block2 + (j * frag_size), frag_size) != 0){
435 if(XBT_LOG_ISENABLED(xbt_mm_legacy, xbt_log_priority_debug)){
436 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);
462 void mmalloc_display_info_heap(xbt_mheap_t h){