Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
166b0f7d7e15939574f9563d41c4e41c11606c5c
[simgrid.git] / src / xbt / mmalloc / mm_diff.c
1 /* mm_diff - Memory snapshooting and comparison                             */
2
3 /* Copyright (c) 2008-2012. The SimGrid Team. All rights reserved.          */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "xbt/ex_interface.h" /* internals of backtrace setup */
9 #include "xbt/str.h"
10 #include "mc/mc.h"
11 #include "xbt/mmalloc.h"
12
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mm_diff, xbt,
14                                 "Logging specific to mm_diff in mmalloc");
15
16 xbt_dynar_t mc_heap_comparison_ignore;
17 xbt_dynar_t stacks_areas;
18
19 static void heap_area_pair_free(heap_area_pair_t pair);
20 static void heap_area_pair_free_voidp(void *d);
21 static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2);
22 static int is_new_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2);
23 static heap_area_t new_heap_area(int block, int fragment);
24
25 static int compare_area(void *area1, void* area2, size_t size, xbt_dynar_t previous, int check_ignore);
26 static void match_equals(xbt_dynar_t list, xbt_dynar_t *equals);
27
28 static int in_mc_comparison_ignore(int block, int fragment);
29 static size_t heap_comparison_ignore_size(void *address);
30 static void add_heap_equality(xbt_dynar_t *equals, void *a1, void *a2);
31 static void remove_heap_equality(xbt_dynar_t *equals, int address, void *a);
32
33 static char* is_stack(void *address);
34
35 void mmalloc_backtrace_block_display(void* heapinfo, int block){
36
37   xbt_ex_t e;
38
39   if (((malloc_info *)heapinfo)[block].busy_block.bt_size == 0) {
40     fprintf(stderr, "No backtrace available for that block, sorry.\n");
41     return;
42   }
43
44   memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_block.bt),sizeof(void*)*XBT_BACKTRACE_SIZE);
45   e.used = ((malloc_info *)heapinfo)[block].busy_block.bt_size;
46
47   xbt_ex_setup_backtrace(&e);
48   if (e.used == 0) {
49     fprintf(stderr, "(backtrace not set)\n");
50   } else if (e.bt_strings == NULL) {
51     fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet");
52   } else {
53     int i;
54
55     fprintf(stderr, "Backtrace of where the block %d was malloced (%d frames):\n", block ,e.used);
56     for (i = 0; i < e.used; i++)       /* no need to display "xbt_backtrace_display" */{
57       fprintf(stderr, "%d ---> %s\n",i, e.bt_strings[i] + 4);
58     }
59   }
60
61 }
62
63 void mmalloc_backtrace_fragment_display(void* heapinfo, int block, int frag){
64
65   xbt_ex_t e;
66
67   memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_frag.bt[frag]),sizeof(void*)*XBT_BACKTRACE_SIZE);
68   e.used = XBT_BACKTRACE_SIZE;
69
70   xbt_ex_setup_backtrace(&e);
71   if (e.used == 0) {
72     fprintf(stderr, "(backtrace not set)\n");
73   } else if (e.bt_strings == NULL) {
74     fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet");
75   } else {
76     int i;
77
78     fprintf(stderr, "Backtrace of where the fragment %d in block %d was malloced (%d frames):\n", frag, block ,e.used);
79     for (i = 0; i < e.used; i++)       /* no need to display "xbt_backtrace_display" */{
80       fprintf(stderr, "%d ---> %s\n",i, e.bt_strings[i] + 4);
81     }
82   }
83
84 }
85
86 void mmalloc_backtrace_display(void *addr){
87
88   size_t block, frag_nb;
89   int type;
90   
91   xbt_mheap_t heap = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
92
93   block = (((char*) (addr) - (char*) heap -> heapbase) / BLOCKSIZE + 1);
94
95   type = heap->heapinfo[block].type;
96
97   switch(type){
98   case -1 : /* Free block */
99     fprintf(stderr, "Asked to display the backtrace of a block that is free. I'm puzzled\n");
100     xbt_abort();
101     break; 
102   case 0: /* Large block */
103     mmalloc_backtrace_block_display(heap->heapinfo, block);
104     break;
105   default: /* Fragmented block */
106     frag_nb = RESIDUAL(addr, BLOCKSIZE) >> type;
107     if(heap->heapinfo[block].busy_frag.frag_size[frag_nb] == -1){
108       fprintf(stderr , "Asked to display the backtrace of a fragment that is free. I'm puzzled\n");
109       xbt_abort();
110     }
111     mmalloc_backtrace_fragment_display(heap->heapinfo, block, frag_nb);
112     break;
113   }
114
115 }
116
117
118 void *s_heap = NULL, *heapbase1 = NULL, *heapbase2 = NULL;
119 malloc_info *heapinfo1 = NULL, *heapinfo2 = NULL;
120 size_t heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
121
122 int ignore_done = 0;
123
124 int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t *stack1, xbt_dynar_t *stack2, xbt_dynar_t *equals){
125
126   if(heap1 == NULL && heap1 == NULL){
127     XBT_DEBUG("Malloc descriptors null");
128     return 0;
129   }
130
131   if(heap1->heaplimit != heap2->heaplimit){
132     XBT_DEBUG("Different limit of valid info table indices");
133     return 1;
134   }
135
136   /* Heap information */
137   heaplimit = ((struct mdesc *)heap1)->heaplimit;
138
139   s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
140
141   heapbase1 = (char *)heap1 + BLOCKSIZE;
142   heapbase2 = (char *)heap2 + BLOCKSIZE;
143
144   heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)s_heap)));
145   heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)s_heap)));
146
147   heapsize1 = heap1->heapsize;
148   heapsize2 = heap2->heapsize;
149
150   /* Start comparison */
151   size_t i1, i2, j1, j2, k, current_block, current_fragment;
152   void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
153   void *real_addr_block1, *real_addr_block2;
154   char *stack_name;
155
156   xbt_dynar_t previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
157
158   int equal, res_compare = 0;
159
160   /* Init equal information */
161   i1 = 1;
162
163   while(i1<=heaplimit){
164     if(heapinfo1[i1].type == 0){
165       heapinfo1[i1].busy_block.equal_to = NULL;
166     }
167     if(heapinfo1[i1].type > 0){
168       for(j1=0; j1 < (size_t) (BLOCKSIZE >> heapinfo1[i1].type); j1++){
169         heapinfo1[i1].busy_frag.equal_to[j1] = NULL;
170       }
171     }
172     i1++; 
173   }
174
175   i2 = 1;
176
177   while(i2<=heaplimit){
178     if(heapinfo2[i2].type == 0){
179       heapinfo2[i2].busy_block.equal_to = NULL;
180     }
181     if(heapinfo2[i2].type > 0){
182       for(j2=0; j2 < (size_t) (BLOCKSIZE >> heapinfo2[i2].type); j2++){
183         heapinfo2[i2].busy_frag.equal_to[j2] = NULL;
184       }
185     }
186     i2++; 
187   }
188
189   /* Init equal information */
190   i1 = 1;
191
192   while(i1<=heaplimit){
193     if(heapinfo1[i1].type == 0){
194       heapinfo1[i1].busy_block.equal_to = -1;
195     }
196     if(heapinfo1[i1].type > 0){
197       for(j1=0; j1 < MAX_FRAGMENT_PER_BLOCK; j1++){
198         heapinfo1[i1].busy_frag.equal_to[j1] = -1;
199       }
200     }
201     i1++; 
202   }
203
204   i2 = 1;
205
206   while(i2<=heaplimit){
207     if(heapinfo2[i2].type == 0){
208       heapinfo2[i2].busy_block.equal_to = -1;
209     }
210     if(heapinfo2[i2].type > 0){
211       for(j2=0; j2 < MAX_FRAGMENT_PER_BLOCK; j2++){
212         heapinfo2[i2].busy_frag.equal_to[j2] = -1;
213       }
214     }
215     i2++; 
216   }
217
218   /* Check busy blocks*/
219
220   i1 = 1;
221
222   while(i1 <= heaplimit){
223
224     current_block = i1;
225
226     if(heapinfo1[i1].type == -1){ /* Free block */
227       i1++;
228       continue;
229     }
230
231     addr_block1 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)heapbase1));
232     real_addr_block1 = (char*)((xbt_mheap_t)s_heap)->heapbase + (((char *)addr_block1) - (char *)heapbase1);
233
234     if(heapinfo1[i1].type == 0){  /* Large block */
235       
236       if((stack_name = is_stack(real_addr_block1)) != NULL){
237         stack_region_t stack = xbt_new0(s_stack_region_t, 1);
238         stack->address = addr_block1;
239         stack->process_name = strdup(stack_name);
240         stack->size = heapinfo1[i1].busy_block.busy_size;
241         xbt_dynar_push(*stack1, &stack);
242         res_compare = -1;
243       }
244
245       if(heapinfo1[i1].busy_block.busy_size == 0){
246         i1++;
247         continue;
248       }
249
250       if(heapinfo1[i1].busy_block.equal_to != NULL){
251         i1++;
252         continue;
253       }
254     
255       i2 = 1;
256       equal = 0;
257       res_compare = 0;
258   
259       /* Try first to associate to same block in the other heap */
260       if(heapinfo2[current_block].type == heapinfo1[current_block].type){
261
262         if(heapinfo2[current_block].busy_block.equal_to == NULL){  
263         
264           if(heapinfo1[current_block].busy_block.busy_size == heapinfo2[current_block].busy_block.busy_size){
265
266             addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)heapbase2));
267             real_addr_block2 = (char*)((xbt_mheap_t)s_heap)->heapbase + (((char *)addr_block2) - (char *)heapbase2);
268           
269             if((stack_name = is_stack(real_addr_block2)) != NULL){
270               stack_region_t stack = xbt_new0(s_stack_region_t, 1);
271               stack->address = addr_block2;
272               stack->process_name = strdup(stack_name);
273               stack->size = heapinfo2[current_block].busy_block.busy_size;
274               xbt_dynar_push(*stack2, &stack);
275               res_compare = -1;
276             }
277         
278             add_heap_area_pair(previous, current_block, -1, current_block, -1);
279         
280             if(res_compare != -1){
281               if(ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)){
282                 if(in_mc_comparison_ignore((int)current_block, -1))
283                   res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 1);
284                 else
285                   res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 0);
286               }else{
287                 res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 0);
288               }
289             }
290         
291             if(res_compare == 0 || res_compare == -1){
292               for(k=1; k < heapinfo2[current_block].busy_block.size; k++)
293                 heapinfo2[current_block+k].busy_block.equal_to = new_heap_area(i1, -1);
294               for(k=1; k < heapinfo1[current_block].busy_block.size; k++)
295                 heapinfo1[current_block+k].busy_block.equal_to = new_heap_area(i1, -1);
296               equal = 1;
297               match_equals(previous, equals);
298               i1 = i1 + heapinfo1[current_block].busy_block.size;
299             }
300         
301             xbt_dynar_reset(previous);
302         
303           }
304
305         }
306         
307       }
308
309       while(i2 <= heaplimit && !equal){
310
311         addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)heapbase2));        
312         real_addr_block2 = (char*)((xbt_mheap_t)s_heap)->heapbase + (((char *)addr_block2) - (char *)heapbase2);
313         
314         if((stack_name = is_stack(real_addr_block2)) != NULL){
315           stack_region_t stack = xbt_new0(s_stack_region_t, 1);
316           stack->address = addr_block2;
317           stack->process_name = strdup(stack_name);
318           stack->size = heapinfo2[i2].busy_block.busy_size;
319           xbt_dynar_push(*stack2, &stack);
320           res_compare = -1;
321         }
322            
323         if(i2 == current_block){
324           i2++;
325           continue;
326         }
327
328         if(heapinfo2[i2].type != 0){
329           i2++;
330           continue;
331         }
332
333         if(heapinfo2[i2].busy_block.equal_to != NULL){         
334           i2++;
335           continue;
336         }
337         
338         if(heapinfo1[i1].busy_block.size != heapinfo2[i2].busy_block.size){
339           i2++;
340           continue;
341         }
342         
343         if(heapinfo1[i1].busy_block.busy_size != heapinfo2[i2].busy_block.busy_size){
344           i2++;
345           continue;
346         }
347
348         /* Comparison */
349         add_heap_area_pair(previous, i1, -1, i2, -1);
350         
351         if(res_compare != -1){
352           if(ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)){
353             if(in_mc_comparison_ignore((int)i1, -1))
354               res_compare = compare_area(addr_block1, addr_block2, heapinfo1[i1].busy_block.busy_size, previous, 1);
355             else
356               res_compare = compare_area(addr_block1, addr_block2, heapinfo1[i1].busy_block.busy_size, previous, 0);
357           }else{
358             res_compare = compare_area(addr_block1, addr_block2, heapinfo1[i1].busy_block.busy_size, previous, 0);
359           }
360         }
361         
362         if(res_compare == 0 || res_compare == -1){
363           for(k=1; k < heapinfo2[i2].busy_block.size; k++)
364             heapinfo2[i2+k].busy_block.equal_to = new_heap_area(i1, -1);
365           for(k=1; k < heapinfo1[i1].busy_block.size; k++)
366             heapinfo1[i1+k].busy_block.equal_to = new_heap_area(i2, -1);
367           equal = 1;
368           match_equals(previous, equals);
369           i1 = i1 + heapinfo1[i1].busy_block.size;
370         }
371
372         xbt_dynar_reset(previous);
373
374         i2++;
375
376       }
377
378       if(!equal)
379         i1++;
380       
381     }else{ /* Fragmented block */
382
383       for(j1=0; j1 < (size_t) (BLOCKSIZE >> heapinfo1[i1].type); j1++){
384
385         current_fragment = j1;
386
387         if(heapinfo1[i1].busy_frag.frag_size[j1] == -1) /* Free fragment */
388           continue;
389
390         if(heapinfo1[i1].busy_frag.equal_to[j1] != NULL)
391           continue;
392
393         addr_frag1 = (void*) ((char *)addr_block1 + (j1 << heapinfo1[i1].type));
394
395         i2 = 1;
396         equal = 0;
397         
398         /* Try first to associate to same fragment in the other heap */
399         if(heapinfo2[current_block].type == heapinfo1[current_block].type){
400
401           if(heapinfo2[current_block].busy_frag.equal_to[current_fragment] == NULL){  
402           
403               if(heapinfo1[current_block].busy_frag.frag_size[current_fragment] == heapinfo2[current_block].busy_frag.frag_size[current_fragment]){
404
405                 addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)heapbase2));
406                 addr_frag2 = (void*) ((char *)addr_block2 + (current_fragment << heapinfo2[current_block].type));
407                
408                 add_heap_area_pair(previous, current_block, current_fragment, current_block, current_fragment);
409             
410                 if(ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)){
411                   if(in_mc_comparison_ignore((int)current_block, (int)current_fragment))
412                     res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 1);
413                   else
414                     res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 0);
415                 }else{
416                   res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 0);
417                 }
418
419                 if(res_compare == 0){
420                   equal = 1;
421                   match_equals(previous, equals);
422                 }
423             
424                 xbt_dynar_reset(previous);
425             
426               }
427
428             }
429
430         }
431
432         while(i2 <= heaplimit && !equal){
433
434           
435           if(heapinfo2[i2].type <= 0){
436             i2++;
437             continue;
438           }
439
440           for(j2=0; j2 < (size_t) (BLOCKSIZE >> heapinfo2[i2].type); j2++){
441
442             if(heapinfo2[i2].type == heapinfo1[i1].type && i2 == current_block && j2 == current_fragment)
443               continue;
444
445             if(heapinfo2[i2].busy_frag.equal_to[j2] != NULL)                
446               continue;              
447              
448             if(heapinfo1[i1].busy_frag.frag_size[j1] != heapinfo2[i2].busy_frag.frag_size[j2]) /* Different size_used */    
449               continue;
450              
451             addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)heapbase2));
452             addr_frag2 = (void*) ((char *)addr_block2 + (j2 << heapinfo2[i2].type));
453              
454             /* Comparison */
455             add_heap_area_pair(previous, i1, j1, i2, j2);
456             
457             if(ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)){
458               if(in_mc_comparison_ignore((int)i1, (int)j1))
459                 res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[i1].busy_frag.frag_size[j1], previous, 1);
460               else
461                 res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[i1].busy_frag.frag_size[j1], previous, 0);
462             }else{
463               res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[i1].busy_frag.frag_size[j1], previous, 0);
464             }
465
466             if(res_compare == 0){
467               equal = 1;
468               match_equals(previous, equals);
469               break;
470             }
471
472             xbt_dynar_reset(previous);
473
474           }
475
476           i2++;
477
478         }
479
480       }
481
482       i1++;
483       
484     }
485
486   }
487
488   /* All blocks/fragments are equal to another block/fragment ? */
489   size_t i = 1, j = 0;
490   int nb_diff1 = 0, nb_diff2 = 0;
491  
492   while(i<heaplimit){
493     if(heapinfo1[i].type == 0){
494       if(heapinfo1[i].busy_block.busy_size > 0){
495         if(heapinfo1[i].busy_block.equal_to == NULL){
496           if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
497             addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
498             XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block1, heapinfo1[i].busy_block.busy_size);
499             mmalloc_backtrace_block_display((void*)heapinfo1, i);
500           }
501           nb_diff1++;
502         }else{
503           xbt_free(heapinfo1[i].busy_block.equal_to);
504         }
505       }
506     }
507     if(heapinfo1[i].type > 0){
508       addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
509       for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
510         if(heapinfo1[i].busy_frag.frag_size[j] > 0){
511           if(heapinfo1[i].busy_frag.equal_to[j] == NULL){
512             if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
513               addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
514               XBT_DEBUG("Block %zu, Fragment %zu (%p) not found (size used = %d)", i, j, addr_frag1, heapinfo1[i].busy_frag.frag_size[j]);
515               mmalloc_backtrace_fragment_display((void*)heapinfo1, i, j);
516             }
517             nb_diff1++;
518           }else{
519             xbt_free(heapinfo1[i].busy_frag.equal_to[j]);
520           }
521         }
522       }
523     }
524     
525     i++; 
526   }
527
528   XBT_DEBUG("Different blocks or fragments in heap1 : %d", nb_diff1);
529
530   i = 1;
531
532   while(i<heaplimit){
533     if(heapinfo2[i].type == 0){
534       if(heapinfo2[i].busy_block.busy_size > 0){
535         if(heapinfo2[i].busy_block.equal_to == NULL){
536           if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
537             addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
538             XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block2, heapinfo2[i].busy_block.busy_size);
539             mmalloc_backtrace_block_display((void*)heapinfo2, i);
540           }
541           nb_diff2++;
542         }else{
543           xbt_free(heapinfo2[i].busy_block.equal_to);
544         }
545       }
546     }
547     if(heapinfo2[i].type > 0){
548       addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
549       for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo2[i].type); j++){
550         if(heapinfo2[i].busy_frag.frag_size[j] > 0){
551           if(heapinfo2[i].busy_frag.equal_to[j] == NULL){
552             if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
553               addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
554               XBT_DEBUG( "Block %zu, Fragment %zu (%p) not found (size used = %d)", i, j, addr_frag2, heapinfo2[i].busy_frag.frag_size[j]);
555               mmalloc_backtrace_fragment_display((void*)heapinfo2, i, j);
556             }
557             nb_diff2++;
558           }else{
559             xbt_free(heapinfo2[i].busy_frag.equal_to[j]);
560           }
561         }
562       }
563     }
564     i++; 
565   }
566
567   XBT_DEBUG("Different blocks or fragments in heap2 : %d", nb_diff2);
568
569   xbt_dynar_free(&previous);
570   ignore_done = 0;
571   s_heap = NULL, heapbase1 = NULL, heapbase2 = NULL;
572   heapinfo1 = NULL, heapinfo2 = NULL;
573   heaplimit = 0, heapsize1 = 0, heapsize2 = 0;
574
575   return ((nb_diff1 > 0) || (nb_diff2 > 0));
576 }
577
578 static heap_area_t new_heap_area(int block, int fragment){
579   heap_area_t area = NULL;
580   area = xbt_new0(s_heap_area_t, 1);
581   area->block = block;
582   area->fragment = fragment;
583   return area;
584 }
585
586 static int in_mc_comparison_ignore(int block, int fragment){
587
588   unsigned int cursor = 0;
589   int start = 0;
590   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
591   mc_heap_ignore_region_t region;
592
593   while(start <= end){
594     cursor = (start + end) / 2;
595     region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
596     if(region->block == block){
597       if(region->fragment == fragment)
598         return 1;
599       if(region->fragment < fragment)
600         start = cursor + 1;
601       if(region->fragment > fragment)
602         end = cursor - 1;
603     }
604     if(region->block < block)
605       start = cursor + 1;
606     if(region->block > block)
607       end = cursor - 1; 
608   }
609
610   return 0;
611 }
612
613 static size_t heap_comparison_ignore_size(void *address){
614   unsigned int cursor = 0;
615   int start = 0;
616   int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
617   mc_heap_ignore_region_t region;
618
619   while(start <= end){
620     cursor = (start + end) / 2;
621     region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
622     if(region->address == address)
623       return region->size;
624     if(region->address < address)
625       start = cursor + 1;
626     if(region->address > address)
627       end = cursor - 1;   
628   }
629
630   return 0;
631 }
632
633
634 static int compare_area(void *area1, void* area2, size_t size, xbt_dynar_t previous, int check_ignore){
635
636   size_t i = 0, pointer_align = 0, ignore1 = 0, ignore2 = 0;
637   void *address_pointed1, *address_pointed2, *addr_block_pointed1, *addr_block_pointed2, *addr_frag_pointed1, *addr_frag_pointed2;
638   size_t block_pointed1, block_pointed2, frag_pointed1, frag_pointed2;
639   int res_compare;
640   void *current_area1, *current_area2;
641  
642   while(i<size){
643
644     if(check_ignore){
645
646       current_area1 = (char*)((xbt_mheap_t)s_heap)->heapbase + ((((char *)area1) + i) - (char *)heapbase1);
647       if((ignore1 = heap_comparison_ignore_size(current_area1)) > 0){
648         current_area2 = (char*)((xbt_mheap_t)s_heap)->heapbase + ((((char *)area2) + i) - (char *)heapbase2);
649         if((ignore2 = heap_comparison_ignore_size(current_area2))  == ignore1){
650           i = i + ignore2;
651           ignore_done++;
652           continue;
653         }
654       }
655
656     }
657    
658     if(memcmp(((char *)area1) + i, ((char *)area2) + i, 1) != 0){
659
660       /* Check pointer difference */
661       pointer_align = (i / sizeof(void*)) * sizeof(void*);
662       address_pointed1 = *((void **)((char *)area1 + pointer_align));
663       address_pointed2 = *((void **)((char *)area2 + pointer_align));
664
665       /* Get pointed blocks number */ 
666       block_pointed1 = ((char*)address_pointed1 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
667       block_pointed2 = ((char*)address_pointed2 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
668
669       /* Check if valid blocks number */
670       if((char *)address_pointed1 < (char*)((xbt_mheap_t)s_heap)->heapbase || block_pointed1 > heapsize1 || block_pointed1 < 1 || (char *)address_pointed2 < (char*)((xbt_mheap_t)s_heap)->heapbase || block_pointed2 > heapsize2 || block_pointed2 < 1)
671         return 1;
672
673       if(heapinfo1[block_pointed1].type == heapinfo2[block_pointed2].type){ /* Same type of block (large or fragmented) */
674
675         addr_block_pointed1 = ((void*) (((ADDR2UINT(block_pointed1)) - 1) * BLOCKSIZE + (char*)heapbase1));
676         addr_block_pointed2 = ((void*) (((ADDR2UINT(block_pointed2)) - 1) * BLOCKSIZE + (char*)heapbase2));
677         
678         if(heapinfo1[block_pointed1].type == 0){ /* Large block */
679
680           if(heapinfo1[block_pointed1].busy_block.size != heapinfo2[block_pointed2].busy_block.size){
681             return 1;
682           }
683
684           if(heapinfo1[block_pointed1].busy_block.busy_size != heapinfo2[block_pointed2].busy_block.busy_size){
685             return 1;
686           }
687
688           if(add_heap_area_pair(previous, block_pointed1, -1, block_pointed2, -1)){
689
690             if(ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)){
691               if(in_mc_comparison_ignore(block_pointed1, -1))
692                 res_compare = compare_area(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size, previous, 1);
693               else
694                 res_compare = compare_area(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size, previous, 0);
695             }else{
696               res_compare = compare_area(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size, previous, 0);
697             }
698             
699             if(res_compare == 1)    
700               return 1;
701            
702           }
703           
704         }else{ /* Fragmented block */
705
706           /* Get pointed fragments number */ 
707           frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> heapinfo1[block_pointed1].type;
708           frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> heapinfo2[block_pointed2].type;
709          
710           if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] != heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]) /* Different size_used */    
711             return 1;
712             
713           addr_frag_pointed1 = (void*) ((char *)addr_block_pointed1 + (frag_pointed1 << heapinfo1[block_pointed1].type));
714           addr_frag_pointed2 = (void*) ((char *)addr_block_pointed2 + (frag_pointed2 << heapinfo2[block_pointed2].type));
715
716           if(add_heap_area_pair(previous, block_pointed1, frag_pointed1, block_pointed2, frag_pointed2)){
717
718             if(ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)){
719               if(in_mc_comparison_ignore(block_pointed1, frag_pointed1))
720                 res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 1);
721               else
722                 res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 0);
723             }else{
724               res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 0);
725             }
726
727             if(res_compare == 1)
728               return 1;
729            
730           }
731           
732         }
733           
734       }else{
735
736         if((heapinfo1[block_pointed1].type > 0) && (heapinfo2[block_pointed2].type > 0)){
737           
738           addr_block_pointed1 = ((void*) (((ADDR2UINT(block_pointed1)) - 1) * BLOCKSIZE + (char*)heapbase1));
739           addr_block_pointed2 = ((void*) (((ADDR2UINT(block_pointed2)) - 1) * BLOCKSIZE + (char*)heapbase2));
740        
741           frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> heapinfo1[block_pointed1].type;
742           frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> heapinfo2[block_pointed2].type;
743
744           if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] != heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]) /* Different size_used */  
745             return 1;
746
747           addr_frag_pointed1 = (void*) ((char *)addr_block_pointed1 + (frag_pointed1 << heapinfo1[block_pointed1].type));
748           addr_frag_pointed2 = (void*) ((char *)addr_block_pointed2 + (frag_pointed2 << heapinfo2[block_pointed2].type));
749
750           if(add_heap_area_pair(previous, block_pointed1, frag_pointed1, block_pointed2, frag_pointed2)){
751
752             if(ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)){
753               if(in_mc_comparison_ignore(block_pointed1, frag_pointed1))
754                 res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 1);
755               else
756                 res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 0);
757             }else{
758               res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 0);
759             }
760             
761             if(res_compare == 1)
762               return 1;
763            
764           }
765
766         }else{
767           return 1;
768         }
769
770       }
771
772       i = pointer_align + sizeof(void *);
773       
774     }else{
775
776       i++;
777
778     }
779   }
780
781   return 0;
782   
783
784 }
785
786 static void heap_area_pair_free(heap_area_pair_t pair){
787   if (pair){
788     free(pair);
789     pair = NULL;
790   }
791 }
792
793 static void heap_area_pair_free_voidp(void *d)
794 {
795   heap_area_pair_free((heap_area_pair_t) * (void **) d);
796 }
797
798 static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2){
799
800   if(is_new_heap_area_pair(list, block1, fragment1, block2, fragment2)){
801     heap_area_pair_t pair = NULL;
802     pair = xbt_new0(s_heap_area_pair_t, 1);
803     pair->block1 = block1;
804     pair->fragment1 = fragment1;
805     pair->block2 = block2;
806     pair->fragment2 = fragment2;
807     
808     xbt_dynar_push(list, &pair); 
809
810     return 1;
811   }
812
813   return 0;
814 }
815  
816 static int is_new_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2){
817   
818   unsigned int cursor = 0;
819   heap_area_pair_t current_pair;
820
821   xbt_dynar_foreach(list, cursor, current_pair){
822     if(current_pair->block1 == block1 && current_pair->block2 == block2 && current_pair->fragment1 == fragment1 && current_pair->fragment2 == fragment2)
823       return 0; 
824   }
825   
826   return 1;
827 }
828
829 static void match_equals(xbt_dynar_t list, xbt_dynar_t *equals){
830
831   unsigned int cursor = 0;
832   heap_area_pair_t current_pair;
833   heap_area_t previous_area;
834
835   void *real_addr_block1, *real_addr_block2, *real_addr_frag1, *real_addr_frag2;
836
837   xbt_dynar_foreach(list, cursor, current_pair){
838
839     if(current_pair->fragment1 != -1){
840
841       real_addr_block1 = ((void*) (((ADDR2UINT((size_t)current_pair->block1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
842       real_addr_frag1 = (void*) ((char *)real_addr_block1 + (current_pair->fragment1 << heapinfo1[current_pair->block1].type));
843       real_addr_block2 = ((void*) (((ADDR2UINT((size_t)current_pair->block2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
844       real_addr_frag2 = (void*) ((char *)real_addr_block2 + (current_pair->fragment2 << heapinfo2[current_pair->block2].type));
845
846       if(heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1] != NULL){    
847         remove_heap_equality(equals, 1, real_addr_frag1);
848         previous_area = heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1];
849         xbt_free( heapinfo2[previous_area->block].busy_frag.equal_to[previous_area->fragment]);
850         heapinfo2[previous_area->block].busy_frag.equal_to[previous_area->fragment] = NULL;
851         xbt_free(heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1]); 
852       }
853       if(heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2] != NULL){        
854         remove_heap_equality(equals, 2, real_addr_frag2); 
855         previous_area = heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2];
856         xbt_free(heapinfo1[previous_area->block].busy_frag.equal_to[previous_area->fragment]);
857         heapinfo1[previous_area->block].busy_frag.equal_to[previous_area->fragment] = NULL;
858         xbt_free(heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2]);
859       }
860       
861       if(real_addr_frag1 != real_addr_frag2)
862         add_heap_equality(equals, real_addr_frag1, real_addr_frag2);
863
864       heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1] = new_heap_area(current_pair->block2, current_pair->fragment2);
865       heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2] = new_heap_area(current_pair->block1, current_pair->fragment1);
866
867     }else{
868
869       real_addr_block1 = ((void*) (((ADDR2UINT((size_t)current_pair->block1)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
870       real_addr_block2 = ((void*) (((ADDR2UINT((size_t)current_pair->block2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
871
872       if(heapinfo1[current_pair->block1].busy_block.equal_to != NULL){
873         remove_heap_equality(equals, 1, real_addr_block1);
874         previous_area = heapinfo1[current_pair->block1].busy_block.equal_to;
875         xbt_free(heapinfo2[previous_area->block].busy_block.equal_to);
876         heapinfo2[previous_area->block].busy_block.equal_to = NULL; 
877         xbt_free(heapinfo1[current_pair->block1].busy_block.equal_to);
878       }
879       if(heapinfo2[current_pair->block2].busy_block.equal_to != NULL){
880         remove_heap_equality(equals, 2, real_addr_block2);
881         previous_area = heapinfo2[current_pair->block2].busy_block.equal_to;
882         xbt_free(heapinfo1[previous_area->block].busy_block.equal_to);
883         heapinfo1[previous_area->block].busy_block.equal_to = NULL;
884         xbt_free(heapinfo2[current_pair->block2].busy_block.equal_to);
885       }
886       
887       if(real_addr_block1 != real_addr_block2)
888         add_heap_equality(equals, real_addr_block1, real_addr_block2);
889
890       heapinfo1[current_pair->block1].busy_block.equal_to = new_heap_area(current_pair->block2, current_pair->fragment2);
891       heapinfo2[current_pair->block2].busy_block.equal_to = new_heap_area(current_pair->block1, current_pair->fragment1);
892
893     }
894   }
895
896
897 }
898
899 #ifndef max
900 #define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
901 #endif
902
903 int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
904
905   if(heap1 == NULL && heap1 == NULL){
906     XBT_DEBUG("Malloc descriptors null");
907     return 0;
908   }
909
910   if(heap1->heaplimit != heap2->heaplimit){
911     XBT_DEBUG("Different limit of valid info table indices");
912     return 1;
913   }
914
915   /* Heap information */
916   heaplimit = ((struct mdesc *)heap1)->heaplimit;
917
918   s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
919
920   heapbase1 = (char *)heap1 + BLOCKSIZE;
921   heapbase2 = (char *)heap2 + BLOCKSIZE;
922
923   heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)s_heap)));
924   heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)s_heap)));
925
926   heapsize1 = heap1->heapsize;
927   heapsize2 = heap2->heapsize;
928
929   /* Start comparison */
930   size_t i, j, k;
931   void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
932
933   int distance = 0;
934
935   /* Check busy blocks*/
936
937   i = 1;
938
939   while(i <= heaplimit){
940
941     addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
942     addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
943
944     if(heapinfo1[i].type != heapinfo2[i].type){
945   
946       distance += BLOCKSIZE;
947       XBT_DEBUG("Different type of blocks (%zu) : %d - %d -> distance = %d", i, heapinfo1[i].type, heapinfo2[i].type, distance);
948       i++;
949     
950     }else{
951
952       if(heapinfo1[i].type == -1){ /* Free block */
953         i++;
954         continue;
955       }
956
957       if(heapinfo1[i].type == 0){ /* Large block */
958        
959         if(heapinfo1[i].busy_block.size != heapinfo2[i].busy_block.size){
960           distance += BLOCKSIZE * max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
961           i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
962           XBT_DEBUG("Different larger of cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size, distance);
963           continue;
964         }
965
966         /*if(heapinfo1[i].busy_block.busy_size != heapinfo2[i].busy_block.busy_size){
967           distance += max(heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size);
968           i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
969           XBT_DEBUG("Different size used oin large cluster at block %zu : %zu - %zu -> distance = %d", i, heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size, distance);
970           continue;
971           }*/
972
973         k = 0;
974
975         //while(k < (heapinfo1[i].busy_block.busy_size)){
976         while(k < heapinfo1[i].busy_block.size * BLOCKSIZE){
977           if(memcmp((char *)addr_block1 + k, (char *)addr_block2 + k, 1) != 0){
978             distance ++;
979           }
980           k++;
981         } 
982
983         i++;
984
985       }else { /* Fragmented block */
986
987         for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
988
989           addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
990           addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
991
992           if(heapinfo1[i].busy_frag.frag_size[j] == 0 && heapinfo2[i].busy_frag.frag_size[j] == 0){
993             continue;
994           }
995           
996           
997           /*if(heapinfo1[i].busy_frag.frag_size[j] != heapinfo2[i].busy_frag.frag_size[j]){
998             distance += max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j]);
999             XBT_DEBUG("Different size used in fragment %zu in block %zu : %d - %d -> distance = %d", j, i, heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j], distance); 
1000             continue;
1001             }*/
1002    
1003           k=0;
1004
1005           //while(k < max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j])){
1006           while(k < (BLOCKSIZE / (BLOCKSIZE >> heapinfo1[i].type))){
1007             if(memcmp((char *)addr_frag1 + k, (char *)addr_frag2 + k, 1) != 0){
1008               distance ++;
1009             }
1010             k++;
1011           }
1012
1013         }
1014
1015         i++;
1016
1017       }
1018       
1019     }
1020
1021   }
1022
1023   return distance;
1024   
1025 }
1026
1027 static char * is_stack(void *address){
1028   unsigned int cursor = 0;
1029   stack_region_t stack;
1030
1031   xbt_dynar_foreach(stacks_areas, cursor, stack){
1032     if(address == stack->address)
1033       return stack->process_name;
1034   }
1035
1036   return NULL;
1037 }
1038
1039 static void add_heap_equality(xbt_dynar_t *equals, void *a1, void *a2){
1040   
1041   if(xbt_dynar_is_empty(*equals)){
1042
1043     heap_equality_t he = xbt_new0(s_heap_equality_t, 1);
1044     he->address1 = a1;
1045     he->address2 = a2;
1046
1047     xbt_dynar_insert_at(*equals, 0, &he);
1048   
1049   }else{
1050
1051     unsigned int cursor = 0;
1052     int start = 0;
1053     int end = xbt_dynar_length(*equals) - 1;
1054     heap_equality_t current_equality = NULL;
1055
1056     while(start <= end){
1057       cursor = (start + end) / 2;
1058       current_equality = (heap_equality_t)xbt_dynar_get_as(*equals, cursor, heap_equality_t);
1059       if(current_equality->address1 == a1){
1060         if(current_equality->address2 == a2)
1061           return;
1062         if(current_equality->address2 < a2)
1063           start = cursor + 1;
1064         if(current_equality->address2 > a2)
1065           end = cursor - 1;
1066       }
1067       if(current_equality->address1 < a1)
1068         start = cursor + 1;
1069       if(current_equality->address1 > a1)
1070         end = cursor - 1; 
1071     }
1072
1073     heap_equality_t he = xbt_new0(s_heap_equality_t, 1);
1074     he->address1 = a1;
1075     he->address2 = a2;
1076   
1077     if(current_equality->address1 < a1)
1078       xbt_dynar_insert_at(*equals, cursor + 1 , &he);
1079     else
1080        xbt_dynar_insert_at(*equals, cursor, &he); 
1081
1082   }
1083
1084 }
1085
1086 static void remove_heap_equality(xbt_dynar_t *equals, int address, void *a){
1087   
1088   unsigned int cursor = 0;
1089   heap_equality_t current_equality;
1090   int found = 0;
1091
1092   if(address == 1){
1093
1094     int start = 0;
1095     int end = xbt_dynar_length(*equals) - 1;
1096
1097
1098     while(start <= end && found == 0){
1099       cursor = (start + end) / 2;
1100       current_equality = (heap_equality_t)xbt_dynar_get_as(*equals, cursor, heap_equality_t);
1101       if(current_equality->address1 == a)
1102         found = 1;
1103       if(current_equality->address1 < a)
1104         start = cursor + 1;
1105       if(current_equality->address1 > a)
1106         end = cursor - 1; 
1107     }
1108
1109     if(found == 1)
1110       xbt_dynar_remove_at(*equals, cursor, NULL);
1111   
1112   }else{
1113
1114     xbt_dynar_foreach(*equals, cursor, current_equality){
1115       if(current_equality->address2 == a){
1116         found = 1;
1117         break;
1118       }
1119     }
1120
1121     if(found == 1)
1122       xbt_dynar_remove_at(*equals, cursor, NULL);
1123
1124   }
1125
1126   
1127 }
1128
1129 int is_free_area(void *area, xbt_mheap_t heap){
1130
1131   void *sheap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
1132   malloc_info *heapinfo = (malloc_info *)((char *)heap + ((uintptr_t)((char *)heap->heapinfo - (char *)sheap)));
1133   size_t heapsize = heap->heapsize;
1134
1135   /* Get block number */ 
1136   size_t block = ((char*)area - (char*)((xbt_mheap_t)sheap)->heapbase) / BLOCKSIZE + 1;
1137   size_t fragment;
1138
1139   /* Check if valid block number */
1140   if((char *)area < (char*)((xbt_mheap_t)sheap)->heapbase || block > heapsize || block < 1)
1141     return 0;
1142
1143   if(heapinfo[block].type < 0)
1144     return 1;
1145
1146   if(heapinfo[block].type == 0)
1147     return 0;
1148
1149   if(heapinfo[block].type > 0){
1150     fragment = ((uintptr_t) (ADDR2UINT(area) % (BLOCKSIZE))) >> heapinfo[block].type;
1151     if(heapinfo[block].busy_frag.frag_size[fragment] == 0)
1152       return 1;  
1153   }
1154
1155   return 0;
1156   
1157
1158
1159 }