+#ifndef max
+#define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
+#endif
+
+int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
+
+ if(heap1 == NULL && heap1 == NULL){
+ XBT_DEBUG("Malloc descriptors null");
+ return 0;
+ }
+
+ if(heap1->heaplimit != heap2->heaplimit){
+ XBT_DEBUG("Different limit of valid info table indices");
+ return 1;
+ }
+
+ /* Heap information */
+ heaplimit = ((struct mdesc *)heap1)->heaplimit;
+
+ s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
+
+ heapbase1 = (char *)heap1 + BLOCKSIZE;
+ heapbase2 = (char *)heap2 + BLOCKSIZE;
+
+ heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)s_heap)));
+ heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)s_heap)));
+
+ heapsize1 = heap1->heapsize;
+ heapsize2 = heap2->heapsize;
+
+ /* Start comparison */
+ size_t i, j, k;
+ void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
+
+ int distance = 0;
+
+ /* Check busy blocks*/
+
+ i = 1;
+
+ while(i <= heaplimit){
+
+ addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
+ addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
+
+ if(heapinfo1[i].type != heapinfo2[i].type){
+
+ distance += BLOCKSIZE;
+ XBT_DEBUG("Different type of blocks (%zu) : %d - %d -> distance = %d", i, heapinfo1[i].type, heapinfo2[i].type, distance);
+ i++;
+
+ }else{
+
+ if(heapinfo1[i].type == -1){ /* Free block */
+ i++;
+ continue;
+ }
+
+ if(heapinfo1[i].type == 0){ /* Large block */
+
+ if(heapinfo1[i].busy_block.size != heapinfo2[i].busy_block.size){
+ distance += BLOCKSIZE * max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
+ i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
+ 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);
+ continue;
+ }
+
+ /*if(heapinfo1[i].busy_block.busy_size != heapinfo2[i].busy_block.busy_size){
+ distance += max(heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size);
+ i += max(heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size);
+ 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);
+ continue;
+ }*/
+
+ k = 0;
+
+ //while(k < (heapinfo1[i].busy_block.busy_size)){
+ while(k < heapinfo1[i].busy_block.size * BLOCKSIZE){
+ if(memcmp((char *)addr_block1 + k, (char *)addr_block2 + k, 1) != 0){
+ distance ++;
+ }
+ k++;
+ }
+
+ i++;
+
+ }else { /* Fragmented block */
+
+ for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
+
+ addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
+ addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
+
+ if(heapinfo1[i].busy_frag.frag_size[j] == 0 && heapinfo2[i].busy_frag.frag_size[j] == 0){
+ continue;
+ }
+
+
+ /*if(heapinfo1[i].busy_frag.frag_size[j] != heapinfo2[i].busy_frag.frag_size[j]){
+ distance += max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j]);
+ 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);
+ continue;
+ }*/
+
+ k=0;
+
+ //while(k < max(heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j])){
+ while(k < (BLOCKSIZE / (BLOCKSIZE >> heapinfo1[i].type))){
+ if(memcmp((char *)addr_frag1 + k, (char *)addr_frag2 + k, 1) != 0){
+ distance ++;
+ }
+ k++;
+ }
+
+ }
+
+ i++;
+
+ }
+
+ }
+
+ }
+
+ return distance;
+
+}
+
+static char* is_stack(void *address){
+ unsigned int cursor = 0;
+ stack_region_t stack;
+
+ xbt_dynar_foreach(stacks_areas, cursor, stack){
+ if(address == stack->address)
+ return stack->process_name;
+ }
+
+ return NULL;
+}
+
+static void add_heap_equality(xbt_dynar_t equals, void *a1, void *a2){
+
+ if(xbt_dynar_is_empty(equals)){
+
+ heap_equality_t he = xbt_new0(s_heap_equality_t, 1);
+ he->address1 = a1;
+ he->address2 = a2;
+
+ xbt_dynar_insert_at(equals, 0, &he);
+
+ }else{
+
+ unsigned int cursor = 0;
+ int start = 0;
+ int end = xbt_dynar_length(equals) - 1;
+ heap_equality_t current_equality = NULL;
+
+ while(start <= end){
+ cursor = (start + end) / 2;
+ current_equality = (heap_equality_t)xbt_dynar_get_as(equals, cursor, heap_equality_t);
+ if(current_equality->address1 == a1){
+ if(current_equality->address2 == a2)
+ return;
+ if(current_equality->address2 < a2)
+ start = cursor + 1;
+ if(current_equality->address2 > a2)
+ end = cursor - 1;
+ }
+ if(current_equality->address1 < a1)
+ start = cursor + 1;
+ if(current_equality->address1 > a1)
+ end = cursor - 1;
+ }
+
+ heap_equality_t he = xbt_new0(s_heap_equality_t, 1);
+ he->address1 = a1;
+ he->address2 = a2;
+
+ if(current_equality->address1 < a1)
+ xbt_dynar_insert_at(equals, cursor + 1 , &he);
+ else
+ xbt_dynar_insert_at(equals, cursor, &he);
+
+ }
+
+}
+
+static void remove_heap_equality(xbt_dynar_t equals, int address, void *a){
+
+ unsigned int cursor = 0;
+ heap_equality_t current_equality;
+ int found = 0;
+
+ if(address == 1){
+
+ int start = 0;
+ int end = xbt_dynar_length(equals) - 1;
+
+
+ while(start <= end && found == 0){
+ cursor = (start + end) / 2;
+ current_equality = (heap_equality_t)xbt_dynar_get_as(equals, cursor, heap_equality_t);
+ if(current_equality->address1 == a)
+ found = 1;
+ if(current_equality->address1 < a)
+ start = cursor + 1;
+ if(current_equality->address1 > a)
+ end = cursor - 1;
+ }
+
+ if(found == 1)
+ xbt_dynar_remove_at(equals, cursor, NULL);
+
+ }else{
+
+ xbt_dynar_foreach(equals, cursor, current_equality){
+ if(current_equality->address2 == a){
+ found = 1;
+ break;
+ }
+ }
+
+ if(found == 1)
+ xbt_dynar_remove_at(equals, cursor, NULL);
+
+ }
+
+}
+
+int is_free_area(void *area, xbt_mheap_t heap){
+
+ void *sheap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
+ malloc_info *heapinfo = (malloc_info *)((char *)heap + ((uintptr_t)((char *)heap->heapinfo - (char *)sheap)));
+ size_t heapsize = heap->heapsize;
+
+ /* Get block number */
+ size_t block = ((char*)area - (char*)((xbt_mheap_t)sheap)->heapbase) / BLOCKSIZE + 1;
+ size_t fragment;
+
+ /* Check if valid block number */
+ if((char *)area < (char*)((xbt_mheap_t)sheap)->heapbase || block > heapsize || block < 1)
+ return 0;
+
+ if(heapinfo[block].type < 0)
+ return 1;
+
+ if(heapinfo[block].type == 0)
+ return 0;
+
+ if(heapinfo[block].type > 0){
+ fragment = ((uintptr_t) (ADDR2UINT(area) % (BLOCKSIZE))) >> heapinfo[block].type;
+ if(heapinfo[block].busy_frag.frag_size[fragment] == 0)
+ return 1;
+ }
+
+ return 0;
+
+
+
+}