Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
0cdf6ea490eacf333b5b0c6d4e2054aacc09f659
[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     fulfill_promise(promise, code);
59   });
60   return promise.get_future().get();
61 }
62
63 class Context;
64 class ContextFactory;
65
66 class ContextFactory {
67 private:
68   std::string name_;
69 public:
70
71   ContextFactory(std::string name) : name_(std::move(name)) {}
72   virtual ~ContextFactory();
73   virtual Context* create_context(std::function<void()> code,
74     void_pfn_smxprocess_t cleanup, smx_process_t process) = 0;
75   virtual void run_all() = 0;
76   virtual Context* self();
77   std::string const& name() const
78   {
79     return name_;
80   }
81 private:
82   void declare_context(void* T, std::size_t size);
83 protected:
84   template<class T, class... Args>
85   T* new_context(Args&&... args)
86   {
87     T* context = new T(std::forward<Args>(args)...);
88     this->declare_context(context, sizeof(T));
89     return context;
90   }
91 };
92
93 class Context {
94 private:
95   std::function<void()> code_;
96   void_pfn_smxprocess_t cleanup_func_ = nullptr;
97   smx_process_t process_ = nullptr;
98 public:
99   bool iwannadie;
100 public:
101   Context(std::function<void()> code,
102           void_pfn_smxprocess_t cleanup_func,
103           smx_process_t process);
104   void operator()()
105   {
106     code_();
107   }
108   bool has_code() const
109   {
110     return (bool) code_;
111   }
112   smx_process_t process()
113   {
114     return this->process_;
115   }
116   void set_cleanup(void_pfn_smxprocess_t cleanup)
117   {
118     cleanup_func_ = cleanup;
119   }
120
121   // Virtual methods
122   virtual ~Context();
123   virtual void stop();
124   virtual void suspend() = 0;
125 };
126
127 }
128 }
129
130 #endif