JavaContextFactory::~JavaContextFactory()=default;
-JavaContext* JavaContextFactory::create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup_fun,
- smx_actor_t actor)
+JavaContext* JavaContextFactory::create_context(std::function<void()> code, smx_actor_t actor)
{
- return this->new_context<JavaContext>(std::move(code), cleanup_fun, actor);
+ return this->new_context<JavaContext>(std::move(code), actor);
}
void JavaContextFactory::run_all()
SerialThreadContext::run_all();
}
-JavaContext::JavaContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process)
- : SerialThreadContext(std::move(code), cleanup_func, process, false /* not maestro */)
+JavaContext::JavaContext(std::function<void()> code, smx_actor_t actor)
+ : SerialThreadContext(std::move(code), actor, false /* not maestro */)
{
/* ThreadContext already does all we need */
}
JNIEnv* jenv_ = nullptr;
friend class JavaContextFactory;
- JavaContext(std::function<void()> code,
- void_pfn_smxprocess_t cleanup_func,
- smx_actor_t process);
+ JavaContext(std::function<void()> code, smx_actor_t actor);
void start_hook() override;
void stop_hook() override;
public:
JavaContextFactory();
~JavaContextFactory() override;
- JavaContext* create_context(std::function<void()> code,
- void_pfn_smxprocess_t, smx_actor_t process) override;
+ JavaContext* create_context(std::function<void()> code, smx_actor_t actor) override;
void run_all() override;
};
#include "src/internal_config.h" // HAVE_FUTEX_H
#include "src/kernel/context/Context.hpp"
+#include "src/simix/smx_private.hpp" /* simix_global */
#include <boost/optional.hpp>
#include <condition_variable>
ThreadData* data = static_cast<ThreadData*>(arg);
Parmap<T>& parmap = data->parmap;
unsigned round = 0;
- smx_context_t context = SIMIX_context_new(std::function<void()>(), nullptr, nullptr);
+ smx_context_t context = simix_global->context_factory->create_context(std::function<void()>(), nullptr);
kernel::context::Context::set_current(context);
XBT_CDEBUG(xbt_parmap, "New worker thread created");
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
-/**
- * @brief creates a new context for a user level process
- * @param code a main function
- * @param cleanup_func the function to call when the context stops
- * @param simix_process
- */
-smx_context_t SIMIX_context_new(
- std::function<void()> code,
- void_pfn_smxprocess_t cleanup_func,
- smx_actor_t simix_process)
-{
- return simix_global->context_factory->create_context(
- std::move(code), cleanup_func, simix_process);
-}
namespace simgrid {
namespace kernel {
#endif
}
-Context* ContextFactory::attach(void_pfn_smxprocess_t, smx_actor_t)
+Context* ContextFactory::attach(smx_actor_t)
{
xbt_die("Cannot attach with this ContextFactory.\n"
"Try using --cfg=contexts/factory:thread instead.\n");
"Try using --cfg=contexts/factory:thread instead.\n");
}
-Context::Context(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor)
- : code_(std::move(code)), cleanup_func_(cleanup_func), actor_(actor)
+Context::Context(std::function<void()> code, smx_actor_t actor) : code_(std::move(code)), actor_(actor)
{
/* If no function was provided, this is the context for maestro
* and we should set it as the current context */
XBT_DEBUG("%s@%s(%ld) should not run anymore", actor_->get_cname(), actor_->iface()->get_host()->get_cname(),
actor_->get_pid());
- if (this->cleanup_func_)
- this->cleanup_func_(this->actor_);
+ if (this->actor_ == simix_global->maestro_process) /* Do not cleanup maestro */
+ this->actor_->cleanup();
this->iwannadie = false; // don't let the simcall's yield() do a Context::stop(), because that's me
simgrid::simix::simcall([this] {
actor_->kill_timer = nullptr;
}
- SIMIX_process_cleanup(actor_);
+ actor_->cleanup();
});
this->iwannadie = true;
}
#include <csignal>
#include <functional>
-/* Process creation/destruction callbacks */
-typedef void (*void_pfn_smxprocess_t)(smx_actor_t);
-
namespace simgrid {
namespace kernel {
namespace context {
public:
explicit ContextFactory() {}
virtual ~ContextFactory();
- virtual Context* create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup, smx_actor_t process) = 0;
+ virtual Context* create_context(std::function<void()> code, smx_actor_t actor) = 0;
/** Turn the current thread into a simulation context */
- virtual Context* attach(void_pfn_smxprocess_t cleanup_func, smx_actor_t process);
+ virtual Context* attach(smx_actor_t actor);
/** Turn the current thread into maestro (the old maestro becomes a regular actor) */
- virtual Context* create_maestro(std::function<void()> code, smx_actor_t process);
+ virtual Context* create_maestro(std::function<void()> code, smx_actor_t actor);
virtual void run_all() = 0;
private:
std::function<void()> code_;
- void_pfn_smxprocess_t cleanup_func_ = nullptr;
smx_actor_t actor_ = nullptr;
void declare_context(std::size_t size);
public:
bool iwannadie = false;
- Context(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor);
+ Context(std::function<void()> code, smx_actor_t actor);
Context(const Context&) = delete;
Context& operator=(const Context&) = delete;
virtual ~Context();
void operator()() { code_(); }
bool has_code() const { return static_cast<bool>(code_); }
smx_actor_t get_actor() { return this->actor_; }
- void set_cleanup(void_pfn_smxprocess_t cleanup) { cleanup_func_ = cleanup; }
// Scheduling methods
virtual void stop();
class XBT_PUBLIC AttachContext : public Context {
public:
- AttachContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor)
- : Context(std::move(code), cleanup_func, actor)
- {
- }
+ AttachContext(std::function<void()> code, smx_actor_t actor) : Context(std::move(code), actor) {}
~AttachContext() override;
XBT_PRIVATE void SIMIX_context_mod_init();
XBT_PRIVATE void SIMIX_context_mod_exit();
-XBT_PUBLIC smx_context_t SIMIX_context_new(std::function<void()> code, void_pfn_smxprocess_t cleanup_func,
- smx_actor_t simix_process);
-
#ifndef WIN32
XBT_PUBLIC_DATA char sigsegv_stack[SIGSTKSZ];
#endif
namespace context {
// BoostContextFactory
-smx_context_t BoostContextFactory::create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup_func,
- smx_actor_t process)
+smx_context_t BoostContextFactory::create_context(std::function<void()> code, smx_actor_t actor)
{
- return this->new_context<BoostContext>(std::move(code), cleanup_func, process, this);
+ return this->new_context<BoostContext>(std::move(code), actor, this);
}
// BoostContext
-BoostContext::BoostContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor,
- SwappedContextFactory* factory)
- : SwappedContext(std::move(code), cleanup_func, actor, factory)
+BoostContext::BoostContext(std::function<void()> code, smx_actor_t actor, SwappedContextFactory* factory)
+ : SwappedContext(std::move(code), actor, factory)
{
/* if the user provided a function for the process then use it, otherwise it is the context for maestro */
/** @brief Userspace context switching implementation based on Boost.Context */
class BoostContext : public SwappedContext {
public:
- BoostContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor,
- SwappedContextFactory* factory);
+ BoostContext(std::function<void()> code, smx_actor_t actor, SwappedContextFactory* factory);
~BoostContext() override;
void swap_into(SwappedContext* to) override;
class BoostContextFactory : public SwappedContextFactory {
public:
- Context* create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup, smx_actor_t process) override;
+ Context* create_context(std::function<void()> code, smx_actor_t actor) override;
};
}}} // namespace
// RawContextFactory
-Context* RawContextFactory::create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup_func,
- smx_actor_t process)
+Context* RawContextFactory::create_context(std::function<void()> code, smx_actor_t actor)
{
- return this->new_context<RawContext>(std::move(code), cleanup_func, process, this);
+ return this->new_context<RawContext>(std::move(code), actor, this);
}
// RawContext
-RawContext::RawContext(std::function<void()> code, void_pfn_smxprocess_t cleanup, smx_actor_t actor,
- SwappedContextFactory* factory)
- : SwappedContext(std::move(code), cleanup, actor, factory)
+RawContext::RawContext(std::function<void()> code, smx_actor_t actor, SwappedContextFactory* factory)
+ : SwappedContext(std::move(code), actor, factory)
{
if (has_code()) {
this->stack_top_ = raw_makecontext(get_stack(), smx_context_usable_stack_size, RawContext::wrapper, this);
*/
class RawContext : public SwappedContext {
public:
- RawContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor,
- SwappedContextFactory* factory);
+ RawContext(std::function<void()> code, smx_actor_t actor, SwappedContextFactory* factory);
void swap_into(SwappedContext* to) override;
class RawContextFactory : public SwappedContextFactory {
public:
- Context* create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup, smx_actor_t process) override;
+ Context* create_context(std::function<void()> code, smx_actor_t actor) override;
};
}}} // namespace
delete parmap_;
}
-SwappedContext::SwappedContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t process,
- SwappedContextFactory* factory)
- : Context(std::move(code), cleanup_func, process), factory_(factory)
+SwappedContext::SwappedContext(std::function<void()> code, smx_actor_t actor, SwappedContextFactory* factory)
+ : Context(std::move(code), actor), factory_(factory)
{
// Save maestro (=context created first) in preparation for run_all
if (not factory->parallel_ && factory_->workers_context_[0] == nullptr)
class SwappedContext : public Context {
public:
- SwappedContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t get_actor,
- SwappedContextFactory* factory);
+ SwappedContext(std::function<void()> code, smx_actor_t get_actor, SwappedContextFactory* factory);
virtual ~SwappedContext();
void suspend() override;
ParallelThreadContext::finalize();
}
-ThreadContext* ThreadContextFactory::create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup,
- smx_actor_t actor, bool maestro)
+ThreadContext* ThreadContextFactory::create_context(std::function<void()> code, smx_actor_t actor, bool maestro)
{
if (parallel_)
- return this->new_context<ParallelThreadContext>(std::move(code), cleanup, actor, maestro);
+ return this->new_context<ParallelThreadContext>(std::move(code), actor, maestro);
else
- return this->new_context<SerialThreadContext>(std::move(code), cleanup, actor, maestro);
+ return this->new_context<SerialThreadContext>(std::move(code), actor, maestro);
}
void ThreadContextFactory::run_all()
// ThreadContext
-ThreadContext::ThreadContext(std::function<void()> code, void_pfn_smxprocess_t cleanup, smx_actor_t actor, bool maestro)
- : AttachContext(std::move(code), cleanup, actor), is_maestro_(maestro)
+ThreadContext::ThreadContext(std::function<void()> code, smx_actor_t actor, bool maestro)
+ : AttachContext(std::move(code), actor), is_maestro_(maestro)
{
/* If the user provided a function for the actor then use it */
if (has_code()) {
class XBT_PUBLIC ThreadContext : public AttachContext {
public:
- ThreadContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor, bool maestro);
+ ThreadContext(std::function<void()> code, smx_actor_t actor, bool maestro);
~ThreadContext() override;
void stop() override;
void suspend() override;
class XBT_PUBLIC SerialThreadContext : public ThreadContext {
public:
- SerialThreadContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor, bool maestro)
- : ThreadContext(std::move(code), cleanup_func, actor, maestro)
+ SerialThreadContext(std::function<void()> code, smx_actor_t actor, bool maestro)
+ : ThreadContext(std::move(code), actor, maestro)
{
}
class ParallelThreadContext : public ThreadContext {
public:
- ParallelThreadContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor, bool maestro)
- : ThreadContext(std::move(code), cleanup_func, actor, maestro)
+ ParallelThreadContext(std::function<void()> code, smx_actor_t actor, bool maestro)
+ : ThreadContext(std::move(code), actor, maestro)
{
}
public:
ThreadContextFactory();
~ThreadContextFactory() override;
- ThreadContext* create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup_func,
- smx_actor_t actor) override
+ ThreadContext* create_context(std::function<void()> code, smx_actor_t actor) override
{
bool maestro = not code;
- return create_context(std::move(code), cleanup_func, actor, maestro);
+ return create_context(std::move(code), actor, maestro);
}
void run_all() override;
// Optional methods:
- ThreadContext* attach(void_pfn_smxprocess_t cleanup_func, smx_actor_t actor) override
- {
- return create_context(std::function<void()>(), cleanup_func, actor, false);
- }
+ ThreadContext* attach(smx_actor_t actor) override { return create_context(std::function<void()>(), actor, false); }
ThreadContext* create_maestro(std::function<void()> code, smx_actor_t actor) override
{
- return create_context(std::move(code), nullptr, actor, true);
+ return create_context(std::move(code), actor, true);
}
private:
bool parallel_;
- ThreadContext* create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor,
- bool maestro);
+ ThreadContext* create_context(std::function<void()> code, smx_actor_t actor, bool maestro);
};
}}} // namespace
namespace context {
// UContextFactory
-Context* UContextFactory::create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup, smx_actor_t actor)
+Context* UContextFactory::create_context(std::function<void()> code, smx_actor_t actor)
{
- return new_context<UContext>(std::move(code), cleanup, actor, this);
+ return new_context<UContext>(std::move(code), actor, this);
}
// UContext
-UContext::UContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor,
- SwappedContextFactory* factory)
- : SwappedContext(std::move(code), cleanup_func, actor, factory)
+UContext::UContext(std::function<void()> code, smx_actor_t actor, SwappedContextFactory* factory)
+ : SwappedContext(std::move(code), actor, factory)
{
/* if the user provided a function for the actor then use it. If not, nothing to do for maestro. */
if (has_code()) {
class UContext : public SwappedContext {
public:
- UContext(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t actor,
- SwappedContextFactory* factory);
+ UContext(std::function<void()> code, smx_actor_t actor, SwappedContextFactory* factory);
void swap_into(SwappedContext* to) override;
class UContextFactory : public SwappedContextFactory {
public:
- Context* create_context(std::function<void()> code, void_pfn_smxprocess_t cleanup, smx_actor_t actor) override;
+ Context* create_context(std::function<void()> code, smx_actor_t actor) override;
};
}}} // namespace
return process->comms.size() > 0;
}
-/**
- * @brief Moves a process to the list of processes to destroy.
- */
-void SIMIX_process_cleanup(smx_actor_t process)
-{
- XBT_DEBUG("Cleanup process %s (%p), waiting synchro %p", process->get_cname(), process,
- process->waiting_synchro.get());
-
- simix_global->mutex.lock();
-
- simix_global->process_list.erase(process->get_pid());
- if (process->get_host() && process->host_process_list_hook.is_linked())
- simgrid::xbt::intrusive_erase(process->get_host()->pimpl_->process_list_, *process);
- if (not process->smx_destroy_list_hook.is_linked()) {
-#if SIMGRID_HAVE_MC
- xbt_dynar_push_as(simix_global->dead_actors_vector, smx_actor_t, process);
-#endif
- simix_global->actors_to_destroy.push_back(*process);
- }
- process->context_->iwannadie = false;
-
- simix_global->mutex.unlock();
-}
-
namespace simgrid {
namespace kernel {
namespace actor {
delete this->context_;
}
+void ActorImpl::cleanup()
+{
+ XBT_DEBUG("Cleanup actor %s (%p), waiting synchro %p", get_cname(), this, waiting_synchro.get());
+
+ simix_global->mutex.lock();
+
+ simix_global->process_list.erase(pid_);
+ if (host_ && host_process_list_hook.is_linked())
+ simgrid::xbt::intrusive_erase(host_->pimpl_->process_list_, *this);
+ if (not smx_destroy_list_hook.is_linked()) {
+#if SIMGRID_HAVE_MC
+ xbt_dynar_push_as(simix_global->dead_actors_vector, smx_actor_t, this);
+#endif
+ simix_global->actors_to_destroy.push_back(*this);
+ }
+ context_->iwannadie = false;
+
+ simix_global->mutex.unlock();
+}
+
void ActorImpl::exit()
{
context_->iwannadie = true;
actor->set_ppid(parent_actor->get_pid());
XBT_VERB("Create context %s", actor->get_cname());
- actor->context_ = SIMIX_context_new(std::move(code), &SIMIX_process_cleanup, actor);
+ actor->context_ = simix_global->context_factory->create_context(std::move(code), actor);
/* Add properties */
if (properties != nullptr)
ActorImpl* maestro = new ActorImpl(xbt::string(""), /*host*/ nullptr);
if (not code) {
- maestro->context_ = SIMIX_context_new(simix::ActorCode(), nullptr, maestro);
+ maestro->context_ = simix_global->context_factory->create_context(simix::ActorCode(), maestro);
} else {
maestro->context_ = simix_global->context_factory->create_maestro(code, maestro);
}
XBT_VERB("Create context %s", actor->get_cname());
xbt_assert(simix_global != nullptr, "simix is not initialized, please call MSG_init first");
- actor->context_ = simix_global->context_factory->attach(&SIMIX_process_cleanup, actor);
+ actor->context_ = simix_global->context_factory->attach(actor);
/* Add properties */
if (properties != nullptr)
if (context == nullptr)
xbt_die("Not a suitable context");
- SIMIX_process_cleanup(context->get_actor());
+ context->get_actor()->cleanup();
context->attach_stop();
}
static ActorImplPtr create(std::string name, simix::ActorCode code, void* data, s4u::Host* host,
std::unordered_map<std::string, std::string>* properties, ActorImpl* parent_actor);
+ void cleanup();
void exit();
void kill(ActorImpl* actor);
void kill_all();
} // namespace kernel
} // namespace simgrid
-XBT_PRIVATE void SIMIX_process_cleanup(smx_actor_t arg);
-
extern void (*SMPI_switch_data_segment)(simgrid::s4u::ActorPtr actor);
XBT_PRIVATE void SIMIX_process_sleep_destroy(smx_activity_t synchro);
}
simgrid::s4u::ActorPtr proc = simgrid::s4u::Actor::self();
- proc->get_impl()->context_->set_cleanup(&SIMIX_process_cleanup);
// cheinrich: I'm not sure what the impact of the SMPI_switch_data_segment on this call is. I moved
// this up here so that I can set the privatized region before the switch.
ActorExt* process = smpi_process_remote(proc);