X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/a40e10b423680eebf86d42c0cd010d699b7b6c4d..HEAD:/doc/doxygen/uhood.doc diff --git a/doc/doxygen/uhood.doc b/doc/doxygen/uhood.doc index d8d0a9bf46..1d2d163398 100644 --- a/doc/doxygen/uhood.doc +++ b/doc/doxygen/uhood.doc @@ -1,52 +1,55 @@ /*! @page uhood Under the Hood -\tableofcontents +@tableofcontents TBD - Simulation Loop, LMM, sharing -> papers - Context Switching, privatization -> papers - - @subpage inside -\section simgrid_uhood_s4u S4U +@section simgrid_uhood_s4u S4U S4U classes are designed to be user process interfaces to Maestro resources. We provide an uniform interface to them: -* automatic reference count with intrusive smart pointers `simgrid::s4u::FooPtr` - (also called `simgrid::s4u::Foo::Ptr`); +- automatic reference count with intrusive smart pointers `simgrid::s4u::FooPtr` + (also called `simgrid::s4u::Foo::Ptr`); -* manual reference count with `intrusive_ptr_add_ref(p)`, - `intrusive_ptr_release(p)`; +- manual reference count with `intrusive_ptr_add_ref(p)`, + `intrusive_ptr_release(p)` (which is the interface used by + [`boost::intrusive_ptr`](http://www.boost.org/doc/libs/1_61_0/libs/smart_ptr/intrusive_ptr.html)); -* delegation of the operations to a opaque `pimpl` (which is the Maestro object); +- delegation of the operations to an opaque `pimpl` (which is the Maestro object); -* the Maestro object and the corresponding S4U object have the same lifetime +- the Maestro object and the corresponding S4U object have the same lifetime (and share the same reference count). -The ability to manipulate thge objects thought pointers and have the ability -to use explicite reference count management is useful for creating C wrappers +The ability to manipulate the objects through pointers and have the ability +to use explicit reference count management is useful for creating C wrappers to the S4U and should play nicely with other language bindings (such as SWIG-based ones). Some objects currently live for the whole duration of the simulation and do -not have refertence counts. We still provide dummy `intrusive_ptr_add_ref(p)`, +not have reference counts. We still provide dummy `intrusive_ptr_add_ref(p)`, `intrusive_ptr_release(p)` and `FooPtr` for consistency. -In many cases, we try to have a API which is consistent with the API or +In many cases, we try to have an API which is consistent with the API or corresponding C++ standard classes. For example, the methods of -`simgrid::s4u::Mutex`. This has different benefits: +`simgrid::s4u::Mutex` are based on [`std::mutex`](http://en.cppreference.com/w/cpp/thread/mutex). +This has several benefits: - * we use a proven interface with a well defined and documented semantic; + - we use a proven interface with a well defined and documented semantic; - * the interface is easy to understand and remember for people used to the C++ + - the interface is easy to understand and remember for people used to the C++ standard interface; - * we can use some standard C++ algorithms and helper classes with our types - (`simgrid::s4u::Mutex` can be used with `std::lock`, `std::unique_lock`, + - we can use some standard C++ algorithms and helper classes with our types + (`simgrid::s4u::Mutex` can be used with + [`std::lock`](http://en.cppreference.com/w/cpp/thread/lock), + [`std::unique_lock`](http://en.cppreference.com/w/cpp/thread/unique_lock), etc.). -Example of `simgris::s4u::Actor`: +Example of `simgrid::s4u::Actor`: ~~~ class Actor { @@ -81,147 +84,37 @@ public: using ActorPtr = Actor::Ptr; ~~~ -It uses the `simgrid::simix::Process` as a opaque pimple: +It uses the `simgrid::simix::Process` as an opaque pimple: -~~~ -class Process { -private: - std::atomic_int_fast32_t refcount_ { 1 }; - // The lifetime of the s4u::Actor is bound to the lifetime of the Process: - simgrid::s4u::Actor actor_; -public: - Process() : actor_(this) {} - - // Reference count: - friend void intrusive_ptr_add_ref(Process* process) - { - // Atomic operation! Do not split in two instructions! - auto previous = (process->refcount_)++; - xbt_assert(previous != 0); - (void) previous; - } - friend void intrusive_ptr_release(Process* process) - { - // Atomic operation! Do not split in two instructions! - auto count = --(process->refcount_); - if (count == 0) - delete process; - } - - // [...] -}; - -smx_process_t SIMIX_process_ref(smx_process_t process) -{ - if (process != nullptr) - intrusive_ptr_add_ref(process); - return process; -} - -/** Decrease the refcount for this process */ -void SIMIX_process_unref(smx_process_t process) -{ - if (process != nullptr) - intrusive_ptr_release(process); -} -~~~ - -\section simgrid_uhood_async Asynchronous operations - -\subsection simgrid_uhood_futures Futures - -The `simgrid::kernel::Future` class has been added to SimGrid as an abstraction -to represent asynchronous operations in the SimGrid maestro. Its API is based -on `std::experimental::future` from the [C++ Extensions for Concurrency Technical -Specification](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0159r0.html): - - - `simgrid::kernel::Future` represents the result an asynchronous operations - in the simulation inside the SimGrid maestro/kernel; - - - `simgrid::kernel::Promise` can be used to set the value of an assocaiated - `simgrid::kernel::Future`. - -The expected way to work with `simgrid::kernel::Future` is to add a -completion handler/continuation: - -~~~ -// This code is executed in the maestro context, we cannot block for the result -// to be ready: -simgrid::kernel::Future> result = simgrid::kernel::readFile(file); - -// Add a completion handler: -result.then([file](simgrid::kernel::Future> result) { - // At this point, the operation is complete and we can safely call .get(): - xbt_assert(result.is_ready()); - try { - std::vector data = result.get(); - XBT_DEBUG("Finished reading file %s: length %zu", file.c_str(), data.size()); - } - // If the operation failed, .get() throws an exception: - catch (std::runtime_error& e) { - XBT_ERROR("Could not read file %s", file.c_str()); - } -}); -~~~ - -The SimGrid kernel cannot block so calling `.get()` or `.wait()` on a -`simgrid::kernel::Future` which is not ready will deadlock. In practice, the -simulator detects this and aborts after reporting an error. - -In order to generate your own future, you might need to use a -`simgrid::kernel::Promise`. The promise is a one-way channel which can be -used to set the result of an associated `simgrid::kernel::Future` -(with either `.set_value()` or `.set_exception()`): - -~~~ -simgrid::kernel::Future kernel_wait_until(double date) -{ - auto promise = std::make_shared>(); - auto future = promise->get_future(); - SIMIX_timer_set(date, [promise] { - promise->set_value(); - }); - return future; -} -~~~ - -Like the experimental futures, we support chaining `.then()` methods with -automatic future unwrapping. -You might want to look at some [C++ tutorial on futures](https://www.youtube.com/watch?v=mPxIegd9J3w&list=PLHTh1InhhwT75gykhs7pqcR_uSiG601oh&index=43) -for more details and examples. Some operations of the proposed experimental -futures are currently not implemented in our futures however such as -`.wait_for()`, `.wait_until()`, `shared_future`, `when_any()`. - -\subsection simgrid_uhood_timer Timers -\section simgrid_uhood_mc Model Checker +@section simgrid_uhood_mc Model Checker The current implementation of the model-checker uses two distinct processes: - the SimGrid model-checker (`simgrid-mc`) itself lives in the parent process; - - it spaws a child process for the SimGrid simulator/mastro and the simulated + - it spawns a child process for the SimGrid simulator/maestro and the simulated processes. -They communicate using a `AF_UNIX` `SOCK_DGRAM` socket and exchange messages +They communicate using a `AF_UNIX` `SOCK_SEQPACKET` socket and exchange messages defined in `mc_protocol.h`. The `SIMGRID_MC_SOCKET_FD` environment variable it set to the file descriptor of this socket in the child process. The model-checker analyzes, saves and restores the state of the model-checked process using the following techniques: -* the model-checker reads and writes in the model-checked address space; +- the model-checker reads and writes in the model-checked address space; -* the model-cheker `ptrace()`s the model-checked process and is thus able to +- the model-cheker `ptrace()`s the model-checked process and is thus able to know the state of the model-checked process if it crashes; -* DWARF debug informations are used to unwind the stack and identify local +- DWARF debug information are used to unwind the stack and identify local variables; -* a custom heap is enabled in the model-checked process which allows the model +- a custom heap is enabled in the model-checked process which allows the model checker to know which chunks are allocated and which are freed. -\subsection simgrid_uhood_mc_address_space Address space +@subsection simgrid_uhood_mc_address_space Address space The `AddressSpace` is a base class used for both the model-checked process and its snapshots and has methods to read in the corresponding address space: @@ -233,24 +126,26 @@ and its snapshots and has methods to read in the corresponding address space: Additional helper class include: - `Remote` is the result of reading a `T` in a remote AddressSpace. For - trivial types (int, etc.), it is convertible t o `T`. + trivial types (int, etc.), it is convertible t o `T`; - `RemotePtr` represents the address of an object of type `T` in some remote `AddressSpace` (it could be an alias to `Remote`). -\subsection simgrid_uhood_mc_address_elf_dwarf ELF and DWARF +@subsection simgrid_uhood_mc_address_elf_dwarf ELF and DWARF -ELF is a standard executable file and dynamic libraries file format. -DWARF is a standard for debug informations. Both are used on GNU/Linux systems -and exploited by the model-checker to understand the model-checked process: +[ELF](http://refspecs.linuxbase.org/elf/elf.pdf) is a standard executable file +and dynamic libraries file format. +[DWARF](http://dwarfstd.org/) is a standard for debug information. +Both are used on GNU/Linux systems and exploited by the model-checker to +understand the model-checked process: - - `ObjectInformation` represents the informations about a given ELF module + - `ObjectInformation` represents the information about a given ELF module (executable or shared-object); - `Frame` represents a subprogram scope (either a subprogram or a scope within the subprogram); - - `Type` represents a type (`char*`, `int`, `std::string`) and is referenced + - `Type` represents a type (eg. `char*`, `int`, `std::string`) and is referenced by variables (global, variables, parameters), functions (return type), and other types (type of a `struct` field, etc.);