Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[simix] Make host->{on,off}() do the simcall directly
authorGabriel Corona <gabriel.corona@loria.fr>
Tue, 5 Jan 2016 13:04:00 +0000 (14:04 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Tue, 5 Jan 2016 14:41:23 +0000 (15:41 +0100)
include/simgrid/Host.hpp
include/simgrid/simix.h
src/msg/msg_host.cpp
src/s4u/s4u_host.cpp
src/simgrid/host.cpp
src/simix/libsmx.cpp
src/simix/popping_private.h
src/simix/smx_private.hpp

index 99494dc..d8d68c8 100644 (file)
@@ -35,6 +35,8 @@ public:
   Host(std::string const& name);
   ~Host();
   simgrid::xbt::string const& getName() const { return name_; }
+  void on();
+  void off();
   static Host* by_name_or_null(const char* name);
   static Host* by_name_or_create(const char* name);
 };
index 0e3117d..b94dec0 100644 (file)
@@ -249,11 +249,11 @@ XBT_PUBLIC(void) SIMIX_comm_finish(smx_synchro_t synchro);
 /* They can also be called from maestro's context, and they are thread safe.  */
 /******************************************************************************/
 
+XBT_PUBLIC(void) simcall_call(smx_process_t process);
+
 /******************************* Host simcalls ********************************/
 /* TODO use handlers and keep sg_host_t hidden from higher levels */
 XBT_PUBLIC(xbt_dict_t) simcall_host_get_properties(sg_host_t host);
-XBT_PUBLIC(void) simcall_host_on(sg_host_t host);
-XBT_PUBLIC(void) simcall_host_off(sg_host_t host);
 XBT_PUBLIC(xbt_swag_t) simcall_host_get_process_list(sg_host_t host);
 
 XBT_PUBLIC(void) simcall_host_set_data(sg_host_t host, void *data);
index db76c66..06716bb 100644 (file)
@@ -128,7 +128,7 @@ msg_host_t MSG_host_self(void)
  */
 void MSG_host_on(msg_host_t host)
 {
-  simcall_host_on(host);
+  host->on();
 }
 
 /** \ingroup m_host_management
@@ -139,7 +139,7 @@ void MSG_host_on(msg_host_t host)
  */
 void MSG_host_off(msg_host_t host)
 {
-  simcall_host_off(host);
+  host->off();
 }
 
 /*
index 6f35dfb..f075483 100644 (file)
@@ -53,10 +53,10 @@ const char* Host::name() {
 }
 
 void Host::turnOn() {
-       simcall_host_on(p_inferior);
+       p_inferior->on();
 }
 void Host::turnOff() {
-       simcall_host_off(p_inferior);
+       p_inferior->off();
 }
 bool Host::isOn() {
        return sg_host_get_state(p_inferior);
index 5efe860..2f70c60 100644 (file)
@@ -4,11 +4,15 @@
 /* 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. */
 
+#include <simgrid/simix.hpp>
+
 #include "xbt/dict.h"
 #include "simgrid/host.h"
 #include "simgrid/Host.hpp"
 #include "surf/surf.h" // routing_get_network_element_type FIXME:killme
 
