X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/1cce0801abcad7c884f9e72ceda87e36d6635104..a138d21077d565562a591d21260cc3937cacdba0:/src/s4u/s4u_actor.cpp diff --git a/src/s4u/s4u_actor.cpp b/src/s4u/s4u_actor.cpp index 0c8b49ad6d..7b6e9687ab 100644 --- a/src/s4u/s4u_actor.cpp +++ b/src/s4u/s4u_actor.cpp @@ -1,72 +1,119 @@ -/* Copyright (c) 2006-2014. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2006-2017. 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. */ #include "xbt/log.h" -#include "src/msg/msg_private.h" -#include "simgrid/s4u/actor.hpp" -#include "simgrid/s4u/comm.hpp" -#include "simgrid/s4u/host.hpp" -#include "simgrid/s4u/mailbox.hpp" +#include "simgrid/s4u/Actor.hpp" +#include "simgrid/s4u/Comm.hpp" +#include "simgrid/s4u/Host.hpp" +#include "simgrid/s4u/Mailbox.hpp" -#include "src/simix/smx_private.h" +#include "src/kernel/context/Context.hpp" +#include -XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor,"S4U actors"); +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor, "S4U actors"); -using namespace simgrid; +namespace simgrid { +namespace s4u { + +// ***** Actor creation ***** +ActorPtr Actor::self() +{ + smx_context_t self_context = SIMIX_context_self(); + if (self_context == nullptr) + return simgrid::s4u::ActorPtr(); + + return self_context->process()->iface(); +} -s4u::Actor::Actor(const char* name, s4u::Host *host, double killTime, std::function code) +ActorPtr Actor::createActor(const char* name, s4u::Host* host, std::function code) { - // TODO, when autorestart is used, the std::function is copied so the new - // instance will get a fresh (reinitialized) state. Is this what we want? - this->pimpl_ = SIMIX_process_ref(simcall_process_create( - name, std::move(code), nullptr, host->name().c_str(), - killTime, nullptr, 0)); + simgrid::simix::ActorImpl* actor = simcall_process_create(name, std::move(code), nullptr, host, nullptr); + return actor->iface(); } -s4u::Actor::Actor(const char* name, s4u::Host *host, double killTime, - const char* function, std::vector args) +ActorPtr Actor::createActor(const char* name, s4u::Host* host, const char* function, std::vector args) { simgrid::simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(function); simgrid::simix::ActorCode code = factory(std::move(args)); - this->pimpl_ = SIMIX_process_ref(simcall_process_create( - name, std::move(code), nullptr, host->name().c_str(), - killTime, nullptr, 0)); + simgrid::simix::ActorImpl* actor = simcall_process_create(name, std::move(code), nullptr, host, nullptr); + return actor->iface(); } -void s4u::Actor::join() { - simcall_process_join(pimpl_, -1); +// ***** Actor methods ***** + +void Actor::join() { + simcall_process_join(this->pimpl_, -1); } -void s4u::Actor::setAutoRestart(bool autorestart) { +void Actor::setAutoRestart(bool autorestart) { simcall_process_auto_restart_set(pimpl_,autorestart); } -s4u::Host *s4u::Actor::getHost() { - return s4u::Host::by_name(sg_host_get_name(simcall_process_get_host(pimpl_))); +void Actor::onExit(int_f_pvoid_pvoid_t fun, void* data) +{ + simcall_process_on_exit(pimpl_, fun, data); +} + +void Actor::migrate(Host* new_host) +{ + simcall_process_set_host(pimpl_, new_host); +} + +s4u::Host* Actor::host() +{ + return this->pimpl_->host; +} + +const char* Actor::cname() +{ + return this->pimpl_->name.c_str(); +} + +simgrid::xbt::string Actor::name() +{ + return this->pimpl_->name; +} + +aid_t Actor::pid() +{ + return this->pimpl_->pid; +} + +aid_t Actor::ppid() +{ + return this->pimpl_->ppid; +} + +void Actor::suspend() +{ + simcall_process_suspend(pimpl_); } -const char* s4u::Actor::getName() { - return simcall_process_get_name(pimpl_); +void Actor::resume() +{ + simcall_process_resume(pimpl_); } -int s4u::Actor::getPid(){ - return simcall_process_get_PID(pimpl_); +int Actor::isSuspended() +{ + return simcall_process_is_suspended(pimpl_); } -void s4u::Actor::setKillTime(double time) { +void Actor::setKillTime(double time) { simcall_process_set_kill_time(pimpl_,time); } -double s4u::Actor::getKillTime() { +double Actor::killTime() +{ return simcall_process_get_kill_time(pimpl_); } -void s4u::Actor::kill(int pid) { - msg_process_t process = SIMIX_process_from_PID(pid); +void Actor::kill(aid_t pid) +{ + smx_actor_t process = SIMIX_process_from_PID(pid); if(process != nullptr) { simcall_process_kill(process); } else { @@ -76,57 +123,174 @@ void s4u::Actor::kill(int pid) { } } -void s4u::Actor::kill() { +smx_actor_t Actor::getImpl() { + return pimpl_; +} + +void Actor::kill() { simcall_process_kill(pimpl_); } -simgrid::s4u::Actor s4u::Actor::forPid(int pid) +// ***** Static functions ***** + +ActorPtr Actor::byPid(aid_t pid) +{ + smx_actor_t process = SIMIX_process_from_PID(pid); + if (process != nullptr) + return process->iface(); + else + return ActorPtr(); +} + +void Actor::killAll() { - // Should we throw if we did not find it? - smx_process_t process = SIMIX_process_from_PID(pid); - return simgrid::s4u::Actor(process); + simcall_process_killall(1); } -// static stuff: +void Actor::killAll(int resetPid) +{ + simcall_process_killall(resetPid); +} -void s4u::Actor::killAll() { - simcall_process_killall(1); +/** Retrieve the property value (or nullptr if not set) */ +const char* Actor::property(const char* key) +{ + return (char*)xbt_dict_get_or_null(simcall_process_get_properties(pimpl_), key); +} +void Actor::setProperty(const char* key, const char* value) +{ + simgrid::simix::kernelImmediate([this, key, value] { + xbt_dict_set(simcall_process_get_properties(pimpl_), key, (char*)value, (void_f_pvoid_t) nullptr); + }); } +// ***** this_actor ***** -namespace simgrid { -namespace s4u { namespace this_actor { -void sleep(double duration) { - simcall_process_sleep(duration); +/** Returns true if run from the kernel mode, and false if run from a real actor + * + * Everything that is run out of any actor (simulation setup before the engine is run, + * computing the model evolutions as a result to the actors' action, etc) is run in + * kernel mode, just as in any operating systems. + * + * In SimGrid, the actor in charge of doing the stuff in kernel mode is called Maestro, + * because it is the one scheduling when the others should move or wait. + */ +bool isMaestro() +{ + smx_context_t self_context = SIMIX_context_self(); + return self_context == nullptr; +} + +void sleep_for(double duration) +{ + if (duration > 0) + simcall_process_sleep(duration); +} + +XBT_PUBLIC(void) sleep_until(double timeout) +{ + double now = SIMIX_get_clock(); + if (timeout > now) + simcall_process_sleep(timeout - now); } e_smx_state_t execute(double flops) { - smx_synchro_t s = simcall_execution_start(nullptr,flops,1.0/*priority*/,0./*bound*/, 0L/*affinity*/); + smx_activity_t s = simcall_execution_start(nullptr,flops,1.0/*priority*/,0./*bound*/); return simcall_execution_wait(s); } -void* recv(Mailbox &chan) { +void* recv(MailboxPtr chan) { void *res = nullptr; - Comm c = Comm::recv_init(chan); - c.setDstData(&res,sizeof(res)); - c.wait(); + CommPtr c = Comm::recv_init(chan); + c->setDstData(&res, sizeof(res)); + c->wait(); return res; } -void send(Mailbox &chan, void *payload, size_t simulatedSize) { - Comm c = Comm::send_init(chan); - c.setRemains(simulatedSize); - c.setSrcData(payload); - // c.start() is optional. - c.wait(); +void send(MailboxPtr chan, void* payload, double simulatedSize) +{ + CommPtr c = Comm::send_init(chan); + c->setRemains(simulatedSize); + c->setSrcData(payload); + // c->start() is optional. + c->wait(); +} + +void send(MailboxPtr chan, void* payload, double simulatedSize, double timeout) +{ + CommPtr c = Comm::send_init(chan); + c->setRemains(simulatedSize); + c->setSrcData(payload); + // c->start() is optional. + c->wait(timeout); +} + +CommPtr isend(MailboxPtr chan, void* payload, double simulatedSize) +{ + return Comm::send_async(chan, payload, simulatedSize); +} + +void dsend(MailboxPtr chan, void* payload, double simulatedSize) +{ + Comm::send_detached(chan, payload, simulatedSize); +} + +CommPtr irecv(MailboxPtr chan, void** data) +{ + return Comm::recv_async(chan, data); +} + +aid_t pid() +{ + return SIMIX_process_self()->pid; } -int getPid() { - return simcall_process_get_PID(SIMIX_process_self()); +aid_t ppid() +{ + return SIMIX_process_self()->ppid; } +std::string name() +{ + return SIMIX_process_self()->name; +} + +Host* host() +{ + return SIMIX_process_self()->host; +} + +void suspend() +{ + simcall_process_suspend(SIMIX_process_self()); +} + +void resume() +{ + simcall_process_resume(SIMIX_process_self()); +} + +int isSuspended() +{ + return simcall_process_is_suspended(SIMIX_process_self()); +} + +void kill() +{ + simcall_process_kill(SIMIX_process_self()); +} + +void onExit(int_f_pvoid_pvoid_t fun, void* data) +{ + simcall_process_on_exit(SIMIX_process_self(), fun, data); +} + +void migrate(Host* new_host) +{ + simcall_process_set_host(SIMIX_process_self(), new_host); +} } } }