Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] s/NULL/nullptr/
[simgrid.git] / src / mc / mc_visited.cpp
index edcfcff..1d218be 100644 (file)
@@ -7,12 +7,18 @@
 #include <unistd.h>
 #include <sys/wait.h>
 
-#include "mc_comm_pattern.h"
-#include "mc_safety.h"
-#include "mc_liveness.h"
-#include "mc_private.h"
-#include "mc_process.h"
-#include "mc_smx.h"
+#include <xbt/automaton.h>
+#include <xbt/log.h>
+#include <xbt/sysdep.h>
+#include <xbt/dynar.h>
+#include <xbt/fifo.h>
+
+#include "src/mc/mc_comm_pattern.h"
+#include "src/mc/mc_safety.h"
+#include "src/mc/mc_liveness.h"
+#include "src/mc/mc_private.h"
+#include "src/mc/Process.hpp"
+#include "src/mc/mc_smx.h"
 
 extern "C" {
 
@@ -60,15 +66,11 @@ static mc_visited_state_t visited_state_new()
     process->get_heap()->heaplimit,
     process->get_malloc_info());
 
-  if (mc_model_checker->process().is_self()) {
-    new_state->nb_processes = xbt_swag_size(simix_global->process_list);
-  } else {
-    MC_process_smx_refresh(&mc_model_checker->process());
-    new_state->nb_processes = xbt_dynar_length(
-      mc_model_checker->process().smx_process_infos);
-  }
+  MC_process_smx_refresh(&mc_model_checker->process());
+  new_state->nb_processes = xbt_dynar_length(
+    mc_model_checker->process().smx_process_infos);
 
-  new_state->system_state = MC_take_snapshot(mc_stats->expanded_states);
+  new_state->system_state = simgrid::mc::take_snapshot(mc_stats->expanded_states);
   new_state->num = mc_stats->expanded_states;
   new_state->other_num = -1;
   return new_state;
@@ -77,28 +79,26 @@ static mc_visited_state_t visited_state_new()
 mc_visited_pair_t MC_visited_pair_new(int pair_num, xbt_automaton_state_t automaton_state, xbt_dynar_t atomic_propositions, mc_state_t graph_state)
 {
   simgrid::mc::Process* process = &(mc_model_checker->process());
-  mc_visited_pair_t pair = NULL;
+  mc_visited_pair_t pair = nullptr;
   pair = xbt_new0(s_mc_visited_pair_t, 1);
   pair->graph_state = graph_state;
-  if(pair->graph_state->system_state == NULL)
-    pair->graph_state->system_state = MC_take_snapshot(pair_num);
+  if(pair->graph_state->system_state == nullptr)
+    pair->graph_state->system_state = simgrid::mc::take_snapshot(pair_num);
   pair->heap_bytes_used = mmalloc_get_bytes_used_remote(
     process->get_heap()->heaplimit,
     process->get_malloc_info());
-  if (mc_model_checker->process().is_self()) {
-    pair->nb_processes = xbt_swag_size(simix_global->process_list);
-  } else {
-    MC_process_smx_refresh(&mc_model_checker->process());
-    pair->nb_processes = xbt_dynar_length(
-      mc_model_checker->process().smx_process_infos);
-  }
+
+  MC_process_smx_refresh(&mc_model_checker->process());
+  pair->nb_processes = xbt_dynar_length(
+    mc_model_checker->process().smx_process_infos);
+
   pair->automaton_state = automaton_state;
   pair->num = pair_num;
   pair->other_num = -1;
   pair->acceptance_removed = 0;
   pair->visited_removed = 0;
   pair->acceptance_pair = 0;
-  pair->atomic_propositions = xbt_dynar_new(sizeof(int), NULL);
+  pair->atomic_propositions = xbt_dynar_new(sizeof(int), nullptr);
   unsigned int cursor = 0;
   int value;
   xbt_dynar_foreach(atomic_propositions, cursor, value)
@@ -120,12 +120,12 @@ static int is_exploration_stack_pair(mc_visited_pair_t pair){
 
 void MC_visited_pair_delete(mc_visited_pair_t p)
 {
-  p->automaton_state = NULL;
+  p->automaton_state = nullptr;
   if( !is_exploration_stack_pair(p))
     MC_state_delete(p->graph_state, 1);
   xbt_dynar_free(&(p->atomic_propositions));
   xbt_free(p);
-  p = NULL;
+  p = nullptr;
 }
 
 /**
@@ -222,6 +222,45 @@ int get_search_interval(xbt_dynar_t list, void *ref, int *min, int *max)
   return cursor;
 }
 
+static
+void replace_state(
+  mc_visited_state_t state_test, mc_visited_state_t new_state, int cursor)
+{
+  if (state_test->other_num == -1)
+    new_state->other_num = state_test->num;
+  else
+    new_state->other_num = state_test->other_num;
+
+  if (dot_output == nullptr)
+    XBT_DEBUG("State %d already visited ! (equal to state %d)",
+      new_state->num, state_test->num);
+  else
+    XBT_DEBUG(
+      "State %d already visited ! (equal to state %d (state %d in dot_output))",
+      new_state->num, state_test->num, new_state->other_num);
+
+  /* Replace the old state with the new one (with a bigger num)
+     (when the max number of visited states is reached,  the oldest
+     one is removed according to its number (= with the min number) */
+  xbt_dynar_remove_at(visited_states, cursor, nullptr);
+  xbt_dynar_insert_at(visited_states, cursor, &new_state);
+  XBT_DEBUG("Replace visited state %d with the new visited state %d",
+    state_test->num, new_state->num);
+}
+
+static
+bool some_dommunications_are_not_finished()
+{
+  for (size_t current_process = 1; current_process < MC_smx_get_maxpid(); current_process++) {
+    xbt_dynar_t pattern = xbt_dynar_get_as(
+      incomplete_communications_pattern, current_process, xbt_dynar_t);
+    if (!xbt_dynar_is_empty(pattern)) {
+      XBT_DEBUG("Some communications are not finished, cannot stop the exploration ! State not visited.");
+      return true;
+    }
+  }
+  return false;
+}
 
 /**
  * \brief Checks whether a given state has already been visited by the algorithm.
@@ -231,24 +270,13 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
 {
 
   if (_sg_mc_visited == 0)
-    return NULL;
-
-  int partial_comm = 0;
+    return nullptr;
 
   /* If comm determinism verification, we cannot stop the exploration if some 
      communications are not finished (at least, data are transfered). These communications 
      are incomplete and they cannot be analyzed and compared with the initial pattern. */
-  if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
-    size_t current_process = 1;
-    while (current_process < MC_smx_get_maxpid()) {
-      if (!xbt_dynar_is_empty((xbt_dynar_t)xbt_dynar_get_as(incomplete_communications_pattern, current_process, xbt_dynar_t))){
-        XBT_DEBUG("Some communications are not finished, cannot stop the exploration ! State not visited.");
-        partial_comm = 1;
-        break;
-      }
-      current_process++;
-    }
-  }
+  int partial_comm = (_sg_mc_comms_determinism || _sg_mc_send_determinism) &&
+    some_dommunications_are_not_finished();
 
   mc_visited_state_t new_state = visited_state_new();
   graph_state->system_state = new_state->system_state;
