heapsize2 = heap2->heapsize;
/* Start comparison */
- size_t i1, i2, j1, j2, k;
+ size_t i1, i2, j1, j2, k, current_block, current_fragment;
void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
xbt_dynar_t previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
i1 = 1;
- while(i1 < heaplimit){
+ while(i1 <= heaplimit){
- i2 = 1;
- equal = 0;
+ current_block = i1;
if(heapinfo1[i1].type == -1){ /* Free block */
i1++;
if(heapinfo1[i1].type == 0){ /* Large block */
+ if(heapinfo1[i1].busy_block.busy_size == 0){
+ i1++;
+ continue;
+ }
+
+ i2 = 1;
+ equal = 0;
+
+ /* Try first to associate to same block in the other heap */
+ if(heapinfo2[current_block].type == heapinfo1[current_block].type){
+
+ if(heapinfo1[current_block].busy_block.busy_size == heapinfo2[current_block].busy_block.busy_size){
+
+ addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)heapbase2));
+
+ add_heap_area_pair(previous, current_block, -1, current_block, -1);
+
+ if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+ if(in_mmalloc_ignore((int)current_block, -1))
+ res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 1);
+ else
+ res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 0);
+ }else{
+ res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 0);
+ }
+
+ if(res_compare == 0){
+ for(k=1; k < heapinfo2[current_block].busy_block.size; k++)
+ heapinfo2[current_block+k].busy_block.equal_to = 1 ;
+ for(k=1; k < heapinfo1[current_block].busy_block.size; k++)
+ heapinfo1[current_block+k].busy_block.equal_to = 1 ;
+ equal = 1;
+ match_equals(previous);
+ i1 = i1 + heapinfo1[i1].busy_block.size;
+ }
+
+ xbt_dynar_reset(previous);
+
+ }
+
+ }
+
while(i2 <= heaplimit && !equal){
+ if(i2 == current_block){
+ i2++;
+ continue;
+ }
+
if(heapinfo2[i2].type != 0){
i2++;
continue;
}
+ if(!equal)
+ i1++;
+
}else{ /* Fragmented block */
for(j1=0; j1 < (size_t) (BLOCKSIZE >> heapinfo1[i1].type); j1++){
+ current_fragment = j1;
+
if(heapinfo1[i1].busy_frag.frag_size[j1] == 0) /* Free fragment */
continue;
addr_frag1 = (void*) ((char *)addr_block1 + (j1 << heapinfo1[i1].type));
-
+
i2 = 1;
equal = 0;
+ /* Try first to associate to same fragment in the other heap */
+ if(heapinfo2[current_block].type == heapinfo1[current_block].type){
+
+ if(heapinfo1[current_block].busy_frag.frag_size[current_fragment] == heapinfo2[current_block].busy_frag.frag_size[current_fragment]){
+
+ addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)heapbase2));
+ addr_frag2 = (void*) ((char *)addr_block2 + (current_fragment << heapinfo2[current_block].type));
+
+ add_heap_area_pair(previous, current_block, current_fragment, current_block, current_fragment);
+
+ if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+ if(in_mmalloc_ignore((int)current_block, (int)current_fragment))
+ res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 1);
+ else
+ res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 0);
+ }else{
+ res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 0);
+ }
+
+ if(res_compare == 0){
+ equal = 1;
+ match_equals(previous);
+ }
+
+ xbt_dynar_reset(previous);
+
+ }
+
+ }
+
+
while(i2 <= heaplimit && !equal){
if(heapinfo2[i2].type <= 0){
for(j2=0; j2 < (size_t) (BLOCKSIZE >> heapinfo2[i2].type); j2++){
- if(heapinfo2[i2].busy_frag.equal_to[j2] == 1){
+ if(heapinfo2[i2].type == heapinfo1[i1].type && i2 == current_block && j2 == current_fragment)
+ continue;
+
+ if(heapinfo2[i2].busy_frag.equal_to[j2] == 1)
continue;
- }
- if(heapinfo1[i1].busy_frag.frag_size[j1] != heapinfo2[i2].busy_frag.frag_size[j2]){ /* Different size_used */
+ if(heapinfo1[i1].busy_frag.frag_size[j1] != heapinfo2[i2].busy_frag.frag_size[j2]) /* Different size_used */
continue;
- }
addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)heapbase2));
addr_frag2 = (void*) ((char *)addr_block2 + (j2 << heapinfo2[i2].type));
}
+ i1++;
+
}
- i1++;
-
}
/* All blocks/fragments are equal to another block/fragment ? */
}else{ /* Fragmented block */
- /* Get pointed fragments number */
+ /* Get pointed fragments number */
frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> heapinfo1[block_pointed1].type;
frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> heapinfo2[block_pointed2].type;
}
+#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;
+
+}
+