class Profile;
} // namespace profile
} // namespace kernel
+namespace simix {
+class Simcall;
+}
namespace mc {
class State;
}
/** Pointer to a constant actor object */
typedef const s4u_Actor* const_sg_actor_t;
-typedef struct s_smx_simcall* smx_simcall_t;
-
/** @ingroup m_datatypes_management_details
* @brief Type for any simgrid size
*/
actor->waiting_synchro_->get_cname(), actor->waiting_synchro_->get_state_str());
} else {
XBT_INFO("Actor %ld (%s@%s) simcall %s", actor->get_pid(), actor->get_cname(), actor->get_host()->get_cname(),
- SIMIX_simcall_name(actor->simcall_));
+ actor->simcall_.get_cname());
}
}
}
*/
for (auto const& actor : actors_that_ran_) {
- if (actor->simcall_.call_ != simix::Simcall::NONE) {
+ if (actor->simcall_.call_ != simix::Simcall::Type::NONE) {
actor->simcall_handle(0);
}
}
XBT_DEBUG("Destroy activity %p", this);
}
-void ActivityImpl::register_simcall(smx_simcall_t simcall)
+void ActivityImpl::register_simcall(simix::Simcall* simcall)
{
simcalls_.push_back(simcall);
simcall->issuer_->waiting_synchro_ = this;
}
-void ActivityImpl::unregister_simcall(smx_simcall_t simcall)
+void ActivityImpl::unregister_simcall(simix::Simcall* simcall)
{
// Remove the first occurrence of simcall:
auto j = boost::range::find(simcalls_, simcall);
state_ = State::CANCELED;
}
-void ActivityImpl::handle_activity_waitany(smx_simcall_t simcall)
+void ActivityImpl::handle_activity_waitany(simix::Simcall* simcall)
{
/* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany
* list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
public:
virtual ~ActivityImpl();
ActivityImpl() = default;
- std::list<smx_simcall_t> simcalls_; /* List of simcalls waiting for this activity */
+ std::list<simix::Simcall*> simcalls_; /* List of simcalls waiting for this activity */
s4u::Activity* piface_ = nullptr;
resource::Action* surf_action_ = nullptr;
virtual void finish() = 0; // Unlock all simcalls blocked on that activity, either because it was marked as done by
// the model or because it terminated without waiting for the model
- void register_simcall(smx_simcall_t simcall);
- void unregister_simcall(smx_simcall_t simcall);
- void handle_activity_waitany(smx_simcall_t simcall);
+ void register_simcall(simix::Simcall* simcall);
+ void unregister_simcall(simix::Simcall* simcall);
+ void handle_activity_waitany(simix::Simcall* simcall);
void clean_action();
virtual double get_remaining() const;
// Support for the boost::intrusive_ptr<ActivityImpl> datatype
void BarrierAcquisitionImpl::finish()
{
xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size());
- smx_simcall_t simcall = simcalls_.front();
+ simix::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
simcall->issuer_->waiting_synchro_ = nullptr;
copy_data();
while (not simcalls_.empty()) {
- smx_simcall_t simcall = simcalls_.front();
+ simix::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
/* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany
* list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
* simcall */
- if (simcall->call_ == simix::Simcall::NONE) // FIXME: maybe a better way to handle this case
- continue; // if actor handling comm is killed
+ if (simcall->call_ == simix::Simcall::Type::NONE) // FIXME: maybe a better way to handle this case
+ continue; // if actor handling comm is killed
handle_activity_waitany(simcall);
proc.waiting_synchro_ = nullptr;
/* Now transform the cond wait simcall into a mutex lock one */
- smx_simcall_t simcall = &proc.simcall_;
+ simix::Simcall* simcall = &proc.simcall_;
const auto* observer = dynamic_cast<kernel::actor::ConditionWaitSimcall*>(simcall->observer_);
xbt_assert(observer != nullptr);
observer->get_mutex()->lock_async(simcall->issuer_)->wait_for(simcall->issuer_, -1);
{
XBT_DEBUG("ExecImpl::finish() in state %s", get_state_str());
while (not simcalls_.empty()) {
- smx_simcall_t simcall = simcalls_.front();
+ simix::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
- if (simcall->call_ == simix::Simcall::NONE) // FIXME: maybe a better way to handle this case
- continue; // if process handling comm is killed
+ if (simcall->call_ == simix::Simcall::Type::NONE) // FIXME: maybe a better way to handle this case
+ continue; // if process handling comm is killed
handle_activity_waitany(simcall);
{
XBT_DEBUG("IoImpl::finish() in state %s", get_state_str());
while (not simcalls_.empty()) {
- smx_simcall_t simcall = simcalls_.front();
+ simix::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
/* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany
* list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
* simcall */
- if (simcall->call_ == simix::Simcall::NONE) // FIXME: maybe a better way to handle this case
- continue; // if process handling comm is killed
+ if (simcall->call_ == simix::Simcall::Type::NONE) // FIXME: maybe a better way to handle this case
+ continue; // if process handling comm is killed
handle_activity_waitany(simcall);
void MutexAcquisitionImpl::finish()
{
xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size());
- smx_simcall_t simcall = simcalls_.front();
+ simix::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
simcall->issuer_->waiting_synchro_ = nullptr;
void SemAcquisitionImpl::finish()
{
xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size());
- smx_simcall_t simcall = simcalls_.front();
+ simix::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
if (surf_action_ != nullptr) { // A timeout was declared
{
XBT_DEBUG("SleepImpl::finish() in state %s", get_state_str());
while (not simcalls_.empty()) {
- const s_smx_simcall* simcall = simcalls_.front();
+ const simix::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
simcall->issuer_->waiting_synchro_ = nullptr;
{
XBT_DEBUG("SynchroImpl::finish() in state %s", get_state_str());
xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size());
- smx_simcall_t simcall = simcalls_.front();
+ simix::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
set_exception(simcall->issuer_);
{
auto* engine = EngineImpl::get_instance();
if (not this->is_maestro()) {
- XBT_DEBUG("Answer simcall %s issued by %s (%p)", SIMIX_simcall_name(simcall_), get_cname(), this);
- xbt_assert(simcall_.call_ != simix::Simcall::NONE);
- simcall_.call_ = simix::Simcall::NONE;
+ XBT_DEBUG("Answer simcall %s issued by %s (%p)", simcall_.get_cname(), get_cname(), this);
+ xbt_assert(simcall_.call_ != simix::Simcall::Type::NONE);
+ simcall_.call_ = simix::Simcall::Type::NONE;
const auto& actors_to_run = engine->get_actors_to_run();
xbt_assert(not XBT_LOG_ISENABLED(ker_actor, xbt_log_priority_debug) ||
std::find(begin(actors_to_run), end(actors_to_run), this) == end(actors_to_run),
activity::ActivityImplPtr waiting_synchro_ = nullptr; /* the current blocking synchro if any */
std::list<activity::ActivityImplPtr> activities_; /* the current non-blocking synchros */
- s_smx_simcall simcall_;
+ simix::Simcall simcall_;
/* list of functions executed when the actor dies */
std::shared_ptr<std::vector<std::function<void(bool)>>> on_exit =
std::make_shared<std::vector<std::function<void(bool)>>>();
while (engine->has_actors_to_run()) {
engine->run_all_actors();
for (auto const& actor : engine->get_actors_that_ran()) {
- const s_smx_simcall* req = &actor->simcall_;
- if (req->call_ != simix::Simcall::NONE && not simgrid::mc::request_is_visible(req))
+ const simix::Simcall* req = &actor->simcall_;
+ if (req->call_ != simix::Simcall::Type::NONE && not simgrid::mc::request_is_visible(req))
actor->simcall_handle(0);
}
}
#endif
// Now, we are in the client app, no need for remote memory reading.
- smx_simcall_t req = &actor->simcall_;
+ simix::Simcall* req = &actor->simcall_;
if (req->observer_ != nullptr)
return req->observer_->is_enabled();
- if (req->call_ == simix::Simcall::NONE)
+ if (req->call_ == simix::Simcall::Type::NONE)
return false;
else
/* The rest of the requests are always enabled */
/* This is the list of requests that are visible from the checker algorithm.
* Any other requests are handled right away on the application side.
*/
-bool request_is_visible(const s_smx_simcall* req)
+bool request_is_visible(const simix::Simcall* req)
{
#if SIMGRID_HAVE_MC
xbt_assert(mc_model_checker == nullptr, "This should be called from the client side");
XBT_PRIVATE extern std::vector<double> processes_time;
/** Execute a given simcall */
-XBT_PRIVATE void handle_simcall(smx_simcall_t req, int req_num);
+XBT_PRIVATE void handle_simcall(simix::Simcall* req, int req_num);
/** Is the process ready to execute its simcall?
*
XBT_PRIVATE bool actor_is_enabled(smx_actor_t process);
/** Check if the given simcall is visible */
-XBT_PRIVATE bool request_is_visible(const s_smx_simcall* req);
+XBT_PRIVATE bool request_is_visible(const simix::Simcall* req);
} // namespace mc
} // namespace simgrid
// Choose a request:
kernel::actor::ActorImpl* actor = kernel::actor::ActorImpl::by_pid(transition->aid_);
xbt_assert(actor != nullptr, "Unexpected actor (id:%ld).", transition->aid_);
- const s_smx_simcall* simcall = &(actor->simcall_);
- xbt_assert(simcall->call_ != simix::Simcall::NONE, "No simcall for process %ld.", transition->aid_);
+ const simix::Simcall* simcall = &(actor->simcall_);
+ xbt_assert(simcall->call_ != simix::Simcall::Type::NONE, "No simcall for process %ld.", transition->aid_);
xbt_assert(simgrid::mc::request_is_visible(simcall) && simgrid::mc::actor_is_enabled(actor), "Unexpected simcall.");
// Execute the request:
return false;
}
-static void simcall(simgrid::simix::Simcall call, std::function<void()> const& code)
+static void simcall(simgrid::simix::Simcall::Type call, std::function<void()> const& code)
{
auto self = simgrid::kernel::actor::ActorImpl::self();
self->simcall_.call_ = call;
self->simcall_.code_ = &code;
if (not simgrid::kernel::EngineImpl::get_instance()->is_maestro(self)) {
- XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), SIMIX_simcall_name(self->simcall_));
+ XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), self->simcall_.get_cname());
self->yield();
} else {
self->simcall_handle(0);
simgrid::kernel::actor::ActorImpl::self()->simcall_.observer_ = 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::simix::Simcall::RUN_ANSWERED, code);
+ simcall(simgrid::simix::Simcall::Type::RUN_ANSWERED, code);
simgrid::kernel::actor::ActorImpl::self()->simcall_.observer_ = nullptr;
}
simgrid::kernel::actor::ActorImpl::self()->simcall_.observer_ = 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::simix::Simcall::RUN_BLOCKING, code);
+ simcall(simgrid::simix::Simcall::Type::RUN_BLOCKING, code);
simgrid::kernel::actor::ActorImpl::self()->simcall_.observer_ = nullptr;
}
*/
void simgrid::kernel::actor::ActorImpl::simcall_handle(int times_considered)
{
- XBT_DEBUG("Handling simcall %p: %s", &simcall_, SIMIX_simcall_name(simcall_));
+ XBT_DEBUG("Handling simcall %p: %s", &simcall_, simcall_.get_cname());
if (simcall_.observer_ != nullptr)
simcall_.observer_->prepare(times_considered);
if (context_->wannadie())
return;
- xbt_assert(simcall_.call_ != simgrid::simix::Simcall::NONE, "Asked to do the noop syscall on %s@%s", get_cname(),
- get_host()->get_cname());
+ xbt_assert(simcall_.call_ != simgrid::simix::Simcall::Type::NONE, "Asked to do the noop syscall on %s@%s",
+ get_cname(), get_host()->get_cname());
(*simcall_.code_)();
- if (simcall_.call_ == simgrid::simix::Simcall::RUN_ANSWERED)
+ if (simcall_.call_ == simgrid::simix::Simcall::Type::RUN_ANSWERED)
simcall_answer();
}
/** @brief returns a printable string representing a simcall */
-const char* SIMIX_simcall_name(const s_smx_simcall& simcall)
+const char* simgrid::simix::Simcall::get_cname() const
{
- if (simcall.observer_ != nullptr) {
+ if (observer_ != nullptr) {
static std::string name;
- name = boost::core::demangle(typeid(*simcall.observer_).name());
+ name = boost::core::demangle(typeid(*observer_).name());
const char* cname = name.c_str();
if (name.rfind("simgrid::kernel::", 0) == 0)
cname += 17; // strip prefix "simgrid::kernel::"
return cname;
} else {
- return to_c_str(simcall.call_);
+ return to_c_str(call_);
}
}
#include "simgrid/forward.h"
#include "src/kernel/activity/ActivityImpl.hpp"
-
-#include <array>
-#include <boost/intrusive_ptr.hpp>
+#include "xbt/utility.hpp"
/********************************* Simcalls *********************************/
namespace simgrid {
namespace simix {
-/** All possible simcalls. */
-XBT_DECLARE_ENUM_CLASS(Simcall, NONE, RUN_ANSWERED, RUN_BLOCKING);
-} // namespace simix
-} // namespace simgrid
-
/**
* @brief Represents a simcall to the kernel.
*/
-struct s_smx_simcall {
- simgrid::simix::Simcall call_ = simgrid::simix::Simcall::NONE;
+class Simcall {
+public:
+ /** All possible simcalls. */
+ XBT_DECLARE_ENUM_CLASS(Type, NONE, RUN_ANSWERED, RUN_BLOCKING);
+
+ Type call_ = Type::NONE;
smx_actor_t issuer_ = nullptr;
simgrid::kernel::timer::Timer* timeout_cb_ = nullptr; // Callback to timeouts
simgrid::kernel::actor::SimcallObserver* observer_ = nullptr; // makes that simcall observable by the MC
unsigned int mc_max_consider_ =
0; // How many times this simcall should be used. If >1, this will be a fork in the state space.
std::function<void()> const* code_ = nullptr;
-};
-/******************************** General *************************************/
+ const char* get_cname() const;
+};
-XBT_PRIVATE const char* SIMIX_simcall_name(const s_smx_simcall& simcall);
+} // namespace simix
+} // namespace simgrid
#endif