Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[simix] Update TODO for simgrid::simix::Future
[simgrid.git] / include / simgrid / simix.hpp
index ad30d41..99d2410 100644 (file)
@@ -9,13 +9,11 @@
 
 #include <cstddef>
 
-#include <exception>
 #include <string>
 #include <utility>
 #include <memory>
 #include <functional>
 #include <future>
-#include <type_traits>
 
 #include <xbt/function_types.h>
 #include <xbt/future.hpp>
 
 XBT_PUBLIC(void) simcall_run_kernel(std::function<void()> const& code);
 
+/** Execute some code in the kernel and block
+ *
+ * run_blocking() is a generic blocking simcall. It is given a callback
+ * which is executed immediately in the SimGrid kernel. The callback is
+ * responsible for setting the suitable logic for waking up the process
+ * when needed.
+ *
+ * @ref simix::kernelSync() is a higher level wrapper for this.
+ */
+XBT_PUBLIC(void) simcall_run_blocking(std::function<void()> const& code);
+
+template<class F> inline
+void simcall_run_kernel(F& f)
+{
+  simcall_run_kernel(std::function<void()>(std::ref(f)));
+}
+template<class F> inline
+void simcall_run_blocking(F& f)
+{
+  simcall_run_blocking(std::function<void()>(std::ref(f)));
+}
+
 namespace simgrid {
+
 namespace simix {
 
 /** Execute some code in the kernel/maestro
@@ -34,23 +55,23 @@ namespace simix {
  *  of the operation with respect to other simcalls.
  */
 template<class F>
-typename std::result_of<F()>::type kernel(F&& code)
+typename std::result_of<F()>::type kernelImmediate(F&& code)
 {
   // If we are in the maestro, we take the fast path and execute the
   // code directly without simcall mashalling/unmarshalling/dispatch:
   if (SIMIX_is_maestro())
     return std::forward<F>(code)();
 
-  // If we are in the application, pass the code to the maestro which is
+  // If we are in the application, pass the code to the maestro which
   // executes it for us and reports the result. We use a std::future which
   // conveniently handles the success/failure value for us.
   typedef typename std::result_of<F()>::type R;
-  std::promise<R> promise;
+  simgrid::xbt::Result<R> result;
   simcall_run_kernel([&]{
     xbt_assert(SIMIX_is_maestro(), "Not in maestro");
-    simgrid::xbt::fulfillPromise(promise, std::forward<F>(code));
+    simgrid::xbt::fulfillPromise(result, std::forward<F>(code));
   });
-  return promise.get_future().get();
+  return result.get();
 }
 
 class Context;
@@ -61,7 +82,7 @@ private:
   std::string name_;
 public:
 
-  ContextFactory(std::string name) : name_(std::move(name)) {}
+  explicit ContextFactory(std::string name) : name_(std::move(name)) {}
   virtual ~ContextFactory();
   virtual Context* create_context(std::function<void()> code,
     void_pfn_smxprocess_t cleanup, smx_process_t process) = 0;
@@ -136,7 +157,7 @@ public:
     : Context(std::move(code), cleanup_func, process)
   {}
 
-  ~AttachContext();
+  ~AttachContext() override;
 
   /** Called by the context when it is ready to give control
    *  to the maestro.
@@ -185,7 +206,13 @@ XBT_PUBLIC(smx_process_t) simcall_process_create(const char *name,
                                           xbt_dict_t properties,
                                           int auto_restart);
 
-XBT_PUBLIC(smx_timer_t) SIMIX_timer_set(double date, std::function<void()> callback);
+XBT_PUBLIC(smx_timer_t) SIMIX_timer_set(double date, std::packaged_task<void()> callback);
+
+template<class F> inline
+XBT_PUBLIC(smx_timer_t) SIMIX_timer_set(double date, F callback)
+{
+  return SIMIX_timer_set(date, std::packaged_task<void()>(std::move(callback)));
+}
 
 template<class R, class T> inline
 XBT_PUBLIC(smx_timer_t) SIMIX_timer_set(double date, R(*callback)(T*), T* arg)