Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into 'master'
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Fri, 20 Sep 2019 12:57:08 +0000 (14:57 +0200)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Fri, 20 Sep 2019 12:57:08 +0000 (14:57 +0200)
NS-3: unblock the number of communications + detect when several flows are simultaneously finishing

See merge request simgrid/simgrid!17

43 files changed:
ChangeLog
README.coding
docs/source/platform_howtos.rst
examples/deprecated/simdag/scheduling/sd_scheduling.c
include/simgrid/actor.h
include/simgrid/host.h
include/simgrid/s4u/Engine.hpp
include/simgrid/s4u/Host.hpp
include/simgrid/s4u/Link.hpp
include/simgrid/s4u/Storage.hpp
include/xbt/Extendable.hpp
src/bindings/lua/lua_platf.cpp
src/instr/instr_config.cpp
src/instr/instr_platform.cpp
src/kernel/actor/ActorImpl.hpp
src/mc/checker/CommunicationDeterminismChecker.cpp
src/mc/checker/LivenessChecker.cpp
src/mc/checker/SafetyChecker.cpp
src/mc/mc_state.cpp
src/mc/mc_state.hpp
src/msg/msg_legacy.cpp
src/plugins/host_energy.cpp
src/plugins/link_energy.cpp
src/s4u/s4u_Actor.cpp
src/s4u/s4u_Engine.cpp
src/s4u/s4u_Host.cpp
src/s4u/s4u_Link.cpp
src/simix/smx_global.cpp
src/smpi/include/smpi_actor.hpp
src/smpi/internals/smpi_actor.cpp
src/smpi/internals/smpi_deployment.cpp
src/smpi/internals/smpi_global.cpp
src/surf/network_interface.hpp
src/surf/network_ns3.cpp
src/surf/sg_platf.cpp
src/surf/surf_c_bindings.cpp
src/surf/surf_interface.cpp
src/surf/xml/surfxml_sax_cb.cpp
src/xbt/exception.cpp
src/xbt/xbt_main.cpp
teshsuite/s4u/cloud-sharing/cloud-sharing.cpp
tools/cmake/Flags.cmake
tools/jenkins/Coverage.sh

index ba6035e..c0f5b21 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,15 @@ S4U:
  - Actor::on_destruction is now called in the destructor
    Actor::on_termination new signal called when the actor terminates
    its code.
+ - Global signals are now part of the Engine:
+   - on_platform_creation: after config settings, before the XML parsing
+   - on_platform_created: right after the XML parsing
+   - on_time_advance: each time the clock advances
+   - on_simulation_end: after simulation, before cleanups
+   - on_deadlock: as the name implies.
+ - C bindings:
+   - sg_{actor,host,link}_{data,data_set}() now all exist.
+     Use them to attach user data to the object and retrieve it.
 
 MSG:
  - convert a new set of functions to the S4U C interface and move the old MSG
@@ -36,6 +45,7 @@ Bugs:
  - FG#28: add sg_actor_self (and other wrappers on this_actor methods)
  - FG#29 and FG#33: provide a new C API to mutexes and condition variables 
  - FG#30: convert MSG_process_{un}ref to sg_actor_{un}ref
+ - FG#31: per-actor data
  - FG#34: SG_BARRIER_SERIAL_THREAD?
  - FG#35: model-checker does not like buster-produced binaries
 
index 6b3d048..44414b9 100644 (file)
@@ -35,6 +35,8 @@ SimGrid4 will follow the these rules:
     - Example: src/kernel/activity/Activity.cpp
                include/simgrid/activity/Activity.hpp
   C
+  - Field getters are named sg_object_field() eg sg_link_name()
+    Field setters are named sg_object_field_set() eg sg_link_data_set()
   - variables and functions are in snake_case()
   - typedefs do not hide the pointers, ie * must be explicit
     char * sg_host_get_name(sg_host_t * host);
index 5f1fe9a..cd61f10 100644 (file)
@@ -185,3 +185,58 @@ period and another one for the shutdown period.
 
 Of course, this is only one possible way to model these things. YMMV ;)
 
