X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/5ed37babb2fa9097abe82df299c0aa259ed84d5a..7f2b1b735c94c604996643f6c915d6209b0db958:/src/kernel/actor/Simcall.cpp diff --git a/src/kernel/actor/Simcall.cpp b/src/kernel/actor/Simcall.cpp index 33af408084..05f232f19d 100644 --- a/src/kernel/actor/Simcall.cpp +++ b/src/kernel/actor/Simcall.cpp @@ -4,12 +4,17 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/actor/Simcall.hpp" +#include "simgrid/modelchecker.h" #include "simgrid/s4u/Host.hpp" +#include "src/kernel/EngineImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" #include "src/kernel/context/Context.hpp" +#include "src/mc/mc_replay.hpp" #include "xbt/log.h" +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_simcall, kernel, "transmuting from user request into kernel handlers"); + namespace simgrid::kernel::actor { /** @brief returns a printable string representing a simcall */ @@ -36,3 +41,53 @@ void ObjectAccessSimcallItem::take_ownership() } } // namespace simgrid::kernel::actor + +static void simcall(simgrid::kernel::actor::Simcall::Type call, std::function const& code, + simgrid::kernel::actor::SimcallObserver* observer) +{ + auto* self = simgrid::kernel::actor::ActorImpl::self(); + self->simcall_.call_ = call; + self->simcall_.code_ = &code; + self->simcall_.observer_ = observer; + if (simgrid::kernel::EngineImpl::get_instance()->is_maestro(self)) { + self->simcall_handle(0); + } else { + XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), self->simcall_.get_cname()); + self->yield(); + } + self->simcall_.observer_ = nullptr; +} + +void simcall_run_answered(std::function const& code, simgrid::kernel::actor::SimcallObserver* observer) +{ + // The function `code` is called in kernel mode (either because we are already in maestor or after a context switch) + // and simcall_answer() is called + simcall(simgrid::kernel::actor::Simcall::Type::RUN_ANSWERED, code, observer); +} + +void simcall_run_blocking(std::function const& code, simgrid::kernel::actor::SimcallObserver* observer) +{ + // The function `code` is called in kernel mode (either because we are already in maestor or after a context switch) + // BUT simcall_answer IS NOT CALLED + simcall(simgrid::kernel::actor::Simcall::Type::RUN_BLOCKING, code, observer); +} + +void simcall_run_object_access(std::function const& code, simgrid::kernel::actor::ObjectAccessSimcallItem* item) +{ + auto* self = simgrid::kernel::actor::ActorImpl::self(); + + // We only need a simcall if the order of the setters is important (parallel run or MC execution). + // Otherwise, just call the function with no simcall + + if (simgrid::kernel::context::Context::is_parallel() || MC_is_active() || MC_record_replay_is_active()) { + simgrid::kernel::actor::ObjectAccessSimcallObserver observer{self, item}; + simcall(simgrid::kernel::actor::Simcall::Type::RUN_ANSWERED, code, &observer); + item->take_ownership(); + } else { + // don't return from the context-switch we don't do + self->simcall_.call_ = simgrid::kernel::actor::Simcall::Type::RUN_BLOCKING; + self->simcall_.code_ = &code; + self->simcall_.observer_ = nullptr; + self->simcall_handle(0); + } +}