+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor, "S4U actors");
+
+namespace simgrid {
+namespace s4u {
+
+simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> s4u::Actor::onCreation;
+
+// ***** 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();
+}
+
+ActorPtr Actor::createActor(const char* name, s4u::Host* host, std::function<void()> code)
+{
+ simgrid::simix::ActorImpl* actor = simcall_process_create(name, std::move(code), nullptr, host, nullptr);
+ return actor->iface();
+}
+
+ActorPtr Actor::createActor(const char* name, s4u::Host* host, const char* function, std::vector<std::string> args)
+{
+ simgrid::simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(function);
+ simgrid::simix::ActorCode code = factory(std::move(args));
+ simgrid::simix::ActorImpl* actor = simcall_process_create(name, std::move(code), nullptr, host, nullptr);
+ return actor->iface();
+}
+
+void intrusive_ptr_add_ref(Actor* actor)
+{
+ intrusive_ptr_add_ref(actor->pimpl_);
+}
+void intrusive_ptr_release(Actor* actor)
+{
+ intrusive_ptr_release(actor->pimpl_);
+}
+
+// ***** Actor methods *****
+
+void Actor::join() {
+ simcall_process_join(this->pimpl_, -1);
+}
+
+void Actor::join(double timeout)
+{
+ simcall_process_join(this->pimpl_, timeout);
+}
+
+void Actor::setAutoRestart(bool autorestart) {
+ simgrid::simix::kernelImmediate([this, autorestart]() { pimpl_->auto_restart = autorestart; });
+}
+
+void Actor::onExit(int_f_pvoid_pvoid_t fun, void* data)
+{
+ simcall_process_on_exit(pimpl_, fun, data);
+}
+
+/** @brief Moves the actor to another host
+ *
+ * If the actor is currently blocked on an execution activity, the activity is also
+ * migrated to the new host. If it's blocked on another kind of activity, an error is
+ * raised as the mandated code is not written yet. Please report that bug if you need it.
+ *
+ * Asynchronous activities started by the actor are not migrated automatically, so you have
+ * to take care of this yourself (only you knows which ones should be migrated).
+ */
+void Actor::migrate(Host* new_host)
+{
+ simgrid::simix::kernelImmediate([this, new_host]() {
+ if (pimpl_->waiting_synchro != nullptr) {
+ // The actor is blocked on an activity. If it's an exec, migrate it too.
+ // FIXME: implement the migration of other kind of activities
+ simgrid::kernel::activity::ExecImplPtr exec =
+ boost::dynamic_pointer_cast<simgrid::kernel::activity::ExecImpl>(pimpl_->waiting_synchro);
+ xbt_assert(exec.get() != nullptr, "We can only migrate blocked actors when they are blocked on executions.");
+ exec->migrate(new_host);
+ }
+ SIMIX_process_change_host(this->pimpl_, new_host);
+ });
+}
+
+s4u::Host* Actor::getHost()
+{
+ return this->pimpl_->host;
+}
+
+void Actor::daemonize()