X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/b6dde5ff6f208b83545a4b4e9e81712d0d8617a1..cd4a6bff769c06de3840b08926eccf0734642f57:/src/s4u/s4u_Actor.cpp diff --git a/src/s4u/s4u_Actor.cpp b/src/s4u/s4u_Actor.cpp index 02f2ba7bb6..363569617b 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. */ @@ -11,6 +11,7 @@ #include "simgrid/s4u/Host.hpp" #include "simgrid/s4u/VirtualMachine.hpp" #include "src/include/mc/mc.h" +#include "src/kernel/EngineImpl.hpp" #include "src/kernel/activity/ExecImpl.hpp" #include "src/mc/mc_replay.hpp" #include "src/surf/HostImpl.hpp" @@ -31,8 +32,6 @@ 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; -xbt::signal s4u::Actor::on_migration_start; // deprecated -xbt::signal s4u::Actor::on_migration_end; // deprecated xbt::signal s4u::Actor::on_host_change; xbt::signal s4u::Actor::on_termination; xbt::signal s4u::Actor::on_destruction; @@ -40,19 +39,28 @@ xbt::signal s4u::Actor::on_destruction; // ***** Actor creation ***** Actor* Actor::self() { - kernel::context::Context* self_context = kernel::context::Context::self(); + const kernel::context::Context* self_context = kernel::context::Context::self(); if (self_context == nullptr) return nullptr; - return self_context->get_actor()->ciface(); + return self_context->get_actor()->get_ciface(); } ActorPtr Actor::init(const std::string& name, s4u::Host* host) { - kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self(); + const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self(); kernel::actor::ActorImpl* actor = kernel::actor::simcall([self, &name, host] { return self->init(name, host).get(); }); - return actor->iface(); + return actor->get_iface(); +} + +/** Set a non-default stack size for this context (in Kb) + * + * This must be done before starting the actor, and it won't work with the thread factory. */ +ActorPtr Actor::set_stacksize(unsigned stacksize) +{ + pimpl_->set_stacksize(stacksize * 1024); + return this; } ActorPtr Actor::start(const std::function& code) @@ -63,17 +71,18 @@ ActorPtr Actor::start(const std::function& code) ActorPtr Actor::create(const std::string& name, s4u::Host* host, const std::function& code) { - kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self(); + const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self(); kernel::actor::ActorImpl* actor = kernel::actor::simcall([self, &name, host, &code] { return self->init(name, host)->start(code); }); - return actor->iface(); + return actor->get_iface(); } ActorPtr Actor::create(const std::string& name, s4u::Host* host, const std::string& function, std::vector args) { - const simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(function); + const simgrid::kernel::actor::ActorCodeFactory& factory = + simgrid::kernel::EngineImpl::get_instance()->get_function(function); return create(name, host, factory(std::move(args))); } @@ -85,29 +94,29 @@ void intrusive_ptr_release(const Actor* actor) { intrusive_ptr_release(actor->pimpl_); } -int Actor::get_refcount() +int Actor::get_refcount() const { return pimpl_->get_refcount(); } // ***** Actor methods ***** -void Actor::join() +void Actor::join() const { join(-1); } -void Actor::join(double timeout) +void Actor::join(double timeout) const { kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActorImpl* target = pimpl_; - kernel::actor::simcall_blocking([issuer, target, timeout] { + const kernel::actor::ActorImpl* target = pimpl_; + 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); - sync->register_simcall(&issuer->simcall); + sync->register_simcall(&issuer->simcall_); } }); } @@ -118,9 +127,9 @@ void Actor::set_auto_restart(bool autorestart) xbt_assert(autorestart && not pimpl_->has_to_auto_restart()); // FIXME: handle all cases pimpl_->set_auto_restart(autorestart); - kernel::actor::ProcessArg* arg = new kernel::actor::ProcessArg(pimpl_->get_host(), pimpl_); + 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); }); } @@ -131,40 +140,17 @@ void Actor::on_exit(const std::function& fun) const void Actor::set_host(Host* new_host) { - if (s4u::Actor::on_migration_start.get_slot_count() > 0) { // XBT_ATTRIB_DEPRECATED_v329 - static bool already_warned = false; - if (not already_warned) { - XBT_INFO("Please use s4u::Actor::on_host_change instead of s4u::Actor::on_migration_start. This will be removed " - "in v3.29"); - already_warned = true; - } - s4u::Actor::on_migration_start(*this); - } - 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); }); - if (s4u::Actor::on_migration_end.get_slot_count() > 0) { // XBT_ATTRIB_DEPRECATED_v329 - static bool already_warned = false; - if (not already_warned) { - XBT_INFO("Please use s4u::Actor::on_host_change instead of s4u::Actor::on_migration_end. This will be removed in " - "v3.29"); - already_warned = true; - } - s4u::Actor::on_migration_end(*this); - } - s4u::Actor::on_host_change(*this, *previous_location); } @@ -208,7 +194,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 */ @@ -223,7 +209,7 @@ void Actor::resume() s4u::Actor::on_resume(*this); } -bool Actor::is_suspended() +bool Actor::is_suspended() const { return pimpl_->is_suspended(); } @@ -234,14 +220,14 @@ void Actor::set_kill_time(double kill_time) } /** @brief Get the kill time of an actor(or 0 if unset). */ -double Actor::get_kill_time() +double Actor::get_kill_time() const { return pimpl_->get_kill_time(); } void Actor::kill() { - kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self(); + const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self(); kernel::actor::simcall([this, self] { self->kill(pimpl_); }); } @@ -249,16 +235,16 @@ 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->iface(); + return actor->get_iface(); else return ActorPtr(); } void Actor::kill_all() { - kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self(); + const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self(); kernel::actor::simcall([self] { self->kill_all(); }); } @@ -305,22 +291,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->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->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() @@ -330,7 +328,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); } @@ -342,7 +340,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, @@ -351,26 +349,20 @@ void parallel_execute(const std::vector& hosts, const std::vectorwait(); } -void parallel_execute(const std::vector& hosts, const std::vector& flops_amounts, - const std::vector& bytes_amounts, double timeout) // XBT_ATTRIB_DEPRECATED_v329 -{ - exec_init(hosts, flops_amounts, bytes_amounts)->wait_for(timeout); -} - ExecPtr exec_init(double flops_amount) { - return ExecPtr(new ExecSeq(get_host(), flops_amount)); + 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(), "bytes_amounts must be a matrix of size host_count * host_count (%zu*%zu), but it's of size %zu.", - hosts.size(), hosts.size(), flops_amounts.size()); + hosts.size(), hosts.size(), bytes_amounts.size()); /* Check that we are not mixing VMs and PMs in the parallel task */ bool is_a_vm = (nullptr != dynamic_cast(hosts.front())); xbt_assert(std::all_of(hosts.begin(), hosts.end(), @@ -385,13 +377,13 @@ ExecPtr exec_init(const std::vector& hosts, const std::vectorset_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; } @@ -423,8 +415,8 @@ Host* get_host() void suspend() { kernel::actor::ActorImpl* self = simgrid::kernel::actor::ActorImpl::self(); - s4u::Actor::on_suspend(*self->ciface()); - kernel::actor::simcall_blocking([self] { self->suspend(); }); + s4u::Actor::on_suspend(*self->get_ciface()); + kernel::actor::simcall_blocking([self] { self->suspend(); }); } void exit() @@ -435,7 +427,7 @@ void exit() void on_exit(const std::function& fun) { - simgrid::kernel::actor::ActorImpl::self()->iface()->on_exit(fun); + simgrid::kernel::actor::ActorImpl::self()->get_iface()->on_exit(fun); } /** @brief Moves the current actor to another host @@ -444,11 +436,7 @@ void on_exit(const std::function& fun) */ void set_host(Host* new_host) { - simgrid::kernel::actor::ActorImpl::self()->iface()->set_host(new_host); -} -void migrate(Host* new_host) // deprecated -{ - set_host(new_host); + simgrid::kernel::actor::ActorImpl::self()->get_iface()->set_host(new_host); } } // namespace this_actor @@ -456,26 +444,60 @@ void migrate(Host* new_host) // deprecated } // namespace simgrid /* **************************** Public C interface *************************** */ +size_t sg_actor_count() +{ + return simgrid::s4u::Engine::get_instance()->get_actor_count(); +} + +sg_actor_t* sg_actor_list() +{ + const simgrid::s4u::Engine* e = simgrid::s4u::Engine::get_instance(); + size_t actor_count = e->get_actor_count(); + xbt_assert(actor_count > 0, "There is no actor!"); + std::vector actors = e->get_all_actors(); + + 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; +} 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::simix::ActorCode function; + simgrid::kernel::actor::ActorCode function; if (code) function = simgrid::xbt::wrap_main(code, argc, argv); - actor->start(std::move(function)); + 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) +{ + simgrid::kernel::actor::ActorCode function = simgrid::xbt::wrap_main(code, argc, argv); + return simgrid::s4u::Actor::init(name, host)->start(function).get(); } -/** @ingroup m_actor_management +void sg_actor_set_stacksize(sg_actor_t actor, unsigned size) +{ + actor->set_stacksize(size); +} + +void sg_actor_exit() +{ + simgrid::s4u::this_actor::exit(); +} + +/** * @brief Returns the process ID of @a actor. * * 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 */ @@ -484,33 +506,45 @@ aid_t sg_actor_get_PID(const_sg_actor_t actor) return actor->get_pid(); } -/** @ingroup m_actor_management +/** * @brief Returns the process ID of the parent of @a 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(); } -/** @ingroup m_actor_management - * +/** * @brief Return a #sg_actor_t given its PID. * * This function search in the list of all the created sg_actor_t for a sg_actor_t whose PID is equal to @a PID. * 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(); } -/** @ingroup m_actor_management - * @brief Return the name of an actor. - */ +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) { return actor->get_cname(); @@ -521,7 +555,7 @@ sg_host_t sg_actor_get_host(const_sg_actor_t actor) return actor->get_host(); } -/** @ingroup m_actor_management +/** * @brief Returns the value of a given actor property * * @param actor an actor @@ -533,7 +567,7 @@ const char* sg_actor_get_property_value(const_sg_actor_t actor, const char* name return actor->get_property(name); } -/** @ingroup m_actor_management +/** * @brief Return the list of properties * * This function returns all the parameters associated with an actor @@ -551,7 +585,7 @@ xbt_dict_t sg_actor_get_properties(const_sg_actor_t actor) return as_dict; } -/** @ingroup m_actor_management +/** * @brief Suspend the actor. * * This function suspends the actor by suspending the task on which it was waiting for the completion. @@ -562,7 +596,7 @@ void sg_actor_suspend(sg_actor_t actor) actor->suspend(); } -/** @ingroup m_actor_management +/** * @brief Resume a suspended actor. * * This function resumes a suspended actor by resuming the task on which it was waiting for the completion. @@ -573,27 +607,23 @@ void sg_actor_resume(sg_actor_t actor) actor->resume(); } -/** @ingroup m_actor_management +/** * @brief Returns true if the actor is suspended . * * This checks whether an actor is suspended or not by inspecting the task on which it was waiting for the completion. */ -int sg_actor_is_suspended(sg_actor_t actor) +int sg_actor_is_suspended(const_sg_actor_t actor) { return actor->is_suspended(); } -/** - * @ingroup m_actor_management - * @brief Restarts an actor from the beginning. - */ +/** @brief Restarts an actor from the beginning. */ sg_actor_t sg_actor_restart(sg_actor_t actor) { return actor->restart(); } /** - * @ingroup m_actor_management * @brief Sets the "auto-restart" flag of the actor. * If the flag is set to 1, the actor will be automatically restarted when its host comes back up. */ @@ -602,15 +632,19 @@ void sg_actor_set_auto_restart(sg_actor_t actor, int auto_restart) actor->set_auto_restart(auto_restart); } -/** @ingroup m_actor_management - * @brief This actor will be terminated automatically when the last non-daemon actor finishes - */ +/** @brief This actor will be terminated automatically when the last non-daemon actor finishes */ void sg_actor_daemonize(sg_actor_t actor) { actor->daemonize(); } -/** @ingroup m_actor_management +/** Returns whether or not this actor has been daemonized or not */ +int sg_actor_is_daemon(const_sg_actor_t actor) +{ + return actor->is_daemon(); +} + +/** * @brief Migrates an actor to another location. * * This function changes the value of the #sg_host_t on which @a actor is running. @@ -619,18 +653,14 @@ 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) // deprecated -{ - process->set_host(host); -} -/** @ingroup m_actor_management +/** * @brief Wait for the completion of a #sg_actor_t. * * @param actor the actor to wait for * @param timeout wait until the actor is over, or the timeout expires */ -void sg_actor_join(sg_actor_t actor, double timeout) +void sg_actor_join(const_sg_actor_t actor, double timeout) { actor->join(timeout); } @@ -645,7 +675,7 @@ void sg_actor_kill_all() simgrid::s4u::Actor::kill_all(); } -/** @ingroup m_actor_management +/** * @brief Set the kill time of an actor. * * @param actor an actor @@ -667,6 +697,11 @@ void sg_actor_sleep_for(double duration) simgrid::s4u::this_actor::sleep_for(duration); } +void sg_actor_sleep_until(double wakeup_time) +{ + simgrid::s4u::this_actor::sleep_until(wakeup_time); +} + sg_actor_t sg_actor_attach(const char* name, void* data, sg_host_t host, xbt_dict_t properties) { xbt_assert(host != nullptr, "Invalid parameters: host and code params must not be nullptr"); @@ -678,16 +713,17 @@ 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"); } simgrid::s4u::this_actor::yield(); - return actor->ciface(); + return actor->get_ciface(); } void sg_actor_detach() @@ -710,25 +746,57 @@ const char* sg_actor_self_get_name() return simgrid::s4u::this_actor::get_cname(); } -void* sg_actor_self_data() +void* sg_actor_self_get_data() { return simgrid::s4u::Actor::self()->get_data(); } -void sg_actor_self_data_set(void* userdata) +void sg_actor_self_set_data(void* userdata) { simgrid::s4u::Actor::self()->set_data(userdata); } +void* sg_actor_self_data() // XBT_ATTRIB_DEPRECATED_v330 +{ + return sg_actor_self_get_data(); +} + +void sg_actor_self_data_set(void* userdata) // XBT_ATTRIB_DEPRECATED_v330 +{ + sg_actor_self_set_data(userdata); +} + sg_actor_t sg_actor_self() { return simgrid::s4u::Actor::self(); } -void sg_actor_self_execute(double flops) +void sg_actor_self_execute(double flops) // XBT_ATTRIB_DEPRECATED_v330 +{ + simgrid::s4u::this_actor::execute(flops); +} + +void sg_actor_execute(double flops) { simgrid::s4u::this_actor::execute(flops); } +void sg_actor_execute_with_priority(double flops, double priority) +{ + simgrid::s4u::this_actor::exec_init(flops)->set_priority(priority)->wait(); +} + +void sg_actor_parallel_execute(int host_nb, sg_host_t* host_list, double* flops_amount, double* bytes_amount) +{ + std::vector hosts(host_list, host_list + host_nb); + std::vector flops; + std::vector bytes; + if (flops_amount != nullptr) + flops = std::vector(flops_amount, flops_amount + host_nb); + if (bytes_amount != nullptr) + bytes = std::vector(bytes_amount, bytes_amount + host_nb * host_nb); + + simgrid::s4u::this_actor::parallel_execute(hosts, flops, bytes); +} /** @brief Take an extra reference on that actor to prevent it to be garbage-collected */ void sg_actor_ref(const_sg_actor_t actor) @@ -742,12 +810,62 @@ void sg_actor_unref(const_sg_actor_t actor) } /** @brief Return the user data of a #sg_actor_t */ -void* sg_actor_data(const_sg_actor_t actor) +void* sg_actor_get_data(const_sg_actor_t actor) { return actor->get_data(); } + /** @brief Set the user data of a #sg_actor_t */ -void sg_actor_data_set(sg_actor_t actor, void* userdata) +void sg_actor_set_data(sg_actor_t actor, void* userdata) { actor->set_data(userdata); } + +void* sg_actor_data(const_sg_actor_t actor) // XBT_ATTRIB_DEPRECATED_v330 +{ + return sg_actor_get_data(actor); +} + +void sg_actor_data_set(sg_actor_t actor, void* userdata) // XBT_ATTRIB_DEPRECATED_v330 +{ + sg_actor_set_data(actor, userdata); +} + +/** @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) +{ + simgrid::s4u::this_actor::on_exit([fun, data](bool failed) { fun(failed ? 1 /*FAILURE*/ : 0 /*SUCCESS*/, data); }); +} + +sg_exec_t sg_actor_exec_init(double computation_amount) +{ + simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_init(computation_amount); + exec->add_ref(); + return exec.get(); +} + +sg_exec_t sg_actor_parallel_exec_init(int host_nb, const sg_host_t* host_list, double* flops_amount, + double* bytes_amount) +{ + std::vector hosts(host_list, host_list + host_nb); + std::vector flops; + std::vector bytes; + if (flops_amount != nullptr) + flops = std::vector(flops_amount, flops_amount + host_nb); + if (bytes_amount != nullptr) + bytes = std::vector(bytes_amount, bytes_amount + host_nb * host_nb); + + simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_init(hosts, flops, bytes); + exec->add_ref(); + return exec.get(); +} + +sg_exec_t sg_actor_exec_async(double computation_amount) +{ + simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_async(computation_amount); + exec->add_ref(); + return exec.get(); +}