+.. _understanding_lv08
+Understanding the default TCP model
+*****************************
+When simulating a data transfer between two hosts, you may be surprised
+by the obtained simulation time. Lets consider the following platform:
+
+.. code-block:: xml
+
+   <host id="A" speed="1Gf"/>
+   <host id="B" speed="1Gf"/>
+
+   <link id="link1" latency="10ms" bandwidth="1Mbps"/>
+
+   <route src="A" dst="B>
+     <link_ctn id="link1/>
+   </route>
+
+If host `A` sends `100kB` (a hundred kilobytes) to host `B`, one could expect
+that this communication would take `0.81` seconds to complete according to a
+simple latency-plus-size-divided-by-bandwidth model (0.01 + 8e5/1e6 = 0.81).
+However, the default TCP model of SimGrid is a bit more complex than that. It
+accounts for three phenomena that directly impact the simulation time even
+on such a simple example:
+  - The size of a message at the application level (i.e., 100kB in this
+    example) is not the size that will actually be transferred over the
+    network. To mimic the fact that TCP and IP headers are added to each packet of
+    the original payload, the TCP model of SimGrid empirically considers that
+    `only 97% of the nominal bandwidth` are available. In other words, the
+    size of your message is increased by a few percents, whatever this size be.
+
+  - In the real world, the TCP protocol is not able to fully exploit the
+    bandwidth of a link from the emission of the first packet. To reflect this
+    `slow start` phenomenon, the latency declared in the platform file is
+    multiplied by `a factor of 13.01`. Here again, this is an empirically
+    determined value that may not correspond to every TCP implementations on
+    every networks. It can be tuned when more realistic simulated times for
+    short messages are needed though.
+
+  - When data is transferred from A to B, some TCP ACK messages travel in the
+    opposite direction. To reflect the impact of this `cross-traffic`, SimGrid
+    simulates a flow from B to A that represents an additional bandwidth
+    consumption of `0.05`. The route from B to A is implicity declared in the
+    platfrom file and uses the same link `link1` as if the two hosts were
+    connected through a communication bus. The bandwidth share allocated to the
+    flow from A to B is then the available bandwidth of `link1` (i.e., 97% of
+    the nominal bandwidth of 1Mb/s) divided by 1.05 (i.e., the total consumption).
+    This feature, activated by default, can be disabled by adding the
+    `--cfg=network/crosstraffic:0` flag to command line.
+
+As a consequence, the time to transfer 100kB from A to B as simulated by the
+default TCP model of SimGrid is not 0.81 seconds but
+
+.. code-block:: python
+
+    0.01 * 13.01 + 800000 / ((0.97 * 1e6) / 1.05) =  0.996079 seconds.
index fb39c8a..17972b6 100644 (file)
@@ -24,26 +24,26 @@ struct _HostAttribute {
 
 static double sg_host_get_available_at(sg_host_t host)
 {
-  HostAttribute attr = (HostAttribute) sg_host_user(host);
+  HostAttribute attr = (HostAttribute)sg_host_data(host);
   return attr->available_at;
 }
 
 static void sg_host_set_available_at(sg_host_t host, double time)
 {
-  HostAttribute attr = (HostAttribute) sg_host_user(host);
+  HostAttribute attr = (HostAttribute)sg_host_data(host);
   attr->available_at = time;
-  sg_host_user_set(host, attr);
+  sg_host_data_set(host, attr);
 }
 
 static SD_task_t sg_host_get_last_scheduled_task( sg_host_t host){
-  HostAttribute attr = (HostAttribute) sg_host_user(host);
+  HostAttribute attr = (HostAttribute)sg_host_data(host);
   return attr->last_scheduled_task;
 }
 
 static void sg_host_set_last_scheduled_task(sg_host_t host, SD_task_t task){
-  HostAttribute attr = (HostAttribute) sg_host_user(host);
+  HostAttribute attr       = (HostAttribute)sg_host_data(host);
   attr->last_scheduled_task=task;
-  sg_host_user_set(host, attr);
+  sg_host_data_set(host, attr);
 }
 
 static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax)
@@ -155,11 +155,11 @@ int main(int argc, char **argv)
   SD_create_environment(argv[1]);
 
   /*  Allocating the host attribute */
-  int total_nhosts = sg_host_count();
+  unsigned int total_nhosts = sg_host_count();
   sg_host_t *hosts = sg_host_list();
 
   for (cursor = 0; cursor < total_nhosts; cursor++)
-    sg_host_user_set(hosts[cursor], xbt_new0(struct _HostAttribute, 1));
+    sg_host_data_set(hosts[cursor], xbt_new0(struct _HostAttribute, 1));
 
   /* load the DAX file */
   xbt_dynar_t dax = SD_daxload(argv[2]);
@@ -246,8 +246,8 @@ int main(int argc, char **argv)
   xbt_dynar_free_container(&dax);
 
   for (cursor = 0; cursor < total_nhosts; cursor++) {
-    free(sg_host_user(hosts[cursor]));
-    sg_host_user_set(hosts[cursor], NULL);
+    free(sg_host_data(hosts[cursor]));
+    sg_host_data_set(hosts[cursor], NULL);
   }
 
   xbt_free(hosts);
index e13893e..9b38ab5 100644 (file)
@@ -49,6 +49,8 @@ XBT_PUBLIC const char* sg_actor_self_get_name();
 XBT_PUBLIC void sg_actor_self_execute(double flops);
 XBT_PUBLIC void sg_actor_ref(sg_actor_t actor);
 XBT_PUBLIC void sg_actor_unref(sg_actor_t actor);
+XBT_PUBLIC void* sg_actor_data(sg_actor_t actor);
+XBT_PUBLIC void sg_actor_data_set(sg_actor_t actor, void* userdata);
 
 SG_END_DECL()
 
index bdb3d89..fad40cd 100644 (file)
@@ -47,15 +47,18 @@ XBT_PUBLIC const char* sg_host_get_name(sg_host_t host);
 // ========== User Data ==============
 /** @brief Return the user data of a #sg_host_t.
  *
- * This functions returns the user data associated to @a host if it is possible.
+ * This functions returns the user data associated to @a host if any.
  */
-XBT_PUBLIC void* sg_host_user(sg_host_t host);
+XBT_PUBLIC void* sg_host_data(sg_host_t host);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data()") XBT_PUBLIC void* sg_host_user(sg_host_t host);
 /** @brief Set the user data of a #sg_host_t.
  *
- * This functions attach @a data to @a host if it is possible.
+ * This functions attach @a data to @a host.
  */
