Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c022aec11dfdfac8a7cee414fd26c5a31598d28d
[simgrid.git] / doc / doxygen / uhood.doc
1 /*! @page uhood Under the Hood
2
3 \tableofcontents
4
5 TBD
6
7  - Simulation Loop, LMM, sharing -> papers
8  - Context Switching, privatization -> papers
9  - @subpage inside
10
11 \section simgrid_uhood_async Asynchronous operations
12
13 \subsection simgrid_uhood_futures Futures
14
15 The `simgrid::kernel::Future` class has been added to SimGrid as an abstraction
16 to represent asynchronous operations in the SimGrid maestro. Its API is based
17 on `std::experimental::future` from the [C++ Extensions for Concurrency Technical
18 Specification](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0159r0.html):
19
20  - `simgrid::kernel::Future<T>` represents the result an asynchronous operations
21     in the simulation inside the SimGrid maestro/kernel;
22
23  - `simgrid::kernel::Promise<T>` can be used to set the value of an assocaiated
24    `simgrid::kernel::Future<T>`.
25
26 The expected way to work with `simgrid::kernel::Future<T>` is to add a
27 completion handler/continuation:
28
29 ~~~
30 // This code is executed in the maestro context, we cannot block for the result
31 // to be ready:
32 simgrid::kernel::Future<std::vector<char>> result = simgrid::kernel::readFile(file);
33
34 // Add a completion handler:
35 result.then([file](simgrid::kernel::Future<std::vector<char>> result) {
36   // At this point, the operation is complete and we can safely call .get():
37   xbt_assert(result.is_ready());
38   try {
39     std::vector<char> data = result.get();
40     XBT_DEBUG("Finished reading file %s: length %zu", file.c_str(), data.size());
41   }
42   // If the operation failed, .get() throws an exception:
43   catch (std::runtime_error& e) {
44     XBT_ERROR("Could not read file %s", file.c_str());
45   }
46 });
47 ~~~
48
49 The SimGrid kernel cannot block so calling `.get()` or `.wait()` on a
50 `simgrid::kernel::Future<T>` which is not ready will deadlock. In practice, the
51 simulator detects this and aborts after reporting an error.
52
53 In order to generate your own future, you might need to use a
54 `simgrid::kernel::Promise<T>`. The promise is a one-way channel which can be
55 used to set the result of an associated `simgrid::kernel::Future<T>`
56 (with either `.set_value()` or `.set_exception()`):
57
58 ~~~
59 simgrid::kernel::Future<void> kernel_wait_until(double date)
60 {
61   auto promise = std::make_shared<simgrid::kernel::Promise<void>>();
62   auto future = promise->get_future();
63   SIMIX_timer_set(date, [promise] {
64     promise->set_value();
65   });
66   return future;
67 }
68 ~~~
69
70 Like the experimental futures, we support chaining `.then()` methods with
71 automatic future unwrapping.
72 You might want to look at some [C++ tutorial on futures](https://www.youtube.com/watch?v=mPxIegd9J3w&list=PLHTh1InhhwT75gykhs7pqcR_uSiG601oh&index=43)
73 for more details and examples. Some operations of the proposed experimental
74 futures are currently not implemented in our futures however such as
75 `.wait_for()`, `.wait_until()`, `shared_future`, `when_any()`.
76
77 \subsection simgrid_uhood_timer Timers
78
79 */