- 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() {}
-
- /** The main method of your agent */
- virtual int main(int argc, char **argv);
-
- /** The Actor that is currently running */
- static Actor *current();
- /** Retrieves the actor that have the given PID (or NULL if not existing) */
- static Actor *byPid(int pid);
-
- /** Retrieves the name of that actor */
- const char*getName();
- /** Retrieves the host on which that actor is running */
- s4u::Host *getHost();
- /** Retrieves the PID of that actor */
- int getPid();
-
- /** If set to true, the actor will automatically restart when its host reboots */
- void setAutoRestart(bool autorestart);
- /** Sets the time at which that actor should be killed */
- void setKillTime(double time);
- /** 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).
- * SimGrid sometimes have issues when you kill actors that are currently communicating and such. We are working on it to fix the issues.
- */
- void kill();
-
- /** Block the actor sleeping for that amount of seconds (may throws hostFailure) */
- void sleep(double duration);
-
- /** Block the actor, computing the given amount of flops */
- 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);
-
- /** 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);
-
-protected:
- smx_process_t getInferior() {return p_smx_process;}
-private:
- smx_process_t p_smx_process;
+
+ // ***** No copy *****
+
+ Actor(Actor const&) = delete;
+ Actor& operator=(Actor const&) = delete;
+
+ // ***** Reference count (delegated to pimpl_) *****
+
+ friend void intrusive_ptr_add_ref(Actor* actor)
+ {
+ xbt_assert(actor != nullptr);
+ SIMIX_process_ref(actor->pimpl_);
+ }
+ friend void intrusive_ptr_release(Actor* actor)
+ {
+ xbt_assert(actor != nullptr);
+ SIMIX_process_unref(actor->pimpl_);
+ }
+ using Ptr = boost::intrusive_ptr<Actor>;
+
+ // ***** Actor creation *****
+
+ /** Create an actor using a function
+ *
+ * If the actor is restarted, the actor has a fresh copy of the function.
+ */
+ static Ptr createActor(const char* name, s4u::Host *host, double killTime, std::function<void()> code);
+
+ static Ptr createActor(const char* name, s4u::Host *host, std::function<void()> code)
+ {
+ return createActor(name, host, -1.0, std::move(code));
+ }
+
+ /** Create an actor using code
+ *
+ * Using this constructor, move-only type can be used. The consequence is
+ * that we cannot copy the value and restart the process in its initial
+ * state. In order to use auto-restart, an explicit `function` must be passed
+ * instead.
+ */
+ template<class F, class... Args,
+ // This constructor is enabled only if the call code(args...) is valid:
+ typename = typename std::result_of<F(Args...)>::type
+ >
+ static Ptr createActor(const char* name, s4u::Host *host, F code, Args... args)
+ {
+ return createActor(name, host, wrap_task(std::move(code), std::move(args)...));
+ }
+
+ // Create actor from function name:
+
+ static Ptr createActor(const char* name, s4u::Host *host, double killTime,
+ const char* function, std::vector<std::string> args);
+
+ static Ptr createActor(const char* name, s4u::Host *host, const char* function,
+ std::vector<std::string> args)
+ {
+ return createActor(name, host, -1.0, function, std::move(args));
+ }
+
+ // ***** Methods *****
+
+ /** 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();
+ /** Retrieves the host on which that actor is running */
+ s4u::Host *getHost();
+ /** Retrieves the PID of that actor */
+ int getPid();
+
+ /** If set to true, the actor will automatically restart when its host reboots */
+ void setAutoRestart(bool autorestart);
+ /** Sets the time at which that actor should be killed */
+ void setKillTime(double time);
+ /** Retrieves the time at which that actor will be killed (or -1 if not set) */
+ double getKillTime();
+
+ /** Ask the actor to die.
+ *
+ * It will only notice your request when doing a simcall next time (a communication or similar).
+ * SimGrid sometimes have issues when you kill actors that are currently communicating and such. We are working on it to fix the issues.
+ */
+ void kill();
+
+ static void kill(int pid);
+ static Ptr forPid(int pid);
+
+ /**
+ * Wait for the actor to finish.
+ */
+ void join();
+
+ // Static methods on all actors:
+
+ /** Ask kindly to all actors to die. Only the issuer will survive. */
+ static void killAll();
+
+ smx_process_t getInferior();
+};
+
+using ActorPtr = Actor::Ptr;
+
+/** @ingroup s4u_api
+ * @brief Static methods working on the current actor (see @ref s4u::Actor) */
+namespace this_actor {
+
+ /** Block the actor sleeping for that amount of seconds (may throws hostFailure) */
+ XBT_PUBLIC(void) sleep(double duration);
+
+ template<class Rep, class Period>
+ inline void sleep(std::chrono::duration<Rep, Period> duration)
+ {
+ auto seconds = std::chrono::duration_cast<SimulationClockDuration>(duration);
+ sleep(seconds.count());
+ }
+
+ /** Block the actor, computing the given amount of flops */
+ XBT_PUBLIC(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).
+ */
+ XBT_PUBLIC(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).
+ */
+ XBT_PUBLIC(void) send(Mailbox &chan, void*payload, size_t simulatedSize);
+
+ /**
+ * Return the PID of the current actor.
+ */
+ XBT_PUBLIC(int) getPid();
+