#include <atomic>
#include <functional>
-#include <future>
#include <memory>
#include <stdexcept>
#include <type_traits>
namespace simgrid {
namespace s4u {
-/** @addtogroup s4u_actor
- *
- * @tableofcontents
+/** @ingroup s4u_api
*
* An actor is an independent stream of execution in your distributed application.
*
* of this standard</a> may help to understand the philosophy of the S4U
* Actors.
*
- * (back to the @ref s4u_api "S4U documentation")
- *
* @section s4u_actor_def Defining the skeleton of an Actor
*
* %As in the <a href="http://en.cppreference.com/w/cpp/thread">C++11
* pure function or as an object. It is very simple with functions:
*
* @code{.cpp}
+ * #include "s4u/actor.hpp"
+ *
* // Declare the code of your worker
* void worker() {
* printf("Hello s4u");
* };
*
* // From your main or from another actor, create your actor on the host Jupiter
- * Actor("worker", simgrid::s4u::Host::by_name("Jupiter"), worker);
+ * // The following line actually creates a new actor, even if there is no "new".
+ * Actor("Alice", simgrid::s4u::Host::by_name("Jupiter"), worker);
* @endcode
*
* But some people prefer to encapsulate their actors in classes and
* };
*
* // From your main or from another actor, create your actor. Note the () after Worker
- * Actor("worker", simgrid::s4u::Host::by_name("Jupiter"), Worker());
+ * Actor("Bob", simgrid::s4u::Host::by_name("Jupiter"), Worker());
* @endcode
*
* @section s4u_actor_flesh Fleshing your actor
Task(F&& code, Args&&... args) :
code_(std::forward<F>(code)),
args_(std::forward<Args>(args)...)
- {}
+ {
+ done_.clear();
+ }
void operator()()
{
if (done_.test_and_set())
simgrid::xbt::apply(std::move(code_), std::move(args_));
}
private:
- std::atomic_flag done_ = ATOMIC_FLAG_INIT;
+ std::atomic_flag done_;
F code_;
std::tuple<Args...> args_;
};
Actor(const char* name, s4u::Host *host, double killTime, std::function<void()> code);
Actor(const char* name, s4u::Host *host, std::function<void()> code)
- : Actor(name, host, -1.0d, std::move(code)) {};
+ : Actor(name, host, -1.0, std::move(code)) {};
/** Create an actor using code
*
Actor(name, host, wrap_task(std::move(code), std::move(args)...))
{}
+ // Create actor from function name:
+
+ Actor(const char* name, s4u::Host *host, double killTime,
+ const char* function, std::vector<std::string> args);
+
+ Actor(const char* name, s4u::Host *host, const char* function,
+ std::vector<std::string> args)
+ : Actor(name, host, -1.0, function, std::move(args)) {}
+
/** Retrieves the actor that have the given PID (or NULL if not existing) */
//static Actor *byPid(int pid); not implemented
void kill();
static void kill(int pid);
+ static Actor forPid(int pid);
/**
* Wait for the actor to finish.
/** Ask kindly to all actors to die. Only the issuer will survive. */
static void killAll();
+ bool valid() const { return pimpl_ != nullptr; }
+
private:
smx_process_t pimpl_ = nullptr;
};
-/** @brief Static methods working on the current actor (see @ref s4u_actor) */
+/** @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) */
* 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();
};