+#include "src/simix/smx_private.hpp"
+
 size_t sg_host_count()
 {
   return xbt_dict_length(host_list);
@@ -172,6 +176,20 @@ Host::~Host()
 {
 }
 
+/** Start the host if it is off */
+void Host::on()
+{
+  simgrid::simix::kernel(std::bind(SIMIX_host_on, this));
+}
+
+/** Stop the host if it is on */
+void Host::off()
+{
+  /* Go to that function to follow the code flow through the simcall barrier */
+  if (0) simcall_HANDLER_host_off(&SIMIX_process_self()->simcall, this);
+  simgrid::simix::simcall<void>(SIMCALL_HOST_OFF, this);
+}
+
 /** @brief Get the speed of the cpu associated to a host */
 double Host::getSpeed() {
        return p_cpu->getSpeed(1.0);
index e4fd1a6..f6d5d73 100644 (file)
@@ -20,6 +20,7 @@
 #include <math.h>         /* isfinite() */
 #include "mc/mc.h"
 #include "src/simix/smx_host_private.h"
+#include "src/simix/smx_private.hpp"
 
 #include <simgrid/simix.hpp>
 
@@ -27,26 +28,15 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
 
 #include "popping_bodies.cpp"
 
-/**
- * \ingroup simix_host_management
- * \brief Start the host if it is off
- *
- * \param host A SIMIX host
- */
-void simcall_host_on(sg_host_t host)
-{
-  return simgrid::simix::kernel(std::bind(SIMIX_host_on, host));
-}
-
-/**
- * \ingroup simix_host_management
- * \brief Stop the host if it is on
- *
- * \param host A SIMIX host
- */
-void simcall_host_off(sg_host_t host)
+void simcall_call(smx_process_t process)
 {
-  simcall_BODY_host_off(host);
+  if (process != simix_global->maestro_process) {
+    XBT_DEBUG("Yield process '%s' on simcall %s (%d)", process->name,
+              SIMIX_simcall_name(process->simcall.call), (int)process->simcall.call);
+    SIMIX_process_yield(process);
+  } else {
+    SIMIX_simcall_handle(&process->simcall, 0);
+  }
 }
 
 /**
index 1a2d667..c563ac8 100644 (file)
@@ -69,4 +69,181 @@ XBT_PRIVATE void SIMIX_run_kernel(void* code);
 
 SG_END_DECL()
 
+#ifdef __cplusplus
+
+namespace simgrid {
+namespace simix {
+
+template<typename T> struct marshal_t {};
+#define SIMIX_MARSHAL(T, field) \
+  template<> struct marshal_t<T> { \
+    static void marshal(u_smx_scalar& simcall, T value) \
+    { \
+      simcall.field = value; \
+    } \
+    static T unmarshal(u_smx_scalar const& simcall) \
+    { \
+      return simcall.field; \
+    } \
+  };
+
+SIMIX_MARSHAL(char, c);
+SIMIX_MARSHAL(short, s);
+SIMIX_MARSHAL(int, i);
+SIMIX_MARSHAL(long, l);
+SIMIX_MARSHAL(unsigned char, uc);
+SIMIX_MARSHAL(unsigned short, us);
+SIMIX_MARSHAL(unsigned int, ui);
+SIMIX_MARSHAL(unsigned long, ul);
+SIMIX_MARSHAL(float, f);
+SIMIX_MARSHAL(double, d);
+SIMIX_MARSHAL(FPtr, fp);
+
+template<typename T> struct marshal_t<T*> {
+  static void marshal(u_smx_scalar& simcall, T* value)
+  {
+    simcall.dp = value;
+  }
+  static T* unmarshal(u_smx_scalar const& simcall)
+  {
+    return simcall.dp;
+  }
+};
+
+template<> struct marshal_t<void> {
+  static void unmarshal(u_smx_scalar const& simcall) {}
+};
+
+template<class T> inline
+void marshal(u_smx_scalar& simcall, T const& value)
+{
+  marshal_t<T>::marshal(simcall, value);
+}
+
+template<class T> inline
+T unmarshal(u_smx_scalar const& simcall)
+{
+  return marshal_t<T>::unmarshal(simcall);
+}
+
+template<class A> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+}
+
+template<class A, class B> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a, B&& b)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+  marshal(simcall->args[1], std::forward<B>(b));
+}
+
+template<class A, class B, class C> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a, B&& b, C&& c)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+  marshal(simcall->args[1], std::forward<B>(b));
+  marshal(simcall->args[2], std::forward<C>(c));
+}
+
+template<class A, class B, class C, class D> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a, B&& b, C&& c, D&& d)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+  marshal(simcall->args[1], std::forward<B>(b));
+  marshal(simcall->args[2], std::forward<C>(c));
+  marshal(simcall->args[3], std::forward<D>(d));
+}
+
+template<class A, class B, class C, class D, class E> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a, B&& b, C&& c, D&& d, E&& e)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+  marshal(simcall->args[1], std::forward<B>(b));
+  marshal(simcall->args[2], std::forward<C>(c));
+  marshal(simcall->args[3], std::forward<D>(d));
+  marshal(simcall->args[4], std::forward<E>(e));
+}
+
+template<class A, class B, class C, class D, class E, class F> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call,
+  A&& a, B&& b, C&& c, D&& d, E&& e, F&& f)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+  marshal(simcall->args[1], std::forward<B>(b));
+  marshal(simcall->args[2], std::forward<C>(c));
+  marshal(simcall->args[3], std::forward<D>(d));
+  marshal(simcall->args[4], std::forward<E>(e));
+  marshal(simcall->args[5], std::forward<F>(f));
+}
+
+template<class A, class B, class C, class D, class E, class F, class G> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call,
+  A&& a, B&& b, C&& c, D&& d, E&& e, F&& f, G&& g)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+  marshal(simcall->args[1], std::forward<B>(b));
+  marshal(simcall->args[2], std::forward<C>(c));
+  marshal(simcall->args[3], std::forward<D>(d));
+  marshal(simcall->args[4], std::forward<E>(e));
+  marshal(simcall->args[5], std::forward<F>(f));
+  marshal(simcall->args[6], std::forward<G>(g));
+}
+
+template<class A, class B, class C,
+          class D, class E, class F, class G, class H> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call,
+  A&& a, B&& b, C&& c, D&& d, E&& e, F&& f, G&& g, H&& h)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+  marshal(simcall->args[1], std::forward<B>(b));
+  marshal(simcall->args[2], std::forward<C>(c));
+  marshal(simcall->args[3], std::forward<D>(d));
+  marshal(simcall->args[4], std::forward<E>(e));
+  marshal(simcall->args[5], std::forward<F>(f));
+  marshal(simcall->args[6], std::forward<G>(g));
+  marshal(simcall->args[7], std::forward<H>(h));
+}
+
+template<class A, class B, class C,
+          class D, class E, class F,
+          class G, class H, class I> inline
+void marshal(smx_simcall_t simcall, e_smx_simcall_t call,
+  A&& a, B&& b, C&& c, D&& d, E&& e, F&& f, G&& g, H&& h, I&& i)
+{
+  simcall->call = call;
+  memset(&simcall->result, 0, sizeof(simcall->result));
+  marshal(simcall->args[0], std::forward<A>(a));
+  marshal(simcall->args[1], std::forward<B>(b));
+  marshal(simcall->args[2], std::forward<C>(c));
+  marshal(simcall->args[3], std::forward<D>(d));
+  marshal(simcall->args[4], std::forward<E>(e));
+  marshal(simcall->args[5], std::forward<F>(f));
+  marshal(simcall->args[6], std::forward<G>(g));
+  marshal(simcall->args[7], std::forward<H>(h));
+  marshal(simcall->args[8], std::forward<I>(i));
+}
+
+}
+}
+
+#endif
+
 #endif
index a6051cc..255105f 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <simgrid/simix.hpp>
 #include "smx_private.h"
+#include "src/simix/popping_private.h"
 
 /**
  * \brief destroy a context
@@ -77,6 +78,15 @@ XBT_PRIVATE ContextFactory* sysv_factory();
 XBT_PRIVATE ContextFactory* raw_factory();
 XBT_PRIVATE ContextFactory* boost_factory();
 
+template<class R, class... Args> inline
+R simcall(e_smx_simcall_t call, Args&&... args)
+{
+  smx_process_t self = SIMIX_process_self();
+  marshal(&self->simcall, call, std::forward<Args>(args)...);
+  simcall_call(self);
+  return unmarshal<R>(self->simcall.result);
+}
+
 }
 }