Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Merge add_compared_pointers and already_compared_pointers into add_compared_pointers
[simgrid.git] / src / mc / mc_compare.c
index bfa1332..3e6fa29 100644 (file)
@@ -45,38 +45,12 @@ static void pointers_pair_free_voidp(void *p){
 /************************** Snapshot comparison *******************************/
 /******************************************************************************/
 
-static int already_compared_pointers(void *p1, void *p2){
-
-  if(xbt_dynar_is_empty(compared_pointers))
-    return -1;
-
-  unsigned int cursor = 0;
-  int start = 0;
-  int end = xbt_dynar_length(compared_pointers) - 1;
-  pointers_pair_t pair;
-
-  while(start <= end){
-    cursor = (start + end) / 2;
-    pair = (pointers_pair_t)xbt_dynar_get_as(compared_pointers, cursor, pointers_pair_t);
-    if(pair->p1 == p1){
-      if(pair->p2 == p2)
-        return 0;
-      else if(pair->p2 < p2)
-        start = cursor + 1;
-      else
-        end = cursor - 1;
-    }else if(pair->p1 < p1){
-      start = cursor + 1;
-    }else{
-      end = cursor - 1 ;
-    }
-  }
-
-  return -1;
-
-}
-
-static void add_compared_pointers(void *p1, void *p2){
+/** \brief Try to add a pair a compared pointers to the set of compared pointers
+ *
+ *  \result !=0 if the pointers were added (they were not in the set),
+ *      0 otherwise (they were already in the set)
+ */
+static int add_compared_pointers(void *p1, void *p2){
 
   pointers_pair_t new_pair = xbt_new0(s_pointers_pair_t, 1);
   new_pair->p1 = p1;
@@ -84,7 +58,7 @@ static void add_compared_pointers(void *p1, void *p2){
   
   if(xbt_dynar_is_empty(compared_pointers)){
     xbt_dynar_push(compared_pointers, &new_pair);
-    return;
+    return 1;
   }
 
   unsigned int cursor = 0;
@@ -92,36 +66,37 @@ static void add_compared_pointers(void *p1, void *p2){
   int end = xbt_dynar_length(compared_pointers) - 1;
   pointers_pair_t pair = NULL;
 
+  pointers_pair_t* p = (pointers_pair_t*) xbt_dynar_get_ptr(compared_pointers, 0);
+
   while(start <= end){
     cursor = (start + end) / 2;
-    pair = (pointers_pair_t)xbt_dynar_get_as(compared_pointers, cursor, pointers_pair_t);
-    if(pair->p1 == p1){
-      if(pair->p2 == p2){
-        pointers_pair_free(new_pair);
-        return;
-      }else if(pair->p2 < p2)
-        start = cursor + 1;
-      else
-        end = cursor - 1;
-    }else if(pair->p1 < p1){
+    pair = p[cursor];
+    if(pair->p1 < p1){
       start = cursor + 1;
-    }else{
+    } else if(pair->p1 > p1) {
       end = cursor - 1 ;
+    } else if(pair->p2 < p2){
+      start = cursor + 1;
+    } else if(pair->p2 > p2) {
+      end = cursor - 1 ;
+    } else {
+      pointers_pair_free(new_pair);
+      return 0;
     }
   }
 
-  if(pair->p1 == p1){
-    if(pair->p2 < p2)
-      xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
-    else
-      xbt_dynar_insert_at(compared_pointers, cursor, &new_pair); 
-  }else{
-    if(pair->p1 < p1)
-      xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
-    else
-      xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);   
-  }
-
+  if(pair->p1 < p1)
+    xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
+  else if(pair->p1 > p1)
+    xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);
+  else if(pair->p2 < p2)
+    xbt_dynar_insert_at(compared_pointers, cursor + 1, &new_pair);
+  else if(pair->p2 > p2)
+    xbt_dynar_insert_at(compared_pointers, cursor, &new_pair);
+  else
+    xbt_die("Unrecheable");
+
+  return 1;
 }
 
 static int compare_areas_with_type(void *area1, void *area2, mc_object_info_t info, mc_object_info_t other_info, dw_type_t type, int region_size, int region_type, void *start_data, int pointer_level){
@@ -151,13 +126,8 @@ static int compare_areas_with_type(void *area1, void *area2, mc_object_info_t in
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
       if(subtype->byte_size == 0){ /*declaration of the type, need the complete description */
-        dw_type_t full_type = xbt_dict_get_or_null(other_info->types_by_name, subtype->name);
-        if(full_type) {
-          type = full_type;
-        } else {
-          subtype = xbt_dict_get_or_null(other_info->types_by_name, subtype->name);
+          subtype = subtype->other_object_same_type;
           switch_types = 1;
-        }
       }
       elm_size = subtype->byte_size;
       break;
@@ -166,7 +136,7 @@ static int compare_areas_with_type(void *area1, void *area2, mc_object_info_t in
     case DW_TAG_volatile_type:
       subsubtype = subtype->subtype;
       if(subsubtype->byte_size == 0){ /*declaration of the type, need the complete description */
-          subsubtype = xbt_dict_get_or_null(other_info->types_by_name, subsubtype->name);
+          subsubtype = subsubtype->other_object_same_type;
           switch_types = 1;
       }
       elm_size = subsubtype->byte_size;
@@ -185,7 +155,7 @@ static int compare_areas_with_type(void *area1, void *area2, mc_object_info_t in
     }
     break;
   case DW_TAG_pointer_type:
-    if(type->dw_type_id && ((dw_type_t)xbt_dict_get_or_null(info->types, type->dw_type_id))->type == DW_TAG_subroutine_type){
+    if(type->subtype && type->subtype->type == DW_TAG_subroutine_type){
       addr_pointed1 = *((void **)(area1)); 
       addr_pointed2 = *((void **)(area2));
       return (addr_pointed1 != addr_pointed2);
@@ -195,9 +165,8 @@ static int compare_areas_with_type(void *area1, void *area2, mc_object_info_t in
       
       if(addr_pointed1 == NULL && addr_pointed2 == NULL)
         return 0;
-      if(already_compared_pointers(addr_pointed1, addr_pointed2) != -1)
+      if(!add_compared_pointers(addr_pointed1, addr_pointed2))
         return 0;
-      add_compared_pointers(addr_pointed1, addr_pointed2);
 
       pointer_level++;
       
@@ -209,14 +178,14 @@ static int compare_areas_with_type(void *area1, void *area2, mc_object_info_t in
       // The pointers are both in the heap:
       if(addr_pointed1 > std_heap && (char *)addr_pointed1 < (char*) std_heap + STD_HEAP_SIZE){
         if(!(addr_pointed2 > std_heap && (char *)addr_pointed2 < (char*) std_heap + STD_HEAP_SIZE))
-          xbt_die("Die");
+          return 1;
         return compare_heap_area(addr_pointed1, addr_pointed2, NULL, info, other_info, type->dw_type_id, pointer_level);
       }
 
       // The pointers are both in the current object R/W segment:
       else if(addr_pointed1 > start_data && (char*)addr_pointed1 <= (char *)start_data + region_size){
         if(!(addr_pointed2 > start_data && (char*)addr_pointed2 <= (char *)start_data + region_size))
-          xbt_die("Die");
+          return 1;
         if(type->dw_type_id == NULL)
           return  (addr_pointed1 != addr_pointed2);
         else
@@ -283,13 +252,13 @@ static int compare_global_variables(int region_type, mc_mem_region_t r1, mc_mem_
     // If the variable is not in this object, skip it:
     // We do not expect to find a pointer to something which is not reachable
     // by the global variables.
-    if((char*) current_var->address.address < (char*) object_info->start_rw
-      || (char*) current_var->address.address > (char*) object_info->end_rw)
+    if((char*) current_var->address < (char*) object_info->start_rw
+      || (char*) current_var->address > (char*) object_info->end_rw)
        continue;
 
-    offset = (char *)current_var->address.address - (char *)object_info->start_rw;
+    offset = (char *)current_var->address - (char *)object_info->start_rw;
 
-    dw_type_t bvariable_type = xbt_dict_get_or_null(object_info->types, current_var->type_origin);
+    dw_type_t bvariable_type = current_var->type;
     res = compare_areas_with_type((char *)r1->data + offset, (char *)r2->data + offset, object_info, other_object_info, bvariable_type, r1->size, region_type, start_data, 0);
     if(res == 1){
       XBT_VERB("Global variable %s (%p - %p) is different between snapshots", current_var->name, (char *)r1->data + offset, (char *)r2->data + offset);
@@ -341,10 +310,10 @@ static int compare_local_variables(mc_snapshot_stack_t stack1, mc_snapshot_stack
 
 
       if(current_var1->region == 1) {
-        dw_type_t subtype = xbt_dict_get_or_null(mc_libsimgrid_info->types, current_var1->type);
+        dw_type_t subtype = current_var1->type;
         res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_libsimgrid_info, mc_binary_info, subtype, 0, 1, start_data_libsimgrid, 0);
       } else {
-        dw_type_t subtype = xbt_dict_get_or_null(mc_binary_info->types, current_var1->type);
+        dw_type_t subtype = current_var2->type;
         res = compare_areas_with_type( (char *)heap1 + offset1, (char *)heap2 + offset2, mc_binary_info, mc_libsimgrid_info, subtype, 0, 2, start_data_binary, 0);
       }
       if(res == 1){
@@ -395,10 +364,14 @@ int snapshot_compare(void *state1, void *state2){
     xbt_os_walltimer_start(timer);
   #endif
 
-  if(MC_USE_SNAPSHOT_HASH) {
-    if(s1->hash != s2->hash) {
+  int hash_result = 0;
+  if(_sg_mc_hash) {
+    hash_result = (s1->hash != s2->hash);
+    if(hash_result) {
       XBT_VERB("(%d - %d) Different hash : 0x%" PRIx64 "--0x%" PRIx64, num1, num2, s1->hash, s2->hash);
+#ifndef MC_DEBUG
       return 1;
+#endif
     } else {
       XBT_VERB("(%d - %d) Same hash : 0x%" PRIx64, num1, num2, s1->hash);
     }
@@ -603,10 +576,24 @@ int snapshot_compare(void *state1, void *state2){
   #endif
 
 #ifdef MC_VERBOSE
-   if(errors==0)
+   if(errors || hash_result)
+     XBT_VERB("(%d - %d) Difference found", num1, num2);
+   else
      XBT_VERB("(%d - %d) No difference found", num1, num2);
 #endif
-  return errors > 0;
+
+#if defined(MC_DEBUG) && defined(MC_VERBOSE)
+   if(_sg_mc_hash) {
+     // * false positive SHOULD be avoided.
+     // * There MUST not be any false negative.
+
+     XBT_VERB("(%d - %d) State equality hash test is %s %s", num1, num2,
+       (hash_result!=0) == (errors!=0) ? "true" : "false",
+       !hash_result ? "positive" : "negative");
+   }
+#endif
+
+   return errors > 0 || hash_result;
   
 }