X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/be2d18ff8c8ee4ccf6b713010f8999e7613dcdf5..c972ddd5a74b83c183357f707e7dfba87d48e750:/src/s4u/s4u_Actor.cpp diff --git a/src/s4u/s4u_Actor.cpp b/src/s4u/s4u_Actor.cpp index 1fd96f9383..5a67ebda72 100644 --- a/src/s4u/s4u_Actor.cpp +++ b/src/s4u/s4u_Actor.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2020. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2021. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -32,8 +32,10 @@ xbt::signal s4u::Actor::on_suspend; xbt::signal s4u::Actor::on_resume; xbt::signal s4u::Actor::on_sleep; xbt::signal s4u::Actor::on_wake_up; +#ifndef DOXYGEN xbt::signal s4u::Actor::on_migration_start; // XBT_ATTRIB_DEPRECATED_v329 xbt::signal s4u::Actor::on_migration_end; // XBT_ATTRIB_DEPRECATED_v329 +#endif xbt::signal s4u::Actor::on_host_change; xbt::signal s4u::Actor::on_termination; xbt::signal s4u::Actor::on_destruction; @@ -112,9 +114,9 @@ void Actor::join(double timeout) const { kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); const kernel::actor::ActorImpl* target = pimpl_; - kernel::actor::simcall_blocking([issuer, target, timeout] { + kernel::actor::simcall_blocking([issuer, target, timeout] { if (target->finished_) { - // The joined process is already finished, just wake up the issuer right away + // The joined actor is already finished, just wake up the issuer right away issuer->simcall_answer(); } else { kernel::activity::ActivityImplPtr sync = issuer->join(target, timeout); @@ -131,7 +133,7 @@ void Actor::set_auto_restart(bool autorestart) auto* arg = new kernel::actor::ProcessArg(pimpl_->get_host(), pimpl_); XBT_DEBUG("Adding %s to the actors_at_boot_ list of Host %s", arg->name.c_str(), arg->host->get_cname()); - pimpl_->get_host()->pimpl_->add_actor_at_boot(arg); + pimpl_->get_host()->get_impl()->add_actor_at_boot(arg); }); } @@ -155,13 +157,10 @@ void Actor::set_host(Host* new_host) const s4u::Host* previous_location = get_host(); kernel::actor::simcall([this, new_host]() { - if (pimpl_->waiting_synchro_ != nullptr) { - // The actor is blocked on an activity. If it's an exec, migrate it too. + for (auto const& activity : pimpl_->activities_) { // FIXME: implement the migration of other kinds of activities - kernel::activity::ExecImplPtr exec = - boost::dynamic_pointer_cast(pimpl_->waiting_synchro_); - xbt_assert(exec.get() != nullptr, "We can only migrate blocked actors when they are blocked on executions."); - exec->migrate(new_host); + if (auto exec = boost::dynamic_pointer_cast(activity)) + exec->migrate(new_host); } this->pimpl_->set_host(new_host); }); @@ -219,7 +218,7 @@ void Actor::suspend() kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); kernel::actor::ActorImpl* target = pimpl_; s4u::Actor::on_suspend(*this); - kernel::actor::simcall_blocking([issuer, target]() { + kernel::actor::simcall_blocking([issuer, target]() { target->suspend(); if (target != issuer) { /* If we are suspending ourselves, then just do not finish the simcall now */ @@ -260,7 +259,7 @@ void Actor::kill() ActorPtr Actor::by_pid(aid_t pid) { - kernel::actor::ActorImpl* actor = SIMIX_process_from_PID(pid); + kernel::actor::ActorImpl* actor = kernel::actor::ActorImpl::by_pid(pid); if (actor != nullptr) return actor->get_iface(); else @@ -316,22 +315,34 @@ void sleep_for(double duration) { xbt_assert(std::isfinite(duration), "duration is not finite!"); - if (duration > 0) { - kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - Actor::on_sleep(*issuer->get_ciface()); - - kernel::actor::simcall_blocking([issuer, duration]() { - if (MC_is_active() || MC_record_replay_is_active()) { - MC_process_clock_add(issuer, duration); - issuer->simcall_answer(); - return; - } - kernel::activity::ActivityImplPtr sync = issuer->sleep(duration); - sync->register_simcall(&issuer->simcall_); - }); - - Actor::on_wake_up(*issuer->get_ciface()); + if (duration <= 0) /* that's a no-op */ + return; + + if (duration < sg_surf_precision) { + static unsigned int warned = 0; // At most 20 such warnings + warned++; + if (warned <= 20) + XBT_INFO("The parameter to sleep_for() is smaller than the SimGrid numerical accuracy (%g < %g). " + "Please refer to https://simgrid.org/doc/latest/Configuring_SimGrid.html#numerical-precision", + duration, sg_surf_precision); + if (warned == 20) + XBT_VERB("(further warnings about the numerical accuracy of sleep_for() will be omitted)."); } + + kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); + Actor::on_sleep(*issuer->get_ciface()); + + kernel::actor::simcall_blocking([issuer, duration]() { + if (MC_is_active() || MC_record_replay_is_active()) { + MC_process_clock_add(issuer, duration); + issuer->simcall_answer(); + return; + } + kernel::activity::ActivityImplPtr sync = issuer->sleep(duration); + sync->register_simcall(&issuer->simcall_); + }); + + Actor::on_wake_up(*issuer->get_ciface()); } void yield() @@ -341,7 +352,7 @@ void yield() XBT_PUBLIC void sleep_until(double wakeup_time) { - double now = SIMIX_get_clock(); + double now = s4u::Engine::get_clock(); if (wakeup_time > now) sleep_for(wakeup_time - now); } @@ -353,7 +364,7 @@ void execute(double flops) void execute(double flops, double priority) { - exec_init(flops)->set_priority(priority)->start()->wait(); + exec_init(flops)->set_priority(priority)->vetoable_start()->wait(); } void parallel_execute(const std::vector& hosts, const std::vector& flops_amounts, @@ -370,15 +381,13 @@ void parallel_execute(const std::vector& hosts, const std::vectorset_flops_amount(flops_amount)->set_host(get_host()); - return exec; + return Exec::init()->set_flops_amount(flops_amount)->set_host(get_host()); } ExecPtr exec_init(const std::vector& hosts, const std::vector& flops_amounts, const std::vector& bytes_amounts) { - xbt_assert(hosts.size() > 0, "Your parallel executions must span over at least one host."); + xbt_assert(not hosts.empty(), "Your parallel executions must span over at least one host."); xbt_assert(hosts.size() == flops_amounts.size() || flops_amounts.empty(), "Host count (%zu) does not match flops_amount count (%zu).", hosts.size(), flops_amounts.size()); xbt_assert(hosts.size() * hosts.size() == bytes_amounts.size() || bytes_amounts.empty(), @@ -398,15 +407,13 @@ ExecPtr exec_init(const std::vector& hosts, const std::vectorset_flops_amounts(flops_amounts)->set_bytes_amounts(bytes_amounts)->set_hosts(hosts); - return exec; + return Exec::init()->set_flops_amounts(flops_amounts)->set_bytes_amounts(bytes_amounts)->set_hosts(hosts); } ExecPtr exec_async(double flops) { ExecPtr res = exec_init(flops); - res->start(); + res->vetoable_start(); return res; } @@ -439,7 +446,7 @@ void suspend() { kernel::actor::ActorImpl* self = simgrid::kernel::actor::ActorImpl::self(); s4u::Actor::on_suspend(*self->get_ciface()); - kernel::actor::simcall_blocking([self] { self->suspend(); }); + kernel::actor::simcall_blocking([self] { self->suspend(); }); } void exit() @@ -483,7 +490,7 @@ sg_actor_t* sg_actor_list() xbt_assert(actor_count > 0, "There is no actor!"); std::vector actors = e->get_all_actors(); - sg_actor_t* res = xbt_new(sg_actor_t, actors.size()); + auto* res = xbt_new(sg_actor_t, actors.size()); for (size_t i = 0; i < actor_count; i++) res[i] = actors[i].get(); return res; @@ -494,7 +501,7 @@ sg_actor_t sg_actor_init(const char* name, sg_host_t host) return simgrid::s4u::Actor::init(name, host).get(); } -void sg_actor_start(sg_actor_t actor, xbt_main_func_t code, int argc, const char* const* argv) +void sg_actor_start_(sg_actor_t actor, xbt_main_func_t code, int argc, const char* const* argv) { simgrid::kernel::actor::ActorCode function; if (code) @@ -502,7 +509,7 @@ void sg_actor_start(sg_actor_t actor, xbt_main_func_t code, int argc, const char actor->start(function); } -sg_actor_t sg_actor_create(const char* name, sg_host_t host, xbt_main_func_t code, int argc, const char* const* argv) +sg_actor_t sg_actor_create_(const char* name, sg_host_t host, xbt_main_func_t code, int argc, const char* const* argv) { simgrid::kernel::actor::ActorCode function = simgrid::xbt::wrap_main(code, argc, argv); return simgrid::s4u::Actor::init(name, host)->start(function).get(); @@ -524,7 +531,7 @@ void sg_actor_exit() * This function checks whether @a actor is a valid pointer and return its PID (or 0 in case of problem). */ -aid_t sg_actor_get_PID(const_sg_actor_t actor) +aid_t sg_actor_get_pid(const_sg_actor_t actor) { /* Do not raise an exception here: this function is called by the logs * and the exceptions, so it would be called back again and again */ @@ -539,7 +546,7 @@ aid_t sg_actor_get_PID(const_sg_actor_t actor) * This function checks whether @a actor is a valid pointer and return its parent's PID. * Returns -1 if the actor has not been created by any other actor. */ -aid_t sg_actor_get_PPID(const_sg_actor_t actor) +aid_t sg_actor_get_ppid(const_sg_actor_t actor) { return actor->get_ppid(); } @@ -551,11 +558,26 @@ aid_t sg_actor_get_PPID(const_sg_actor_t actor) * If none is found, @c nullptr is returned. Note that the PID are unique in the whole simulation, not only on a given host. */ -sg_actor_t sg_actor_by_PID(aid_t pid) +sg_actor_t sg_actor_by_pid(aid_t pid) { return simgrid::s4u::Actor::by_pid(pid).get(); } +aid_t sg_actor_get_PID(const_sg_actor_t actor) // XBT_ATTRIB_DEPRECATED_v331 +{ + return sg_actor_get_pid(actor); +} + +aid_t sg_actor_get_PPID(const_sg_actor_t actor) // XBT_ATTRIB_DEPRECATED_v331 +{ + return sg_actor_get_ppid(actor); +} + +sg_actor_t sg_actor_by_PID(aid_t pid) // XBT_ATTRIB_DEPRECATED_v331 +{ + return sg_actor_by_pid(pid); +} + /** @brief Return the name of an actor. */ const char* sg_actor_get_name(const_sg_actor_t actor) { @@ -665,9 +687,9 @@ void sg_actor_set_host(sg_actor_t actor, sg_host_t host) { actor->set_host(host); } -void sg_actor_migrate(sg_actor_t process, sg_host_t host) // XBT_ATTRIB_DEPRECATED_v329 +void sg_actor_migrate(sg_actor_t actor, sg_host_t host) // XBT_ATTRIB_DEPRECATED_v329 { - process->set_host(host); + actor->set_host(host); } /** @@ -729,10 +751,11 @@ sg_actor_t sg_actor_attach(const char* name, void* data, sg_host_t host, xbt_dic props[key] = value; xbt_dict_free(&properties); - /* Let's create the process: SIMIX may decide to start it right now, even before returning the flow control to us */ + /* Let's create the actor: SIMIX may decide to start it right now, even before returning the flow control to us */ smx_actor_t actor = nullptr; try { - actor = simgrid::kernel::actor::ActorImpl::attach(name, data, host, &props).get(); + actor = simgrid::kernel::actor::ActorImpl::attach(name, data, host).get(); + actor->set_properties(props); } catch (simgrid::HostFailureException const&) { xbt_die("Could not attach"); } @@ -846,9 +869,9 @@ void sg_actor_data_set(sg_actor_t actor, void* userdata) // XBT_ATTRIB_DEPRECATE sg_actor_set_data(actor, userdata); } -/** @brief Add a function to the list of "on_exit" functions for the current process. - * The on_exit functions are the functions executed when your process is killed. - * You should use them to free the data used by your process. +/** @brief Add a function to the list of "on_exit" functions for the current actor. + * The on_exit functions are the functions executed when your actor is killed. + * You should use them to free the data used by your actor. */ void sg_actor_on_exit(void_f_int_pvoid_t fun, void* data) { @@ -873,8 +896,7 @@ sg_exec_t sg_actor_parallel_exec_init(int host_nb, const sg_host_t* host_list, d if (bytes_amount != nullptr) bytes = std::vector(bytes_amount, bytes_amount + host_nb * host_nb); - simgrid::s4u::ExecPtr exec(new simgrid::s4u::Exec()); - exec->set_flops_amounts(flops)->set_bytes_amounts(bytes)->set_hosts(hosts); + simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_init(hosts, flops, bytes); exec->add_ref(); return exec.get(); }