context->attach_stop();
}
+/** Whether this actor is actually maestro */
+bool ActorImpl::is_maestro() const
+{
+ return context_->is_maestro();
+}
+
void ActorImpl::cleanup_from_simix()
{
auto* engine = EngineImpl::get_instance();
aid_t get_ppid() const { return ppid_; }
void set_ppid(aid_t ppid) { ppid_ = ppid; }
bool is_daemon() const { return daemon_; } /** Whether this actor has been daemonized */
+ bool is_maestro() const; /** Whether this actor is actually maestro (rather cheap call) */
bool has_to_auto_restart() const { return auto_restart_; }
void set_auto_restart(bool autorestart) { auto_restart_ = autorestart; }
void set_stacksize(unsigned stacksize) { stacksize_ = stacksize; }
"Try using --cfg=contexts/factory:thread instead.\n");
}
-Context::Context(std::function<void()>&& code, actor::ActorImpl* actor) : code_(std::move(code)), actor_(actor)
+Context::Context(std::function<void()>&& code, actor::ActorImpl* actor, bool maestro)
+ : code_(std::move(code)), actor_(actor), is_maestro_(maestro)
{
- /* If no function was provided, this is the context for maestro
- * and we should set it as the current context */
- if (not has_code())
+ /* If we are creating maestro, we should set it as the current context */
+ if (maestro)
set_current(this);
}
std::function<void()> code_;
actor::ActorImpl* actor_ = nullptr;
bool iwannadie_ = false;
+ bool is_maestro_;
void declare_context(std::size_t size);
public:
static int install_sigsegv_stack(stack_t* old_stack, bool enable);
#endif
- Context(std::function<void()>&& code, actor::ActorImpl* actor);
+ Context(std::function<void()>&& code, actor::ActorImpl* actor, bool maestro);
Context(const Context&) = delete;
Context& operator=(const Context&) = delete;
virtual ~Context();
bool wannadie() const { return iwannadie_; }
void set_wannadie(bool value = true) { iwannadie_ = value; }
+ bool is_maestro() const { return is_maestro_; }
void operator()() const { code_(); }
bool has_code() const { return static_cast<bool>(code_); }
actor::ActorImpl* get_actor() const { return this->actor_; }
class XBT_PUBLIC AttachContext : public Context {
public:
- AttachContext(std::function<void()>&& code, actor::ActorImpl* actor) : Context(std::move(code), actor) {}
+ AttachContext(std::function<void()>&& code, actor::ActorImpl* actor, bool maestro)
+ : Context(std::move(code), actor, maestro)
+ {
+ }
AttachContext(const AttachContext&) = delete;
AttachContext& operator=(const AttachContext&) = delete;
~AttachContext() override;
- /** Called by the context when it is ready to give control
- * to the maestro.
- */
+ /** Called by the context when it is ready to give control to the maestro */
virtual void attach_start() = 0;
/** Called by the context when it has finished its job */
thread_local SwappedContext* SwappedContext::worker_context_ = nullptr;
SwappedContext::SwappedContext(std::function<void()>&& code, smx_actor_t actor, SwappedContextFactory* factory)
- : Context(std::move(code), actor), factory_(*factory)
+ : Context(std::move(code), actor, not code /* maestro if no code */), factory_(*factory)
{
// Save maestro (=first created context) in preparation for run_all
if (not is_parallel() && factory_.maestro_context_ == nullptr)
// ThreadContext
ThreadContext::ThreadContext(std::function<void()>&& code, actor::ActorImpl* actor, bool maestro)
- : AttachContext(std::move(code), actor), is_maestro_(maestro)
+ : AttachContext(std::move(code), actor, maestro)
{
/* If the user provided a function for the actor then use it */
if (has_code()) {
void attach_start() override;
void attach_stop() override;
- bool is_maestro() const { return is_maestro_; }
void release(); // unblock context's start()
void wait(); // wait for context's yield()
xbt::OsSemaphore begin_{0};
/** Semaphore used to schedule/unschedule (not needed when the maestro is in main, but harmless then) */
xbt::OsSemaphore end_{0};
- bool is_maestro_;
void start(); // match a call to release()
void yield(); // match a call to yield()