@@ -258,14 +286,11 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
   if (xbt_dynar_is_empty(visited_states)) {
 
     xbt_dynar_push(visited_states, &new_state);
-    return NULL;
+    return nullptr;
 
   } else {
 
     int min = -1, max = -1, index;
-    //int res;
-    mc_visited_state_t state_test;
-    int cursor;
 
     index = get_search_interval(visited_states, new_state, &min, &max);
 
@@ -274,16 +299,16 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
       // Parallell implementation
       /*res = xbt_parmap_mc_apply(parmap, snapshot_compare, xbt_dynar_get_ptr(visited_states, min), (max-min)+1, new_state);
          if(res != -1){
-         state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, (min+res)-1, mc_visited_state_t);
+         mc_visited_state_t state_test = (mc_visited_state_t)xbt_dynar_get_as(visited_states, (min+res)-1, mc_visited_state_t);
          if(state_test->other_num == -1)
          new_state->other_num = state_test->num;
          else
          new_state->other_num = state_test->other_num;
-         if(dot_output == NULL)
+         if(dot_output == nullptr)
          XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num);
          else
          XBT_DEBUG("State %d already visited ! (equal to state %d (state %d in dot_output))", new_state->num, state_test->num, new_state->other_num);
-         xbt_dynar_remove_at(visited_states, (min + res) - 1, NULL);
+         xbt_dynar_remove_at(visited_states, (min + res) - 1, nullptr);
          xbt_dynar_insert_at(visited_states, (min+res) - 1, &new_state);
          return new_state->other_num;
          } */
@@ -291,28 +316,13 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
       if (_sg_mc_safety || (!partial_comm
         && initial_global_state->initial_communications_pattern_done)) {
 
-        cursor = min;
+        int cursor = min;
         while (cursor <= max) {
-          state_test = (mc_visited_state_t) xbt_dynar_get_as(visited_states, cursor, mc_visited_state_t);
+          mc_visited_state_t state_test = (mc_visited_state_t) xbt_dynar_get_as(visited_states, cursor, mc_visited_state_t);
           if (snapshot_compare(state_test, new_state) == 0) {
             // The state has been visited:
 
-            if (state_test->other_num == -1)
-              new_state->other_num = state_test->num;
-            else
-              new_state->other_num = state_test->other_num;
-            if (dot_output == NULL)
-              XBT_DEBUG("State %d already visited ! (equal to state %d)", new_state->num, state_test->num);
-            else
-              XBT_DEBUG("State %d already visited ! (equal to state %d (state %d in dot_output))", new_state->num, state_test->num, new_state->other_num);
-
-            /* Replace the old state with the new one (with a bigger num) 
-               (when the max number of visited states is reached,  the oldest 
-               one is removed according to its number (= with the min number) */
-            xbt_dynar_remove_at(visited_states, cursor, NULL);
-            xbt_dynar_insert_at(visited_states, cursor, &new_state);
-            XBT_DEBUG("Replace visited state %d with the new visited state %d", state_test->num, new_state->num);
-
+            replace_state(state_test, new_state, cursor);
             return state_test;
           }
           cursor++;
@@ -325,7 +335,7 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
     } else {
 
       // The state has not been visited: insert the state in the dynamic array.
-      state_test = (mc_visited_state_t) xbt_dynar_get_as(visited_states, index, mc_visited_state_t);
+      mc_visited_state_t state_test = (mc_visited_state_t) xbt_dynar_get_as(visited_states, index, mc_visited_state_t);
       if (state_test->nb_processes < new_state->nb_processes) {
         xbt_dynar_insert_at(visited_states, index + 1, &new_state);
       } else {
@@ -348,19 +358,22 @@ mc_visited_state_t is_visited_state(mc_state_t graph_state)
       int min2 = mc_stats->expanded_states;
       unsigned int cursor2 = 0;
       unsigned int index2 = 0;
+
+      mc_visited_state_t state_test;
       xbt_dynar_foreach(visited_states, cursor2, state_test){
-        if (state_test->num < min2) {
+        if (!mc_model_checker->is_important_snapshot(*state_test->system_state)
+            && state_test->num < min2) {
           index2 = cursor2;
           min2 = state_test->num;
         }
       }
 
       // and drop it:
-      xbt_dynar_remove_at(visited_states, index2, NULL);
+      xbt_dynar_remove_at(visited_states, index2, nullptr);
       XBT_DEBUG("Remove visited state (maximum number of stored states reached)");
     }
 
-    return NULL;
+    return nullptr;
   }
 }
 
@@ -372,9 +385,9 @@ int is_visited_pair(mc_visited_pair_t visited_pair, mc_pair_t pair) {
   if (_sg_mc_visited == 0)
     return -1;
 
-  mc_visited_pair_t new_visited_pair = NULL;
+  mc_visited_pair_t new_visited_pair = nullptr;
 
-  if (visited_pair == NULL) {
+  if (visited_pair == nullptr) {
     new_visited_pair = MC_visited_pair_new(pair->num, pair->automaton_state, pair->atomic_propositions, pair->graph_state);
   } else {
     new_visited_pair = visited_pair;
@@ -401,11 +414,11 @@ int is_visited_pair(mc_visited_pair_t visited_pair, mc_pair_t pair) {
          pair->other_num = pair_test->num;
          else
          pair->other_num = pair_test->other_num;
-         if(dot_output == NULL)
+         if(dot_output == nullptr)
          XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
          else
          XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
-         xbt_dynar_remove_at(visited_pairs, (min + res) - 1, NULL);
+         xbt_dynar_remove_at(visited_pairs, (min + res) - 1, nullptr);
          xbt_dynar_insert_at(visited_pairs, (min+res) - 1, &pair);
          pair_test->visited_removed = 1;
          if(pair_test->stack_removed && pair_test->visited_removed){
@@ -429,7 +442,7 @@ int is_visited_pair(mc_visited_pair_t visited_pair, mc_pair_t pair) {
                 new_visited_pair->other_num = pair_test->num;
               else
                 new_visited_pair->other_num = pair_test->other_num;
-              if (dot_output == NULL)
+              if (dot_output == nullptr)
                 XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", new_visited_pair->num, pair_test->num);
               else
                 XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", new_visited_pair->num, pair_test->num, new_visited_pair->other_num);
@@ -466,7 +479,8 @@ int is_visited_pair(mc_visited_pair_t visited_pair, mc_pair_t pair) {
       unsigned int cursor2 = 0;
       unsigned int index2 = 0;
       xbt_dynar_foreach(visited_pairs, cursor2, pair_test) {
-        if (pair_test->num < min2) {
+        if (!mc_model_checker->is_important_snapshot(*pair_test->graph_state->system_state)
+            && pair_test->num < min2) {
           index2 = cursor2;
           min2 = pair_test->num;
         }