-class Context;
-class ContextFactory;
-
-class ContextFactory {
-private:
- std::string name_;
-public:
-
- 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;
- virtual void run_all() = 0;
- virtual Context* self();
- std::string const& name() const
- {
- return name_;
- }
-private:
- void declare_context(void* T, std::size_t size);
-protected:
- template<class T, class... Args>
- T* new_context(Args&&... args)
- {
- T* context = new T(std::forward<Args>(args)...);
- this->declare_context(context, sizeof(T));
- return context;
- }
-};
-
-class Context {
-private:
- std::function<void()> code_;
- void_pfn_smxprocess_t cleanup_func_ = nullptr;
- smx_process_t process_ = nullptr;
-public:
- bool iwannadie;
-public:
- Context(std::function<void()> code,
- void_pfn_smxprocess_t cleanup_func,
- smx_process_t process);
- void operator()()
- {
- code_();
- }
- bool has_code() const
- {
- return (bool) code_;
- }
- smx_process_t process()
- {
- return this->process_;
- }
- void set_cleanup(void_pfn_smxprocess_t cleanup)
- {
- cleanup_func_ = cleanup;
- }
-
- // Virtual methods
- virtual ~Context();
- virtual void stop();
- virtual void suspend() = 0;
-};
+/** 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 <class F> typename std::result_of<F()>::type simcall(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)();