XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
-class Worker : simgrid::s4u::Actor {
+class Worker {
public:
- Worker(const char*procname, simgrid::s4u::Host *host,int argc, char **argv)
- : simgrid::s4u::Actor(procname,host,argc,argv){}
-
- int main(int argc, char **argv) {
+ int operator()() {
XBT_INFO("Hello s4u, I'm ready to serve");
-
- char *msg = (char*)recv(*simgrid::s4u::Mailbox::byName("worker"));
+ char *msg = (char*)simgrid::s4u::Actor::recv(*simgrid::s4u::Mailbox::byName("worker"));
XBT_INFO("I received '%s'",msg);
XBT_INFO("I'm done. See you.");
return 1;
}
};
-class Master : simgrid::s4u::Actor {
+class Master {
public:
- Master(const char*procname, simgrid::s4u::Host *host,int argc, char **argv)
- : Actor(procname,host,argc,argv){}
-
- int main(int argc, char **argv) {
+ int operator()() {
const char *msg = "GaBuZoMeu";
XBT_INFO("Hello s4u, I have something to send");
- send(*simgrid::s4u::Mailbox::byName("worker"), xbt_strdup(msg), strlen(msg));
-
+ simgrid::s4u::Actor::send(*simgrid::s4u::Mailbox::byName("worker"), xbt_strdup(msg), strlen(msg));
XBT_INFO("I'm done. See you.");
return 1;
}
int main(int argc, char **argv) {
simgrid::s4u::Engine *e = new simgrid::s4u::Engine(&argc,argv);
e->loadPlatform("../../platforms/two_hosts_platform.xml");
-
- new Worker("worker", simgrid::s4u::Host::by_name("host0"), 0, NULL);
- new Master("master", simgrid::s4u::Host::by_name("host1"), 0, NULL);
+ new simgrid::s4u::Actor("worker", simgrid::s4u::Host::by_name("host0"), Worker());
+ new simgrid::s4u::Actor("master", simgrid::s4u::Host::by_name("host1"), 0, Master());
e->run();
return 0;
}
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
-class myHost : simgrid::s4u::Actor {
+class MyHost {
public:
- myHost(const char*procname, simgrid::s4u::Host *host,int argc, char **argv)
-: simgrid::s4u::Actor(procname,host,argc,argv){}
void show_info(boost::unordered_map <std::string, simgrid::s4u::Storage*> const&mounts) {
XBT_INFO("Storage info on %s:",
}
}
- int main(int argc, char **argv) {
+ int operator()() {
boost::unordered_map <std::string, simgrid::s4u::Storage *> const& mounts =
simgrid::s4u::Host::current()->mountedStorages();
}
};
-int main(int argc, char **argv) {
+int main(int argc, char **argv)
+{
simgrid::s4u::Engine *e = new simgrid::s4u::Engine(&argc,argv);
e->loadPlatform("../../platforms/storage/storage.xml");
-
- new myHost("host", simgrid::s4u::Host::by_name("denise"), 0, NULL);
+ new simgrid::s4u::Actor("host", simgrid::s4u::Host::by_name("denise"), MyHost());
e->run();
return 0;
}
*
* \verbatim
* #include "s4u/actor.hpp"
- *
- * class Worker : simgrid::s4u::Actor {
- *
- * int main(int argc, char **argv) {
- * printf("Hello s4u");
- * }
+ *
+ * class Worker {
+ * int operator()() {
+ * printf("Hello s4u");
+ * return 0;
+ * }
* };
+ *
+ * new Actor("worker", host, Worker());
* \endverbatim
*
*/
XBT_PUBLIC_CLASS Actor {
- friend Comm;
Actor(smx_process_t smx_proc);
public:
- Actor(const char*name, s4u::Host *host, int argc, char **argv);
- Actor(const char*name, s4u::Host *host, int argc, char **argv, double killTime);
- virtual ~Actor() {}
+ Actor(const char* name, s4u::Host *host, double killTime, std::function<int()> code);
+ Actor(const char* name, s4u::Host *host, std::function<int()> code)
+ : Actor(name, host, -1, std::move(code)) {};
+ template<class C>
+ Actor(const char* name, s4u::Host *host, C code)
+ : Actor(name, host, -1, std::function<int()>(std::move(code))) {}
+ ~Actor();
- /** The main method of your agent */
- virtual int main(int argc, char **argv);
-
- /** The Actor that is currently running */
- static Actor &self();
/** Retrieves the actor that have the given PID (or NULL if not existing) */
//static Actor *byPid(int pid); not implemented
/** Retrieves the name of that actor */
- const char*getName();
+ const char* getName();
/** Retrieves the host on which that actor is running */
s4u::Host *getHost();
/** Retrieves the PID of that actor */
/** Retrieves the time at which that actor will be killed (or -1 if not set) */
double getKillTime();
- /** Ask kindly to all actors to die. Only the issuer will survive. */
- static void killAll();
/** Ask the actor to die.
*
* It will only notice your request when doing a simcall next time (a communication or similar).
*/
void kill();
+ // Static methods on all actors:
+
+ /** Ask kindly to all actors to die. Only the issuer will survive. */
+ static void killAll();
+
+ // Static methods working on the current actor:
+
/** Block the actor sleeping for that amount of seconds (may throws hostFailure) */
- void sleep(double duration);
+ static void sleep(double duration);
/** Block the actor, computing the given amount of flops */
- e_smx_state_t execute(double flop);
+ static e_smx_state_t execute(double flop);
/** Block the actor until it gets a message from the given mailbox.
*
* See \ref Comm for the full communication API (including non blocking communications).
*/
- void *recv(Mailbox &chan);
+ static void *recv(Mailbox &chan);
/** Block the actor until it delivers a message of the given simulated size to the given mailbox
*
* See \ref Comm for the full communication API (including non blocking communications).
*/
- void send(Mailbox &chan, void*payload, size_t simulatedSize);
+ static void send(Mailbox &chan, void*payload, size_t simulatedSize);
protected:
smx_process_t getInferior() {return pimpl_;}
private:
- smx_process_t pimpl_;
+ smx_process_t pimpl_ = nullptr;
};
+
}} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_ACTOR_HPP */
#if 0
-public abstract class Actor implements Runnable {
- /** Suspends the process. See {@link #resume()} to resume it afterward */
- public native void suspend();
- /** Resume a process that was suspended by {@link #suspend()}. */
- public native void resume();
- /** Tests if a process is suspended. */
- public native boolean isSuspended();
+public final class Actor {
- /**
- * Returns the value of a given process property.
- */
- public native String getProperty(String name);
-
-
- /**
- * Migrates a process to another host.
- *
- * @param host The host where to migrate the process.
- *
- */
- public native void migrate(Host host);
-
- public native void exit();
- /**
- * This static method returns the current amount of processes running
- *
- * @return The count of the running processes
- */
- public native static int getCount();
+ public Actor(String name, Host host, double killTime, Runnable code);
+ // ....
}
#endif
public:
/** Creates (but don't start) an async send to the mailbox #dest */
- static Comm &send_init(Actor *sender, Mailbox &dest);
+ static Comm &send_init(Mailbox &dest);
/** Creates and start an async send to the mailbox #dest */
- static Comm &send_async(s4u::Actor *sender, Mailbox &dest, void *data, int simulatedByteAmount);
+ static Comm &send_async(Mailbox &dest, void *data, int simulatedByteAmount);
/** Creates (but don't start) an async recv onto the mailbox #from */
- static Comm &recv_init(s4u::Actor *receiver, Mailbox &from);
+ static Comm &recv_init(Mailbox &from);
/** Creates and start an async recv to the mailbox #from */
- static Comm &recv_async(s4u::Actor *receiver, Mailbox &from, void **data);
+ static Comm &recv_async(Mailbox &from, void **data);
void start() override;
void wait() override;
void (*copyDataFunction_)(smx_synchro_t, void*, size_t) = NULL;
private:
- Actor *sender_ = NULL;
- Actor *receiver_ = NULL;
+ smx_process_t sender_ = NULL;
+ smx_process_t receiver_ = NULL;
Mailbox *mailbox_ = NULL;
};
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor,"S4U actors");
-/* C main function of a actor, running this->main */
static int s4u_actor_runner(int argc, char **argv)
{
- simgrid::s4u::Actor *actor = (simgrid::s4u::Actor*) SIMIX_process_self_get_data();
- int res = actor->main(argc,argv);
- return res;
+ // Move the callback from the heap to the stack:
+ std::unique_ptr<std::function<int()>> code2 =
+ std::unique_ptr<std::function<int()>>(
+ static_cast<std::function<int()>*>(
+ SIMIX_process_self_get_data()));
+ std::function<int()> code = std::move(*code2);
+ code2 = nullptr;
+ // Call it:
+ // TODO, handle exceptions
+ return code();
}
-
-
using namespace simgrid;
-s4u::Actor::Actor(smx_process_t smx_proc) {
- pimpl_ = smx_proc;
-}
-s4u::Actor::Actor(const char *name, s4u::Host *host, int argc, char **argv)
- : s4u::Actor::Actor(name,host, argc,argv, -1) {
-}
-s4u::Actor::Actor(const char *name, s4u::Host *host, int argc, char **argv, double killTime) {
- pimpl_ = simcall_process_create(name, s4u_actor_runner, this, host->name().c_str(), killTime, argc, argv, NULL/*properties*/,0);
-
- xbt_assert(pimpl_,"Cannot create the actor");
-// TRACE_msg_process_create(procname, simcall_process_get_PID(p_smx_process), host->getInferior());
-// simcall_process_on_exit(p_smx_process,(int_f_pvoid_pvoid_t)TRACE_msg_process_kill,p_smx_process);
-}
+s4u::Actor::Actor(smx_process_t smx_proc) : pimpl_(smx_proc) {}
-int s4u::Actor::main(int argc, char **argv) {
- fprintf(stderr,"Error: You should override the method main(int, char**) in Actor class %s\n",getName());
- return 0;
-}
-s4u::Actor &s4u::Actor::self()
+s4u::Actor::Actor(const char* name, s4u::Host *host, double killTime, std::function<int()> code)
{
- smx_process_t smx_proc = SIMIX_process_self();
- simgrid::s4u::Actor* res = (simgrid::s4u::Actor*) SIMIX_process_self_get_data();
- if (res == NULL) // The smx_process was not created by S4U (but by deployment?). Embed it in a S4U object
- res = new Actor(smx_proc);
- return *res;
+ std::function<int()>* code2 = new std::function<int()>(std::move(code));
+ this->pimpl_ = simcall_process_create(
+ name, s4u_actor_runner, code2, host->name().c_str(),
+ killTime, 0, NULL, NULL, 0);
}
+s4u::Actor::~Actor() {}
+
void s4u::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_)));
}
+
const char* s4u::Actor::getName() {
return simcall_process_get_name(pimpl_);
}
+
int s4u::Actor::getPid(){
return simcall_process_get_PID(pimpl_);
}
void s4u::Actor::setKillTime(double time) {
simcall_process_set_kill_time(pimpl_,time);
}
+
double s4u::Actor::getKillTime() {
return simcall_process_get_kill_time(pimpl_);
}
-void s4u::Actor::killAll() {
- simcall_process_killall(1);
-}
+
void s4u::Actor::kill() {
simcall_process_kill(pimpl_);
}
+// static stuff:
+
+void s4u::Actor::killAll() {
+ simcall_process_killall(1);
+}
+
void s4u::Actor::sleep(double duration) {
simcall_process_sleep(duration);
}
}
void *s4u::Actor::recv(Mailbox &chan) {
- void *res=NULL;
-
- Comm c = Comm::recv_init(this, chan);
+ void *res = NULL;
+ Comm c = Comm::recv_init(chan);
c.setDstData(&res,sizeof(res));
c.wait();
-
- return res;
+ return res;
}
+
void s4u::Actor::send(Mailbox &chan, void *payload, size_t simulatedSize) {
- Comm c = Comm::send_init(this,chan);
+ Comm c = Comm::send_init(chan);
c.setRemains(simulatedSize);
c.setSrcData(payload);
// c.start() is optional.
}
-s4u::Comm &s4u::Comm::send_init(s4u::Actor *sender, s4u::Mailbox &chan) {
+s4u::Comm &s4u::Comm::send_init(s4u::Mailbox &chan) {
s4u::Comm *res = new s4u::Comm();
- res->sender_ = sender;
+ res->sender_ = SIMIX_process_self();
res->mailbox_ = &chan;
-
return *res;
}
-s4u::Comm &s4u::Comm::recv_init(s4u::Actor *receiver, s4u::Mailbox &chan) {
+
+s4u::Comm &s4u::Comm::recv_init(s4u::Mailbox &chan) {
s4u::Comm *res = new s4u::Comm();
- res->receiver_ = receiver;
+ res->receiver_ = SIMIX_process_self();
res->mailbox_ = &chan;
-
return *res;
}
xbt_assert(state_ == inited);
if (srcBuff_ != NULL) { // Sender side
- pimpl_ = simcall_comm_isend(sender_->getInferior(), mailbox_->getInferior(), remains_, rate_,
+ pimpl_ = simcall_comm_isend(sender_, mailbox_->getInferior(), remains_, rate_,
srcBuff_, srcBuffSize_,
matchFunction_, cleanFunction_, copyDataFunction_,
userData_, detached_);
} else if (dstBuff_ != NULL) { // Receiver side
- pimpl_ = simcall_comm_irecv(receiver_->getInferior(), mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
+ pimpl_ = simcall_comm_irecv(receiver_, mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
matchFunction_, copyDataFunction_,
userData_, rate_);
simcall_comm_wait(pimpl_, -1/*timeout*/);
else {// p_state == inited. Save a simcall and do directly a blocking send/recv
if (srcBuff_ != NULL) {
- simcall_comm_send(sender_->getInferior(), mailbox_->getInferior(), remains_, rate_,
+ simcall_comm_send(sender_, mailbox_->getInferior(), remains_, rate_,
srcBuff_, srcBuffSize_,
matchFunction_, copyDataFunction_,
userData_, -1 /*timeout*/);
} else {
- simcall_comm_recv(receiver_->getInferior(), mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
+ simcall_comm_recv(receiver_, mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
matchFunction_, copyDataFunction_,
userData_, -1/*timeout*/, rate_);
}
// It's not started yet. Do it in one simcall
if (srcBuff_ != NULL) {
- simcall_comm_send(sender_->getInferior(), mailbox_->getInferior(), remains_, rate_,
+ simcall_comm_send(sender_, mailbox_->getInferior(), remains_, rate_,
srcBuff_, srcBuffSize_,
matchFunction_, copyDataFunction_,
userData_, timeout);
} else { // Receiver
- simcall_comm_recv(receiver_->getInferior(), mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
+ simcall_comm_recv(receiver_, mailbox_->getInferior(), dstBuff_, &dstBuffSize_,
matchFunction_, copyDataFunction_,
userData_, timeout, rate_);
}
state_ = finished;
}
-s4u::Comm &s4u::Comm::send_async(s4u::Actor *sender, Mailbox &dest, void *data, int simulatedSize) {
- s4u::Comm &res = s4u::Comm::send_init(sender, dest);
-
+s4u::Comm &s4u::Comm::send_async(Mailbox &dest, void *data, int simulatedSize) {
+ s4u::Comm &res = s4u::Comm::send_init(dest);
res.setRemains(simulatedSize);
res.srcBuff_ = data;
res.srcBuffSize_ = sizeof(void*);
-
res.start();
return res;
}
-s4u::Comm &s4u::Comm::recv_async(s4u::Actor *receiver, Mailbox &dest, void **data) {
- s4u::Comm &res = s4u::Comm::recv_init(receiver, dest);
-
+s4u::Comm &s4u::Comm::recv_async(Mailbox &dest, void **data) {
+ s4u::Comm &res = s4u::Comm::recv_init(dest);
res.setDstData(data);
-
res.start();
return res;
}