-XBT_PUBLIC void sg_host_user_set(sg_host_t host, void* userdata);
-XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
+XBT_PUBLIC void sg_host_data_set(sg_host_t host, void* userdata);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data_set()") XBT_PUBLIC
+    void sg_host_user_set(sg_host_t host, void* userdata);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data_set(h, NULL)") XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
 
 // ========= storage related functions ============
 /** @brief Return the list of mount point names on an host.
index 941b7cd..242a979 100644 (file)
@@ -154,27 +154,27 @@ public:
    */
   void set_config(const std::string& str);
 
-private:
-  kernel::EngineImpl* const pimpl;
-  static Engine* instance_;
-};
+  /** Callback fired when the platform is created (ie, the xml file parsed),
+   * right before the actual simulation starts. */
+  static xbt::signal<void()> on_platform_created;
 
-/** Callback fired when the platform is created (ie, the xml file parsed),
* right before the actual simulation starts. */
-extern XBT_PUBLIC xbt::signal<void()> on_platform_created;
+  /** Callback fired when the platform is about to be created
  * (ie, after any configuration change and just before the resource creation) */
+  static xbt::signal<void()> on_platform_creation;
 
-/** Callback fired when the platform is about to be created
- * (ie, after any configuration change and just before the resource creation) */
-extern XBT_PUBLIC xbt::signal<void()> on_platform_creation;
+  /** Callback fired when the main simulation loop ends, just before the end of Engine::run() */
+  static xbt::signal<void()> on_simulation_end;
 
-/** Callback fired when the main simulation loop ends, just before the end of Engine::run() */
-extern XBT_PUBLIC xbt::signal<void()> on_simulation_end;
+  /** Callback fired when the time jumps into the future */
+  static xbt::signal<void(double)> on_time_advance;
 
-/** Callback fired when the time jumps into the future */
-extern XBT_PUBLIC xbt::signal<void(double)> on_time_advance;
+  /** Callback fired when the time cannot advance because of inter-actors deadlock */
+  static xbt::signal<void(void)> on_deadlock;
 
-/** Callback fired when the time cannot advance because of inter-actors deadlock */
-extern XBT_PUBLIC xbt::signal<void(void)> on_deadlock;
+private:
+  kernel::EngineImpl* const pimpl;
+  static Engine* instance_;
+};
 
 #ifndef DOXYGEN /* Internal use only, no need to expose it */
 template <class T> XBT_PRIVATE void get_filtered_netzones_recursive(s4u::NetZone* current, std::vector<T*>* whereto)
index 7702d6b..c136667 100644 (file)
@@ -157,6 +157,4 @@ public:
 } // namespace s4u
 } // namespace simgrid
 
-extern int USER_HOST_LEVEL;
-
 #endif /* SIMGRID_S4U_HOST_HPP */
index 3ef6cee..8d788ed 100644 (file)
@@ -64,9 +64,6 @@ public:
   bool is_on() const;
   void turn_off();
 
-  void* get_data(); /** Should be used only from the C interface. Prefer extensions in C++ */
-  void set_data(void* d);
-
 #ifndef DOXYGEN
   XBT_ATTRIB_DEPRECATED_v325("Please use Link::set_state_profile()") void set_state_trace(
       kernel::profile::Profile* profile)
index 9bfa5ad..3099a47 100644 (file)
@@ -60,9 +60,6 @@ public:
   const char* get_property(const std::string& key) const;
   void set_property(const std::string&, const std::string& value);
 
-  void set_data(void* data) { userdata_ = data; }
-  void* get_data() { return userdata_; }
-
   IoPtr io_init(sg_size_t size, s4u::Io::OpType type);
 
   IoPtr read_async(sg_size_t size);
@@ -76,7 +73,6 @@ private:
   Host* attached_to_ = nullptr;
   kernel::resource::StorageImpl* const pimpl_;
   std::string name_;
-  void* userdata_ = nullptr;
 };
 
 } // namespace s4u
index 37946b6..d95d186 100644 (file)
@@ -52,6 +52,9 @@ private:
 public:
   static size_t extension_create(void (*deleter)(void*))
   {
+    if (deleters_.empty()) { // Save space for void* user data
+      deleters_.push_back(nullptr);
+    }
     deleters_.push_back(deleter);
     return deleters_.size() - 1;
   }
@@ -65,7 +68,7 @@ public:
   {
     return Extension<T, U>(extension_create([](void* p) { delete static_cast<U*>(p); }));
   }
-  Extendable() : extensions_(deleters_.size(), nullptr) {}
+  Extendable() : extensions_((deleters_.size() > 0 ? deleters_.size() : 1), nullptr) {}
   Extendable(const Extendable&) = delete;
   Extendable& operator=(const Extendable&) = delete;
   ~Extendable()
@@ -76,7 +79,7 @@ public:
      * an extension A, the subsystem of B might depend on the subsystem on A and
      * an extension of B might need to have the extension of A around when executing
      * its cleanup function/destructor. */
-    for (std::size_t i = extensions_.size(); i > 0; --i)
+    for (std::size_t i = extensions_.size(); i > 1; --i) // rank=0 is the spot of user's void*
       if (extensions_[i - 1] != nullptr && deleters_[i - 1] != nullptr)
         deleters_[i - 1](extensions_[i - 1]);
   }
@@ -103,7 +106,13 @@ public:
   {
     extension_set(rank.id(), value, use_dtor);
   }
