+ // 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;
+ simgrid::xbt::Result<R> result;
+ simcall_run_kernel([&result, &code] { simgrid::xbt::fulfill_promise(result, std::forward<F>(code)); });
+ return result.get();
+}
+
+/** Execute some code (that does not return immediately) in kernel context
+ *
+ * This is very similar to simcall() right above, but the calling actor will not get rescheduled until
+ * actor->simcall_answer() is called explicitely.
+ *
+ * This is meant for blocking actions. For example, locking a mutex is a blocking simcall.
+ * First it's a simcall because that's obviously a modification of the world. Then, that's a blocking simcall because if
+ * the mutex happens not to be free, the actor is added to a queue of actors in the mutex. Every mutex->unlock() takes
+ * the first actor from the queue, mark it as current owner of the mutex and call actor->simcall_answer() to mark that
+ * this mutex is now unblocked and ready to run again. If the mutex is initially free, the calling actor is unblocked
+ * right away with actor->simcall_answer() once the mutex is marked as locked.
+ *
+ * If your code never calls actor->simcall_answer() itself, the actor will never return from its simcall.
+ */
+template <class F> typename std::result_of<F()>::type simcall_blocking(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
+ // 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;
+ simgrid::xbt::Result<R> result;
+ simcall_run_blocking([&result, &code] { simgrid::xbt::fulfill_promise(result, std::forward<F>(code)); });
+ return result.get();
+}
+
+XBT_ATTRIB_DEPRECATED_v325("Please manifest if you actually need this function")
+ XBT_PUBLIC const std::vector<smx_actor_t>& process_get_runnable();
+
+// What's executed as SIMIX actor code:
+typedef std::function<void()> ActorCode;
+
+// Create an ActorCode based on a std::string
+typedef std::function<ActorCode(std::vector<std::string> args)> ActorCodeFactory;
+
+XBT_PUBLIC void register_function(const std::string& name, const ActorCodeFactory& factory);
+
+typedef std::pair<double, Timer*> TimerQelt;
+static boost::heap::fibonacci_heap<TimerQelt, boost::heap::compare<xbt::HeapComparator<TimerQelt>>> simix_timers;
+
+/** @brief Timer datatype */
+class Timer {
+ double date = 0.0;