X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/f9d7b35c174d52377ef297f786129e0340ae0778..7d12748cce3a184f60108fa8b12e0f78c6971b77:/include/simgrid/simix.hpp diff --git a/include/simgrid/simix.hpp b/include/simgrid/simix.hpp index 5fbc4d5fd8..2f19728b8d 100644 --- a/include/simgrid/simix.hpp +++ b/include/simgrid/simix.hpp @@ -24,18 +24,57 @@ XBT_PUBLIC(void) simcall_run_kernel(std::function const& code); namespace simgrid { namespace simix { +/** Fulfill a promise by executing a given code */ +template +void fulfill_promise(std::promise& promise, F&& code) +{ + try { + promise.set_value(std::forward(code)()); + } + catch(...) { + promise.set_exception(std::current_exception()); + } +} + +/** Fulfill a promise by executing a given code + * + * This is a special version for `std::promise` because the default + * version does not compile in this case. + */ +template +void fulfill_promise(std::promise& promise, F&& code) +{ + try { + std::forward(code)(); + promise.set_value(); + } + catch(...) { + promise.set_exception(std::current_exception()); + } +} + +/** Execute some code in the kernel/maestro + * + * This can be used to enforce mutual exclusion with other simcall. + * More importantly, this enforces a deterministic/reproducible ordering + * of the operation with respect to other simcalls. + */ template typename std::result_of::type kernel(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(code)(); + + // If we are in the application, pass the code to the maestro which is + // 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::type R; std::promise promise; simcall_run_kernel([&]{ - try { - promise.set_value(code()); - } - catch(...) { - promise.set_exception(std::current_exception()); - } + xbt_assert(SIMIX_is_maestro(), "Not in maestro"); + fulfill_promise(promise, std::forward(code)); }); return promise.get_future().get(); } @@ -43,7 +82,7 @@ typename std::result_of::type kernel(F&& code) class Context; class ContextFactory; -class ContextFactory { +XBT_PUBLIC_CLASS ContextFactory { private: std::string name_; public: @@ -70,7 +109,7 @@ protected: } }; -class Context { +XBT_PUBLIC_CLASS Context { private: std::function code_; void_pfn_smxprocess_t cleanup_func_ = nullptr; @@ -107,4 +146,4 @@ public: } } -#endif \ No newline at end of file +#endif