-
+  // void* version, for C users and nostalgics
+  void set_data(void* data){
+    extensions_[0]=data;
+  }
+  void* get_data(){
+    return extensions_[0];
+  }
   // Convenience extension access when the type has a associated EXTENSION ID:
   template <class U> U* extension() const { return extension<U>(U::EXTENSION_ID); }
   template<class U> void extension_set(U* p) { extension_set<U>(U::EXTENSION_ID, p); }
index eba4663..404887f 100644 (file)
@@ -65,14 +65,14 @@ static simgrid::s4u::Link::SharingPolicy link_policy_get_by_name(const char* pol
 int console_open(lua_State*)
 {
   sg_platf_init();
-  simgrid::s4u::on_platform_creation();
+  simgrid::s4u::Engine::on_platform_creation();
 
   return 0;
 }
 
 int console_close(lua_State*)
 {
-  simgrid::s4u::on_platform_created();
+  simgrid::s4u::Engine::on_platform_created();
   sg_platf_exit();
   return 0;
 }
index 415e3ba..ff20f26 100644 (file)
@@ -294,9 +294,9 @@ void TRACE_global_init()
                                      6);
 
   /* Connect callbacks */
-  simgrid::s4u::on_platform_creation.connect(TRACE_start);
-  simgrid::s4u::on_deadlock.connect(TRACE_end);
-  simgrid::s4u::on_simulation_end.connect(TRACE_end);
+  simgrid::s4u::Engine::on_platform_creation.connect(TRACE_start);
+  simgrid::s4u::Engine::on_deadlock.connect(TRACE_end);
+  simgrid::s4u::Engine::on_simulation_end.connect(TRACE_end);
 }
 
 static void print_line(const char* option, const char* desc, const char* longdesc)
index 9ce839a..fa042a8 100644 (file)
@@ -355,7 +355,7 @@ void instr_define_callbacks()
   // always need the callbacks to zones (we need only the root zone), to create the rootContainer and the rootType
   // properly
   if (TRACE_needs_platform()) {
-    simgrid::s4u::on_platform_created.connect(instr_on_platform_created);
+    simgrid::s4u::Engine::on_platform_created.connect(instr_on_platform_created);
     simgrid::s4u::Host::on_creation.connect(instr_host_on_creation);
     simgrid::s4u::Host::on_speed_change.connect(instr_host_on_speed_change);
     simgrid::s4u::Link::on_creation.connect(instr_link_on_creation);
index d0c75f2..ee082de 100644 (file)
@@ -79,11 +79,14 @@ public:
   int get_refcount() { return refcount_; }
   friend void intrusive_ptr_add_ref(ActorImpl* actor)
   {
-    // std::memory_order_relaxed ought to be enough here instead of std::memory_order_seq_cst
-    // But then, we have a threading issue when an actor commits a suicide:
-    //  it seems that in this case, the worker thread kills the last occurrence of the actor
-    //  while usually, the maestro does so. FIXME: we should change how actors suicide
-    actor->refcount_.fetch_add(1, std::memory_order_seq_cst);
+    // This whole memory consistency semantic drives me nuts.
+    // std::memory_order_relaxed proves to not be enough: There is a threading issue when actors commit suicide.
+    //   My guess is that the maestro context wants to propagate changes to the actor's fields after the
+    //   actor context frees that memory area or something. But I'm not 100% certain of what's going on.
+    // std::memory_order_seq_cst works but that's rather demanding.
+    // AFAIK, std::memory_order_acq_rel works on all tested platforms, so let's stick to it.
+    // Reducing the requirements to _relaxed would require to fix our suicide procedure, which is a messy piece of code.
+    actor->refcount_.fetch_add(1, std::memory_order_acq_rel);
   }
   friend void intrusive_ptr_release(ActorImpl* actor)
   {
index a4b48c9..1302502 100644 (file)
@@ -425,7 +425,7 @@ void CommunicationDeterminismChecker::real_run()
     mc_model_checker->visited_states++;
 
     if (stack_.size() <= (std::size_t)_sg_mc_max_depth)
-      req = MC_state_get_request(cur_state);
+      req = MC_state_choose_request(cur_state);
     else
       req = nullptr;
 
index 4f6000f..bbced3a 100644 (file)
@@ -379,7 +379,7 @@ void LivenessChecker::run()
       }
     }
 
