Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Remove the horrible MC_EACH_SIMIX_PROCESS() macro
authorGabriel Corona <gabriel.corona@loria.fr>
Tue, 1 Mar 2016 12:18:08 +0000 (13:18 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Tue, 1 Mar 2016 12:40:01 +0000 (13:40 +0100)
Use a range for loop instead.

14 files changed:
include/xbt/dynar.hpp [new file with mode: 0644]
include/xbt/range.hpp
src/mc/Frame.hpp
src/mc/LocationList.hpp
src/mc/Process.cpp
src/mc/Process.hpp
src/mc/mc_checkpoint.cpp
src/mc/mc_comm_determinism.cpp
src/mc/mc_forward.hpp
src/mc/mc_liveness.cpp
src/mc/mc_safety.cpp
src/mc/mc_smx.h
src/mc/mc_state.cpp
tools/cmake/DefinePackages.cmake

diff --git a/include/xbt/dynar.hpp b/include/xbt/dynar.hpp
new file mode 100644 (file)
index 0000000..7ef2e68
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (c) 2004-2007, 2009-2015. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef SIMGRId_XBT_DYNAR_HPP
+#define SIMGRId_XBT_DYNAR_HPP
+
+#include <boost/range/iterator_range.hpp>
+
+#include <xbt/asserts.h>
+#include <xbt/dynar.h>
+
+namespace simgrid {
+namespace xbt {
+
+/** A C++ range from a a dynar */
+template<class T>
+using DynarRange = boost::iterator_range<T*>;
+
+/** Create an iterator range representing a dynar
+ *
+ *  C++ range loops for `xbt_dynar_t`:
+ *
+ *  <code>for (auto& x : range<double>(some_dynar)) ++x;</code>
+ */
+template<class T> inline
+DynarRange<T> range(xbt_dynar_t dynar)
+{
+  xbt_assert(dynar->elmsize == sizeof(T));
+  return DynarRange<T>((T*) dynar->data,
+    (T*) ((char*) dynar->data + dynar->used * dynar->elmsize));
+}
+
+}
+}
+
+#endif
index 7e13722..5c20a9c 100644 (file)
@@ -11,13 +11,13 @@ namespace simgrid {
 namespace xbt {
 
 /** Describes a contiguous inclusive-exclusive [a,b) range of values */
-template<class T> class range {
+template<class T> class Range {
   T begin_;
   T end_;
 public:
-  range()               : begin_(), end_() {}
-  range(T begin, T end) : begin_(std::move(begin)), end_(std::move(end)) {}
-  range(T value) : begin_(value), end_(value + 1) {}
+  Range()               : begin_(), end_() {}
+  Range(T begin, T end) : begin_(std::move(begin)), end_(std::move(end)) {}
+  Range(T value) : begin_(value), end_(value + 1) {}
   T& begin()             { return begin_; }
   T& end()               { return end_; }
   const T& begin() const { return begin_; }
index eb5ff10..243610a 100644 (file)
@@ -33,7 +33,7 @@ public:
   std::string name;
 
   /** Range of instruction addresses for which this scope is valid */
-  simgrid::xbt::range<std::uint64_t> range;
+  simgrid::xbt::Range<std::uint64_t> range;
 
   simgrid::dwarf::LocationList frame_base_location;
 
index 2a8bdba..9759836 100644 (file)
@@ -29,7 +29,7 @@ namespace dwarf {
 /** \brief A DWARF expression with optional validity contraints */
 class LocationListEntry {
 public:
-  typedef simgrid::xbt::range<std::uint64_t> range_type;
+  typedef simgrid::xbt::Range<std::uint64_t> range_type;
 private:
   DwarfExpression expression_;
   range_type range_ = {0, UINT64_MAX};
index ed5880b..2e51067 100644 (file)
@@ -701,5 +701,12 @@ void Process::ignore_local_variable(const char *var_name, const char *frame_name
     info->remove_local_variable(var_name, frame_name);
 }
 
+boost::iterator_range<s_mc_smx_process_info*> Process::simix_processes()
+{
+  xbt_assert(mc_mode != MC_MODE_CLIENT);
+  MC_process_smx_refresh(&mc_model_checker->process());
+  return simgrid::xbt::range<s_mc_smx_process_info>(smx_process_infos);
+}
+
 }
 }
index 62fad58..8de8435 100644 (file)
 #include <vector>
 #include <memory>
 
+#include <boost/range/iterator_range.hpp>
+
 #include <sys/types.h>
 
 #include <simgrid_config.h>
 
 #include <xbt/base.h>
 #include <xbt/dynar.h>
+#include <xbt/dynar.hpp>
 #include <xbt/mmalloc.h>
 
 #ifdef HAVE_MC
@@ -46,6 +49,16 @@ typedef int mc_process_cache_flags_t;
 #define MC_PROCESS_CACHE_FLAG_MALLOC_INFO 2
 #define MC_PROCESS_CACHE_FLAG_SIMIX_PROCESSES 4
 
+struct s_mc_smx_process_info {
+  /** MCed address of the process */
+  void* address;
+  /** (Flat) Copy of the process data structure */
+  struct s_smx_process copy;
+  /** Hostname (owned by `mc_modelchecker->hostnames`) */
+  const char* hostname;
+  char* name;
+};
+
 namespace simgrid {
 namespace mc {
 
@@ -194,6 +207,7 @@ public:
 
   void ignore_local_variable(const char *var_name, const char *frame_name);
   int socket() { return socket_; }
+  simgrid::xbt::DynarRange<s_mc_smx_process_info> simix_processes();
 
 private:
   void init_memory_map_info();
index 939fe0c..38b4e44 100644 (file)
@@ -554,9 +554,8 @@ mc_snapshot_t take_snapshot(int num_state)
 
   snapshot->num_state = num_state;
 
-  smx_process_t process;
-  MC_EACH_SIMIX_PROCESS(process,
-    snapshot->enabled_processes.insert(process->pid));
+  for (auto& p : mc_model_checker->process().simix_processes())
+    snapshot->enabled_processes.insert(p.copy.pid);
 
   snapshot_handle_ignore(snapshot);
 
index 1be100a..d499d1b 100644 (file)
@@ -302,7 +302,6 @@ static int MC_modelcheck_comm_determinism_main(void);
 static void MC_pre_modelcheck_comm_determinism(void)
 {
   mc_state_t initial_state = nullptr;
-  smx_process_t process;
   int i;
   const int maxpid = MC_smx_get_maxpid();
 
@@ -333,11 +332,9 @@ static void MC_pre_modelcheck_comm_determinism(void)
   mc_model_checker->wait_for_requests();
 
   /* Get an enabled process and insert it in the interleave set of the initial state */
-  MC_EACH_SIMIX_PROCESS(process,
-    if (MC_process_is_enabled(process)) {
-      MC_state_interleave_process(initial_state, process);
-    }
-  );
+  for (auto& p : mc_model_checker->process().simix_processes())
+    if (MC_process_is_enabled(&p.copy))
+      MC_state_interleave_process(initial_state, &p.copy);
 
   xbt_fifo_unshift(mc_stack, initial_state);
 }
@@ -349,7 +346,6 @@ static int MC_modelcheck_comm_determinism_main(void)
   int value;
   mc_visited_state_t visited_state = nullptr;
   smx_simcall_t req = nullptr;
-  smx_process_t process = nullptr;
   mc_state_t state = nullptr, next_state = NULL;
 
   while (xbt_fifo_size(mc_stack) > 0) {
@@ -403,11 +399,9 @@ static int MC_modelcheck_comm_determinism_main(void)
       if ((visited_state = is_visited_state(next_state)) == nullptr) {
 
         /* Get enabled processes and insert them in the interleave set of the next state */
-        MC_EACH_SIMIX_PROCESS(process,
-          if (MC_process_is_enabled(process)) {
-            MC_state_interleave_process(next_state, process);
-          }
-        );
+        for (auto& p : mc_model_checker->process().simix_processes())
+          if (MC_process_is_enabled(&p.copy))
+            MC_state_interleave_process(next_state, &p.copy);
 
         if (dot_output != nullptr)
           fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num,  next_state->num, req_str);
index e77c97d..1be20a4 100644 (file)
@@ -30,6 +30,8 @@ class Frame;
 }
 }
 
+struct s_mc_smx_process_info;
+
 // TODO, try to get rid of the global ModelChecker variable
 extern simgrid::mc::ModelChecker* mc_model_checker;
 
index 84e996d..d184f90 100644 (file)
@@ -178,10 +178,7 @@ static int MC_modelcheck_liveness_main(void);
 static void MC_pre_modelcheck_liveness(void)
 {
   mc_pair_t initial_pair = nullptr;
-  smx_process_t process;
-
   mc_model_checker->wait_for_requests();
-
   acceptance_pairs = xbt_dynar_new(sizeof(mc_visited_pair_t), nullptr);
   if(_sg_mc_visited > 0)
     visited_pairs = xbt_dynar_new(sizeof(mc_visited_pair_t), nullptr);
@@ -202,11 +199,9 @@ static void MC_pre_modelcheck_liveness(void)
       initial_pair->depth = 1;
 
       /* Get enabled processes and insert them in the interleave set of the graph_state */
-      MC_EACH_SIMIX_PROCESS(process,
-        if (MC_process_is_enabled(process)) {
-          MC_state_interleave_process(initial_pair->graph_state, process);
-        }
-      );
+      for (auto& p : mc_model_checker->process().simix_processes())
+        if (MC_process_is_enabled(&p.copy))
+          MC_state_interleave_process(initial_pair->graph_state, &p.copy);
 
       initial_pair->requests = MC_state_interleave_size(initial_pair->graph_state);
       initial_pair->search_cycle = 0;
@@ -218,7 +213,6 @@ static void MC_pre_modelcheck_liveness(void)
 
 static int MC_modelcheck_liveness_main(void)
 {
-  smx_process_t process = nullptr;
   mc_pair_t current_pair = nullptr;
   int value, res, visited_num = -1;
   smx_simcall_t req = nullptr;
@@ -324,11 +318,9 @@ static int MC_modelcheck_liveness_main(void)
               next_pair->atomic_propositions = get_atomic_propositions_values();
               next_pair->depth = current_pair->depth + 1;
               /* Get enabled processes and insert them in the interleave set of the next graph_state */
-              MC_EACH_SIMIX_PROCESS(process,
-                if (MC_process_is_enabled(process)) {
-                  MC_state_interleave_process(next_pair->graph_state, process);
-                }
-              );
+              for (auto& p : mc_model_checker->process().simix_processes())
+                if (MC_process_is_enabled(&p.copy))
+                  MC_state_interleave_process(next_pair->graph_state, &p.copy);
 
               next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
 
index 594cb71..5d3c23a 100644 (file)
@@ -64,14 +64,12 @@ static void MC_pre_modelcheck_safety()
   mc_model_checker->wait_for_requests();
 
   /* Get an enabled process and insert it in the interleave set of the initial state */
-  smx_process_t process;
-  MC_EACH_SIMIX_PROCESS(process,
-    if (MC_process_is_enabled(process)) {
-      MC_state_interleave_process(initial_state, process);
+  for (auto& p : mc_model_checker->process().simix_processes())
+    if (MC_process_is_enabled(&p.copy)) {
+      MC_state_interleave_process(initial_state, &p.copy);
       if (mc_reduce_kind != e_mc_reduce_none)
         break;
     }
-  );
 
   xbt_fifo_unshift(mc_stack, initial_state);
 }
@@ -139,14 +137,12 @@ int MC_modelcheck_safety(void)
       if ((visited_state = is_visited_state(next_state)) == nullptr) {
 
         /* Get an enabled process and insert it in the interleave set of the next state */
-        smx_process_t process = nullptr;
-        MC_EACH_SIMIX_PROCESS(process,
-          if (MC_process_is_enabled(process)) {
-            MC_state_interleave_process(next_state, process);
+        for (auto& p : mc_model_checker->process().simix_processes())
+          if (MC_process_is_enabled(&p.copy)) {
+            MC_state_interleave_process(next_state, &p.copy);
             if (mc_reduce_kind != e_mc_reduce_none)
               break;
           }
-        );
 
         if (dot_output != nullptr)
           std::fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num, next_state->num, req_str);
index 3ca4e5d..6db9ae4 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <xbt/base.h>
 #include <xbt/dynar.h>
+#include <xbt/dynar.hpp>
 #include <xbt/log.h>
 
 #include <simgrid/simix.h>
 
 SG_BEGIN_DECL()
 
-struct s_mc_smx_process_info {
-  /** MCed address of the process */
-  void* address;
-  /** (Flat) Copy of the process data structure */
-  struct s_smx_process copy;
-  /** Hostname (owned by `mc_modelchecker->hostnames`) */
-  const char* hostname;
-  char* name;
-};
-
 typedef struct s_mc_smx_process_info s_mc_smx_process_info_t, *mc_smx_process_info_t;
 
 XBT_PRIVATE xbt_dynar_t MC_smx_process_info_list_new(void);
@@ -72,22 +63,6 @@ XBT_PRIVATE smx_process_t MC_smx_simcall_get_issuer(smx_simcall_t req);
 XBT_PRIVATE const char* MC_smx_process_get_name(smx_process_t p);
 XBT_PRIVATE const char* MC_smx_process_get_host_name(smx_process_t p);
 
-#define MC_EACH_SIMIX_PROCESS(process, code) \
-  if (mc_mode == MC_MODE_CLIENT) { \
-    xbt_swag_foreach(process, simix_global->process_list) { \
-      code; \
-    } \
-  } else { \
-    MC_process_smx_refresh(&mc_model_checker->process()); \
-    unsigned int _smx_process_index; \
-    mc_smx_process_info_t _smx_process_info; \
-    xbt_dynar_foreach_ptr(mc_model_checker->process().smx_process_infos, _smx_process_index, _smx_process_info) { \
-      smx_process_t process = &_smx_process_info->copy; \
-      code; \
-    } \
-  }
-
-
 XBT_PRIVATE int MC_smpi_process_count(void);
 
 
index 7c81fd5..726294f 100644 (file)
@@ -102,8 +102,6 @@ void MC_state_set_executed_request(mc_state_t state, smx_simcall_t req,
   state->executed_req = *req;
   state->req_num = value;
 
-  smx_process_t process = nullptr;
-
   /* The waitany and testany request are transformed into a wait or test request over the
    * corresponding communication action so it can be treated later by the dependence
    * function. */
@@ -157,14 +155,14 @@ void MC_state_set_executed_request(mc_state_t state, smx_simcall_t req,
     state->internal_req = *req;
     int random_max = simcall_mc_random__get__max(req);
     if (value != random_max) {
-      MC_EACH_SIMIX_PROCESS(process,
-        mc_procstate_t procstate = &state->proc_status[process->pid];
+      for (auto& p : mc_model_checker->process().simix_processes()) {
+        mc_procstate_t procstate = &state->proc_status[p.copy.pid];
         const smx_process_t issuer = MC_smx_simcall_get_issuer(req);
-        if (process->pid == issuer->pid) {
+        if (p.copy.pid == issuer->pid) {
           procstate->state = MC_MORE_INTERLEAVE;
           break;
         }
-      );
+      }
     }
     break;
   }
@@ -283,13 +281,11 @@ static inline smx_simcall_t MC_state_get_request_for_process(
 
 smx_simcall_t MC_state_get_request(mc_state_t state, int *value)
 {
-  smx_process_t process = nullptr;
-  MC_EACH_SIMIX_PROCESS(process,
-    smx_simcall_t res = MC_state_get_request_for_process(state, value, process);
+  for (auto& p : mc_model_checker->process().simix_processes()) {
+    smx_simcall_t res = MC_state_get_request_for_process(state, value, &p.copy);
     if (res)
       return res;
-  );
-
+  }
   return nullptr;
 }
 
index ff55c1d..67c7b4f 100644 (file)
@@ -673,6 +673,7 @@ set(headers_to_install
   include/xbt/string.hpp
   include/xbt/signal.hpp
   include/xbt/dynar.h
+  include/xbt/dynar.hpp
   include/xbt/ex.h
   include/xbt/fifo.h
   include/xbt/file.h