Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[cmake] fix make dist
[simgrid.git] / include / simgrid / simix.hpp
1 /* Copyright (c) 2007-2010, 2012-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #ifndef SIMGRID_SIMIX_HPP
8 #define SIMGRID_SIMIX_HPP
9
10 #include <cstddef>
11
12 #include <string>
13 #include <utility>
14 #include <memory>
15 #include <functional>
16 #include <future>
17 #include <type_traits>
18
19 #include <xbt/function_types.h>
20 #include <simgrid/simix.h>
21
22 XBT_PUBLIC(void) simcall_run_kernel(std::function<void()> const& code);
23
24 namespace simgrid {
25 namespace simix {
26
27 template<class R, class F>
28 void fulfill_promise(std::promise<R>& promise, F&& code)
29 {
30   try {
31     promise.set_value(code());
32   }
33   catch(...) {
34     promise.set_exception(std::current_exception());
35   }
36 }
37
38 // special version for R=void because the previous code does not compile
39 // in this case:
40 template<class F>
41 void fulfill_promise(std::promise<void>& promise, F&& code)
42 {
43   try {
44     code();
45     promise.set_value();
46   }
47   catch(...) {
48     promise.set_exception(std::current_exception());
49   }
50 }
51
52 template<class F>
53 typename std::result_of<F()>::type kernel(F&& code)
54 {
55   typedef typename std::result_of<F()>::type R;
56   std::promise<R> promise;
57   simcall_run_kernel([&]{
58     xbt_assert(SIMIX_is_maestro(), "Not in maestro");
59     fulfill_promise(promise, code);
60   });
61   return promise.get_future().get();
62 }
63
64 class Context;
65 class ContextFactory;
66
67 class ContextFactory {
68 private:
69   std::string name_;
70 public:
71
72   ContextFactory(std::string name) : name_(std::move(name)) {}
73   virtual ~ContextFactory();
74   virtual Context* create_context(std::function<void()> code,
75     void_pfn_smxprocess_t cleanup, smx_process_t process) = 0;
76   virtual void run_all() = 0;
77   virtual Context* self();
78   std::string const& name() const
79   {
80     return name_;
81   }
82 private:
83   void declare_context(void* T, std::size_t size);
84 protected:
85   template<class T, class... Args>
86   T* new_context(Args&&... args)
87   {
88     T* context = new T(std::forward<Args>(args)...);
89     this->declare_context(context, sizeof(T));
90     return context;
91   }
92 };
93
94 class Context {
95 private:
96   std::function<void()> code_;
97   void_pfn_smxprocess_t cleanup_func_ = nullptr;
98   smx_process_t process_ = nullptr;
99 public:
100   bool iwannadie;
101 public:
102   Context(std::function<void()> code,
103           void_pfn_smxprocess_t cleanup_func,
104           smx_process_t process);
105   void operator()()
106   {
107     code_();
108   }
109   bool has_code() const
110   {
111     return (bool) code_;
112   }
113   smx_process_t process()
114   {
115     return this->process_;
116   }
117   void set_cleanup(void_pfn_smxprocess_t cleanup)
118   {
119     cleanup_func_ = cleanup;
120   }
121
122   // Virtual methods
123   virtual ~Context();
124   virtual void stop();
125   virtual void suspend() = 0;
126 };
127
128 }
129 }
130
131 #endif