-    smx_simcall_t req = MC_state_get_request(current_pair->graph_state.get());
+    smx_simcall_t req = MC_state_choose_request(current_pair->graph_state.get());
     int req_num       = current_pair->graph_state->transition_.argument_;
 
     if (dot_output != nullptr) {
index ecc8ca3..c08ecaa 100644 (file)
@@ -113,7 +113,7 @@ void SafetyChecker::run()
 
     // Search an enabled transition in the current state; backtrack if the interleave set is empty
     // get_request also sets state.transition to be the one corresponding to the returned req
-    smx_simcall_t req = MC_state_get_request(state);
+    smx_simcall_t req = MC_state_choose_request(state);
     // req is now the transition of the process that was selected to be executed
 
     if (req == nullptr) {
index 0106b84..535dae9 100644 (file)
@@ -60,7 +60,7 @@ Transition State::get_transition() const
  * Things can get muddled with the WAITANY and TESTANY simcalls, that are rewritten on the fly to a bunch of WAIT
  * (resp TEST) transitions using the transition.argument field to remember what was the last returned sub-transition.
  */
-static inline smx_simcall_t MC_state_get_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
+static inline smx_simcall_t MC_state_choose_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
 {
   /* reset the outgoing transition */
   simgrid::mc::ActorState* procstate   = &state->actor_states_[actor->get_pid()];
@@ -202,14 +202,14 @@ static inline smx_simcall_t MC_state_get_request_for_process(simgrid::mc::State*
   return req;
 }
 
-smx_simcall_t MC_state_get_request(simgrid::mc::State* state)
+smx_simcall_t MC_state_choose_request(simgrid::mc::State* state)
 {
   for (auto& actor : mc_model_checker->process().actors()) {
     /* Only consider the actors that were marked as interleaving by the checker algorithm */
     if (not state->actor_states_[actor.copy.get_buffer()->get_pid()].is_todo())
       continue;
 
-    smx_simcall_t res = MC_state_get_request_for_process(state, actor.copy.get_buffer());
+    smx_simcall_t res = MC_state_choose_request_for_process(state, actor.copy.get_buffer());
     if (res)
       return res;
   }
index 96b5910..4123468 100644 (file)
@@ -130,6 +130,6 @@ public:
 }
 }
 
-XBT_PRIVATE smx_simcall_t MC_state_get_request(simgrid::mc::State* state);
+XBT_PRIVATE smx_simcall_t MC_state_choose_request(simgrid::mc::State* state);
 
 #endif
index ab142c8..cd258f3 100644 (file)
@@ -282,11 +282,11 @@ const char* MSG_host_get_name(sg_host_t host)
 }
 void* MSG_host_get_data(sg_host_t host)
 {
-  return sg_host_user(host);
+  return sg_host_data(host);
 }
 void MSG_host_set_data(sg_host_t host, void* data)
 {
-  return sg_host_user_set(host, data);
+  return sg_host_data_set(host, data);
 }
 xbt_dict_t MSG_host_get_mounted_storage_list(sg_host_t host)
 {
index 2dd43f5..2d9f84b 100644 (file)
@@ -489,7 +489,7 @@ void sg_host_energy_plugin_init()
   simgrid::s4u::Host::on_state_change.connect(&on_host_change);
   simgrid::s4u::Host::on_speed_change.connect(&on_host_change);
   simgrid::s4u::Host::on_destruction.connect(&on_host_destruction);
-  simgrid::s4u::on_simulation_end.connect(&on_simulation_end);
+  simgrid::s4u::Engine::on_simulation_end.connect(&on_simulation_end);
   simgrid::kernel::resource::CpuAction::on_state_change.connect(&on_action_state_change);
   // We may only have one actor on a node. If that actor executes something like
   //   compute -> recv -> compute
index bdf842b..20c9873 100644 (file)
@@ -186,7 +186,6 @@ int sg_link_energy_is_inited()
  */
 void sg_link_energy_plugin_init()
 {
-
   if (LinkEnergy::EXTENSION_ID.valid())
     return;
   LinkEnergy::EXTENSION_ID = simgrid::s4u::Link::extension_create<LinkEnergy>();
@@ -213,7 +212,7 @@ void sg_link_energy_plugin_init()
   });
 
   simgrid::s4u::Link::on_communicate.connect(&on_communicate);
-  simgrid::s4u::on_simulation_end.connect(&on_simulation_end);
+  simgrid::s4u::Engine::on_simulation_end.connect(&on_simulation_end);
 }
 
 /** @ingroup plugin_energy
index 5f75e2a..7187920 100644 (file)
@@ -740,3 +740,14 @@ void sg_actor_unref(sg_actor_t actor)
 {
   intrusive_ptr_release(actor);
 }
+
+/** @brief Return the user data of a #sg_actor_t */
+void* sg_actor_data(sg_actor_t actor)
+{
+  return actor->get_data();
+}
+/** @brief Set the user data of a #sg_actor_t */
+void sg_actor_data_set(sg_actor_t actor, void* userdata)
+{
+  actor->set_data(userdata);
+}
index 64cb7f6..5339a77 100644 (file)
@@ -28,11 +28,11 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_engine, s4u, "Logging specific to S4U (engin
 
 namespace simgrid {
 namespace s4u {
-xbt::signal<void()> on_platform_creation;
-xbt::signal<void()> on_platform_created;
-xbt::signal<void()> on_simulation_end;
-xbt::signal<void(double)> on_time_advance;
-xbt::signal<void(void)> on_deadlock;
+xbt::signal<void()> Engine::on_platform_creation;
+xbt::signal<void()> Engine::on_platform_created;
+xbt::signal<void()> Engine::on_simulation_end;
+xbt::signal<void(double)> Engine::on_time_advance;
+xbt::signal<void(void)> Engine::on_deadlock;
 
 Engine* Engine::instance_ = nullptr; /* That singleton is awful, but I don't see no other solution right now. */
 
index 29eb24b..5e90311 100644 (file)
@@ -18,8 +18,6 @@
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_host, s4u, "Logging specific to the S4U hosts");
 XBT_LOG_EXTERNAL_CATEGORY(surf_route);
 
-int USER_HOST_LEVEL = -1;
-
 namespace simgrid {
 namespace xbt {
 template class Extendable<s4u::Host>;
@@ -387,17 +385,25 @@ xbt_dynar_t sg_hosts_as_dynar()
 // ========= Layering madness ==============*
 
 // ========== User data Layer ==========
-void* sg_host_user(sg_host_t host)
+void* sg_host_data(sg_host_t host)
+{
+  return host->get_data();
+}
+void sg_host_data_set(sg_host_t host, void* userdata)
+{
+  host->set_data(userdata);
+}
+void* sg_host_user(sg_host_t host) // deprecated
 {
-  return host->extension(USER_HOST_LEVEL);
+  return host->get_data();
 }
-void sg_host_user_set(sg_host_t host, void* userdata)
+void sg_host_user_set(sg_host_t host, void* userdata) // deprecated
 {
-  host->extension_set(USER_HOST_LEVEL, userdata);
+  host->set_data(userdata);
 }
-void sg_host_user_destroy(sg_host_t host)
+void sg_host_user_destroy(sg_host_t host) // deprecated
 {
-  host->extension_set(USER_HOST_LEVEL, nullptr);
+  host->set_data(nullptr);
 }
 
 // ========= storage related functions ============
index 4fecbd4..bb48a1b 100644 (file)
@@ -83,15 +83,6 @@ bool Link::is_on() const
   return this->pimpl_->is_on();
 }
 
-void* Link::get_data()
-{
-  return this->pimpl_->get_data();
-}
-void Link::set_data(void* d)
-{
-  simgrid::kernel::actor::simcall([this, d]() { this->pimpl_->set_data(d); });
-}
-
 void Link::set_state_profile(kernel::profile::Profile* profile)
 {
   simgrid::kernel::actor::simcall([this, profile]() { this->pimpl_->set_state_profile(profile); });
index 30f3d47..4028e9a 100644 (file)
@@ -238,7 +238,7 @@ void SIMIX_global_init(int *argc, char **argv)
 #endif
     /* register a function to be called by SURF after the environment creation */
     sg_platf_init();
-    simgrid::s4u::on_platform_created.connect(surf_presolve);
+    simgrid::s4u::Engine::on_platform_created.connect(surf_presolve);
 
     simgrid::s4u::Storage::on_creation.connect([](simgrid::s4u::Storage const& storage) {
       sg_storage_t s = simgrid::s4u::Storage::by_name(storage.get_name());
@@ -522,10 +522,10 @@ void SIMIX_run()
       XBT_CRITICAL("Oops! Deadlock or code not perfectly clean.");
     }
     SIMIX_display_process_status();
-    simgrid::s4u::on_deadlock();
+    simgrid::s4u::Engine::on_deadlock();
     xbt_abort();
   }
-  simgrid::s4u::on_simulation_end();
+  simgrid::s4u::Engine::on_simulation_end();
 }
 
 double SIMIX_timer_next()
index 6528fc9..f68549e 100644 (file)
@@ -44,6 +44,8 @@ class ActorExt {
   papi_counter_t papi_counter_data_;
 #endif
 public:
+  static simgrid::xbt::Extension<simgrid::s4u::Actor, ActorExt> EXTENSION_ID;
+
   explicit ActorExt(s4u::ActorPtr actor);
   ActorExt(const ActorExt&) = delete;
   ActorExt& operator=(const ActorExt&) = delete;
index c918f1a..bafd01b 100644 (file)
@@ -19,9 +19,13 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_process, smpi, "Logging specific to SMPI (k
 
 namespace simgrid {
 namespace smpi {
+simgrid::xbt::Extension<simgrid::s4u::Actor, ActorExt> ActorExt::EXTENSION_ID;
 
 ActorExt::ActorExt(s4u::ActorPtr actor) : actor_(actor)
 {
+  if (not simgrid::smpi::ActorExt::EXTENSION_ID.valid())
+    simgrid::smpi::ActorExt::EXTENSION_ID = simgrid::s4u::Actor::extension_create<simgrid::smpi::ActorExt>();
+
   mailbox_         = s4u::Mailbox::by_name("SMPI-" + std::to_string(actor_->get_pid()));
   mailbox_small_   = s4u::Mailbox::by_name("small-" + std::to_string(actor_->get_pid()));
   mailboxes_mutex_ = s4u::Mutex::create();
index 54f42e1..5e74b69 100644 (file)
@@ -61,13 +61,6 @@ void SMPI_app_instance_register(const char *name, xbt_main_func_t code, int num_
   if (code != nullptr) // When started with smpirun, we will not execute a function
     simgrid::s4u::Engine::get_instance()->register_function(name, code);
 
-  static bool already_called = false;
-  if (not already_called) {
-    already_called = true;
-    for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts())
-      host->extension_set(new simgrid::smpi::Host(host));
-  }
-
   Instance instance(std::string(name), num_processes, MPI_COMM_NULL);
 
   smpi_instances.insert(std::pair<std::string, Instance>(name, instance));
index 8144ad9..c1d5476 100644 (file)
@@ -82,7 +82,6 @@ std::map</* computation unit name */ std::string, papi_process_data> units2papi_
 
 std::unordered_map<std::string, double> location2speedup;
 
-static std::map</*process_id*/ simgrid::s4u::Actor const*, simgrid::smpi::ActorExt*> process_data;
 static int smpi_exit_status = 0;
 extern double smpi_total_benched_time;
 xbt_os_timer_t global_timer;
@@ -114,14 +113,14 @@ simgrid::smpi::ActorExt* smpi_process()
   if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...)
     return nullptr;
 
-  return process_data.at(me.get());
+  return me->extension<simgrid::smpi::ActorExt>();
 }
 
 simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor)
 {
   if (actor.get() == nullptr)
     return nullptr;
-  return process_data.at(actor.get());
+  return actor->extension<simgrid::smpi::ActorExt>();
 }
 
 MPI_Comm smpi_process_comm_self(){
@@ -620,10 +619,11 @@ int smpi_main(const char* executable, int argc, char* argv[])
   TRACE_global_init();
   SIMIX_global_init(&argc, argv);
 
+  auto engine              = simgrid::s4u::Engine::get_instance();
   SMPI_switch_data_segment = &smpi_switch_data_segment;
   sg_storage_file_system_init();
   // parse the platform file: get the host list
-  simgrid::s4u::Engine::get_instance()->load_platform(argv[1]);
+  engine->load_platform(argv[1]);
   SIMIX_comm_set_copy_data_callback(smpi_comm_copy_buffer_callback);
 
   smpi_init_options();
@@ -633,9 +633,16 @@ int smpi_main(const char* executable, int argc, char* argv[])
     smpi_init_privatization_no_dlopen(executable);
 
   SMPI_init();
-  simgrid::s4u::Engine::get_instance()->load_deployment(argv[2]);
-  SMPI_app_instance_register(smpi_default_instance_name.c_str(), nullptr,
-                             process_data.size()); // This call has a side effect on process_count...
+
+  /* This is a ... heavy way to count the MPI ranks */
+  int rank_counts = 0;
+  simgrid::s4u::Actor::on_creation.connect([&rank_counts](simgrid::s4u::Actor& actor) {
+    if (not actor.is_daemon())
+      rank_counts++;
+  });
+  engine->load_deployment(argv[2]);
+
+  SMPI_app_instance_register(smpi_default_instance_name.c_str(), nullptr, rank_counts);
   MPI_COMM_WORLD = *smpi_deployment_comm_world(smpi_default_instance_name);
 
   /* Clean IO before the run */
@@ -669,20 +676,13 @@ int smpi_main(const char* executable, int argc, char* argv[])
 // Called either directly from the user code, or from the code called by smpirun
 void SMPI_init(){
   simgrid::s4u::Actor::on_creation.connect([](simgrid::s4u::Actor& actor) {
-    if (not actor.is_daemon()) {
-      process_data.insert({&actor, new simgrid::smpi::ActorExt(&actor)});
-    }
-  });
-  simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::Actor const& actor) {
-    XBT_DEBUG("Delete the extension of actor %s", actor.get_cname());
-    auto it = process_data.find(&actor);
-    if (it != process_data.end()) {
-      delete it->second;
-      process_data.erase(it);
-    }
+    if (not actor.is_daemon())
+      actor.extension_set<simgrid::smpi::ActorExt>(new simgrid::smpi::ActorExt(&actor));
   });
   simgrid::s4u::Host::on_creation.connect(
       [](simgrid::s4u::Host& host) { host.extension_set(new simgrid::smpi::Host(&host)); });
+  for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts())
+    host->extension_set(new simgrid::smpi::Host(host));
 
   smpi_init_options();
   if (not MC_is_active()) {
index d112d2b..c473874 100644 (file)
@@ -109,7 +109,6 @@ public:
  */
 class LinkImpl : public Resource, public surf::PropertyHolder {
   bool currently_destroying_ = false;
-  void* userdata_            = nullptr;
 
 protected:
   LinkImpl(NetworkModel* model, const std::string& name, lmm::Constraint* constraint);
@@ -119,8 +118,6 @@ protected:
 
 public:
   void destroy(); // Must be called instead of the destructor
-  void* get_data() { return userdata_; }
-  void set_data(void* d) { userdata_ = d; }
 
   /** @brief Public interface */
   s4u::Link piface_;
index 31580ea..7416223 100644 (file)
@@ -167,7 +167,7 @@ NetworkNS3Model::NetworkNS3Model() : NetworkModel(Model::UpdateAlgo::FULL)
   });
   surf::on_cluster.connect(&clusterCreation_cb);
 
-  s4u::on_platform_created.connect(&postparse_cb);
+  s4u::Engine::on_platform_created.connect(&postparse_cb);
   s4u::NetZone::on_route_creation.connect(&routeCreation_cb);
 }
 
index 4201ba0..b91dbb0 100644 (file)
@@ -51,13 +51,13 @@ static simgrid::kernel::routing::NetZoneImpl* routing_get_current()
 /** Module management function: creates all internal data structures */
 void sg_platf_init()
 {
-  simgrid::s4u::on_platform_created.connect(check_disk_attachment);
+  simgrid::s4u::Engine::on_platform_created.connect(check_disk_attachment);
 }
 
 /** Module management function: frees all internal data structures */
 void sg_platf_exit() {
   simgrid::surf::on_cluster.disconnect_slots();
-  simgrid::s4u::on_platform_created.disconnect_slots();
+  simgrid::s4u::Engine::on_platform_created.disconnect_slots();
 
   /* make sure that we will reinit the models while loading the platf once reinited */
   surf_parse_models_setup_already_called = 0;
@@ -548,7 +548,7 @@ static void surf_config_models_setup()
 simgrid::kernel::routing::NetZoneImpl* sg_platf_new_Zone_begin(simgrid::kernel::routing::ZoneCreationArgs* zone)
 {
   if (not surf_parse_models_setup_already_called) {
-    simgrid::s4u::on_platform_creation();
+    simgrid::s4u::Engine::on_platform_creation();
 
     /* Initialize the surf models. That must be done after we got all config, and before we need the models.
      * That is, after the last <config> tag, if any, and before the first of cluster|peer|zone|trace|trace_connect
index b0a8280..3b80a2d 100644 (file)
@@ -143,7 +143,7 @@ double surf_solve(double max_date)
   for (auto const& model : all_existing_models)
     model->update_actions_state(NOW, time_delta);
 
-  simgrid::s4u::on_time_advance(time_delta);
+  simgrid::s4u::Engine::on_time_advance(time_delta);
 
   TRACE_paje_dump_buffer(false);
 
index b657ce6..6123158 100644 (file)
@@ -12,6 +12,7 @@
 #include "src/simgrid/version.h"
 #include "src/surf/HostImpl.hpp"
 #include "src/surf/xml/platf.hpp"
+#include "src/xbt_modinter.h" /* whether initialization was already done */
 #include "surf/surf.hpp"
 #include "xbt/module.h"
 
@@ -287,12 +288,9 @@ void sg_version()
 
 void surf_init(int *argc, char **argv)
 {
-  if (USER_HOST_LEVEL != -1) // Already initialized
+  if (xbt_initialized > 0)
     return;
 
-  XBT_DEBUG("Create all Libs");
-  USER_HOST_LEVEL = simgrid::s4u::Host::extension_create(nullptr);
-
   xbt_init(argc, argv);
 
   sg_config_init(argc, argv);
index e5f1c15..ce18fa9 100644 (file)
@@ -409,7 +409,7 @@ void STag_surfxml_platform() {
              surf_parsed_filename.c_str(), version);
 }
 void ETag_surfxml_platform(){
-  simgrid::s4u::on_platform_created();
+  simgrid::s4u::Engine::on_platform_created();
 }
 
 void STag_surfxml_host(){
index 94661db..c89f325 100644 (file)
@@ -140,7 +140,8 @@ void install_exception_handler()
 void xbt_throw_impossible(const char* file, int line, const char* func)
 {
   std::stringstream ss;
-  ss << file << ":" << line << ":" << func << ": The Impossible Did Happen (yet again). Please report this bug.";
+  ss << file << ":" << line << ":" << func
+     << ": The Impossible Did Happen (yet again). Please report this bug (after reading https://xkcd.com/2200 :)";
   throw simgrid::xbt::ImpossibleError(ss.str());
 }
 void xbt_throw_unimplemented(const char* file, int line, const char* func)
index d60ccb0..bfdf869 100644 (file)
@@ -116,14 +116,14 @@ static void xbt_postexit()
 /** @brief Initialize the xbt mechanisms. */
 void xbt_init(int *argc, char **argv)
 {
-  simgrid::xbt::install_exception_handler();
-
   xbt_initialized++;
   if (xbt_initialized > 1) {
     XBT_DEBUG("XBT has been initialized %d times.", xbt_initialized);
     return;
   }
 
+  simgrid::xbt::install_exception_handler();
+
   xbt_binary_name = argv[0];
   xbt_cmdline     = xbt_dynar_new(sizeof(char*), NULL);
   for (int i = 0; i < *argc; i++)
index 03294d0..b9c1d9f 100644 (file)
@@ -12,7 +12,7 @@
 XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this msg example");
 
 const int FAIL_ON_ERROR = 0;
-const int flop_amount = 100000000;
+const int flop_amount   = 100000000; // 100Mf, so that computing this on a 1Gf core takes exactly 0.1s
 int failed_test = 0;
 
 double energy = 0;
index 99f5976..cb7a0c2 100644 (file)
@@ -60,6 +60,9 @@ endif()
 if(enable_compile_warnings AND enable_debug)
   set(warnCFLAGS "${warnCFLAGS} -Werror")
   set(warnCXXFLAGS "${warnCXXFLAGS} -Werror")
+  if(CMAKE_Fortran_COMPILER_ID MATCHES "GCC")
+    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Werror -Werror=format-security")
+  endif()
 endif()
 
 # Activate the warnings on #if FOOBAR when FOOBAR has no value
index ae1f81b..d2f54c1 100755 (executable)
@@ -102,18 +102,4 @@ if [ -f Testing/TAG ] ; then
    #generate sloccount report
    sloccount --duplicates --wide --details $WORKSPACE | grep -v -e '.git' -e 'mpich3-test' -e 'sloccount.sc' -e 'isp/umpire' -e 'build/' -e 'xml_coverage.xml' -e 'CTestResults_memcheck.xml' -e 'DynamicAnalysis.xml' > $WORKSPACE/sloccount.sc
 
-   #upload files to codacy. CODACY_PROJECT_TOKEN must be setup !
-   if ! [ -z $CODACY_PROJECT_TOKEN ]
-   then 
-     for report in $BUILDFOLDER/java_cov*
-     do
-       if [ ! -e "$report" ]; then continue; fi
-       java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l Java -r $report --partial
-     done
-     java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar final
-
-     java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l Python -r $BUILDFOLDER/python_coverage.xml
-     java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l C -f -r $BUILDFOLDER/xml_coverage.xml
-     java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l CPP -f -r $BUILDFOLDER/xml_coverage.xml
-   fi
 fi || exit 42