X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2807fde4fd1f59c230d69a934634c5dfb77905f2..08f744b9a55745ac1b1dcf0ed2ea735471cd7f89:/doc/doxygen/uhood_switch.doc diff --git a/doc/doxygen/uhood_switch.doc b/doc/doxygen/uhood_switch.doc index 684eacbb20..72a86050ea 100644 --- a/doc/doxygen/uhood_switch.doc +++ b/doc/doxygen/uhood_switch.doc @@ -27,7 +27,7 @@ Mimicking the OS behavior may seem over-engineered here, but this is mandatory to the model-checker. The simcalls, representing actors' actions, are the transitions of the formal system. Verifying the system requires to manipulate these transitions explicitly. This also -allows to run safely the actors in parallel, even if this is less +allows one to run the actors safely in parallel, even if this is less commonly used by our users. So, the key ideas here are: @@ -200,7 +200,7 @@ The crux of `future.then()` is: @code{cpp} template template -auto simgrid::kernel::Future::thenNoUnwrap(F continuation) +auto simgrid::kernel::Future::then_no_unwrap(F continuation) -> Future { typedef decltype(continuation(std::move(*this))) R; @@ -468,14 +468,14 @@ kernel which will wake up the actor (with `simgrid::simix::unblock(actor)`) when the operation is completed. This is wrapped in a higher-level primitive as well. The -`kernelSync()` function expects a function-object which is executed +`kernel_sync()` function expects a function-object which is executed immediately in the simulation kernel and returns a `Future`. The simulator blocks the actor and resumes it when the `Future` becomes ready with its result: @code{cpp} template -auto kernelSync(F code) -> decltype(code().get()) +auto kernel_sync(F code) -> decltype(code().get()) { typedef decltype(code().get()) T; if (SIMIX_is_maestro()) @@ -510,7 +510,7 @@ auto kernelSync(F code) -> decltype(code().get()) A contrived example of this would be: @code{cpp} -int res = simgrid::simix::kernelSync([&] { +int res = simgrid::simix::kernel_sync([&] { return kernel_wait_until(30).then( [](simgrid::kernel::Future future) { return 42; @@ -521,7 +521,7 @@ int res = simgrid::simix::kernelSync([&] { ### Asynchronous operations {#uhood_switch_v2_async} -We can write the related `kernelAsync()` which wakes up the actor immediately +We can write the related `kernel_async()` which wakes up the actor immediately and returns a future to the actor. As this future is used in the actor context, it is a different future (`simgrid::simix::Future` instead of `simgrid::kernel::Future`) @@ -572,12 +572,12 @@ T simgrid::simix::Future::get() } @endcode -`kernelAsync()` simply :wink: calls `kernelImmediate()` and wraps the +`kernel_async()` simply :wink: calls `kernelImmediate()` and wraps the `simgrid::kernel::Future` into a `simgrid::simix::Future`: @code{cpp} template -auto kernelAsync(F code) +auto kernel_async(F code) -> Future { typedef decltype(code().get()) T; @@ -594,7 +594,7 @@ auto kernelAsync(F code) A contrived example of this would be: @code{cpp} -simgrid::simix::Future future = simgrid::simix::kernelSync([&] { +simgrid::simix::Future future = simgrid::simix::kernel_sync([&] { return kernel_wait_until(30).then( [](simgrid::kernel::Future future) { return 42; @@ -605,18 +605,18 @@ do_some_stuff(); int res = future.get(); @endcode -`kernelSync()` could be rewritten as: +`kernel_sync()` could be rewritten as: @code{cpp} template -auto kernelSync(F code) -> decltype(code().get()) +auto kernel_sync(F code) -> decltype(code().get()) { - return kernelAsync(std::move(code)).get(); + return kernel_async(std::move(code)).get(); } @endcode The semantic is equivalent but this form would require two simcalls -instead of one to do the same job (one in `kernelAsync()` and one in +instead of one to do the same job (one in `kernel_async()` and one in `.get()`). ## Mutexes and condition variables @@ -708,20 +708,15 @@ std::cv_status ConditionVariable::wait_for( simcall_cond_wait_timeout(cond_, lock.mutex()->mutex_, timeout); return std::cv_status::no_timeout; } - catch (xbt_ex& e) { - + catch (const simgrid::TimeoutException& e) { // If the exception was a timeout, we have to take the lock again: - if (e.category == timeout_error) { - try { - lock.mutex()->lock(); - return std::cv_status::timeout; - } - catch (...) { - std::terminate(); - } + try { + lock.mutex()->lock(); + return std::cv_status::timeout; + } + catch (...) { + std::terminate(); } - - std::terminate(); } catch (...) { std::terminate(); @@ -769,7 +764,7 @@ We wrote two future implementations based on the `std::future` API: * the second one is a wait-based (`future.get()`) future used in the actors which waits using a simcall. -These futures are used to implement `kernelSync()` and `kernelAsync()` which +These futures are used to implement `kernel_sync()` and `kernel_async()` which expose asynchronous operations in the simulation kernel to the actors. In addition, we wrote variations of some other C++ standard library @@ -815,30 +810,14 @@ single-object without shared-state and synchronisation: @code{cpp} template class Result { - enum class ResultStatus { - invalid, - value, - exception, - }; public: - Result(); - ~Result(); - Result(Result const& that); - Result& operator=(Result const& that); - Result(Result&& that); - Result& operator=(Result&& that); bool is_valid() const; - void reset(); void set_exception(std::exception_ptr e); void set_value(T&& value); void set_value(T const& value); T get(); private: - ResultStatus status_ = ResultStatus::invalid; - union { - T value_; - std::exception_ptr exception_; - }; + boost::variant value_; }; @endcode~ @@ -974,4 +953,4 @@ auto makeTask(F code, Args... args) in the simulation which we would like to avoid. `std::try_lock()` should be safe to use though. -*/ \ No newline at end of file +*/