#include <utility>
#include <memory>
+#include <functional>
#include <xbt/function_types.h>
#include <simgrid/simix.h>
ContextFactory(std::string name) : name_(std::move(name)) {}
virtual ~ContextFactory();
- virtual Context* create_context(
- xbt_main_func_t, int, char **, void_pfn_smxprocess_t,
- smx_process_t process
- ) = 0;
+ virtual Context* create_context(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup, smx_process_t process) = 0;
virtual void run_all() = 0;
virtual Context* self();
std::string const& name() const
};
class Context {
-protected:
- xbt_main_func_t code_ = nullptr;
- int argc_ = 0;
- char **argv_ = nullptr;
private:
+ std::function<void()> code_;
void_pfn_smxprocess_t cleanup_func_ = nullptr;
smx_process_t process_ = nullptr;
public:
bool iwannadie;
public:
- Context(xbt_main_func_t code,
- int argc, char **argv,
+ Context(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process);
- int operator()()
+ void operator()()
+ {
+ code_();
+ }
+ bool has_code() const
{
- return code_(argc_, argv_);
+ return (bool) code_;
}
smx_process_t process()
{
}
JavaContext* JavaContextFactory::create_context(
- xbt_main_func_t code, int argc, char ** argv,
+ std::function<void()> code,
void_pfn_smxprocess_t cleanup, smx_process_t process)
{
- return this->new_context<JavaContext>(code, argc, argv, cleanup, process);
+ return this->new_context<JavaContext>(std::move(code), cleanup, process);
}
void JavaContextFactory::run_all()
}
-JavaContext::JavaContext(xbt_main_func_t code,
- int argc, char **argv,
+JavaContext::JavaContext(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process)
- : Context(code, argc, argv, cleanup_func, process)
+ : Context(std::move(code), cleanup_func, process)
{
static int thread_amount=0;
thread_amount++;
/* If the user provided a function for the process then use it
otherwise is the context for maestro */
- if (code) {
+ if (has_code()) {
this->jprocess = nullptr;
this->begin = xbt_os_sem_init(0);
this->end = xbt_os_sem_init(0);
xbt_os_sem_t end = nullptr;
public:
friend class JavaContextFactory;
- JavaContext(xbt_main_func_t code,
- int argc, char **argv,
+ JavaContext(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process);
~JavaContext() override;
JavaContextFactory();
~JavaContextFactory() override;
JavaContext* self() override;
- JavaContext* create_context(
- xbt_main_func_t, int, char **, void_pfn_smxprocess_t,
- smx_process_t process
- ) override;
+ JavaContext* create_context(std::function<void()> code,
+ void_pfn_smxprocess_t, smx_process_t process) override;
void run_all() override;
};
xbt_main_func_t code, void *data,
msg_host_t host)
{
- return MSG_process_create_with_environment(name, code, data, host, -1,
+ return MSG_process_create_with_environment(name, code, data, host, 0,
NULL, NULL);
}
class BoostSerialContext : public BoostContext {
public:
- BoostSerialContext(xbt_main_func_t code,
- int argc, char **argv,
+ BoostSerialContext(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process)
- : BoostContext(code, argc, argv, cleanup_func, process) {}
+ : BoostContext(std::move(code), cleanup_func, process) {}
void stop() override;
void suspend() override;
void resume();
#ifdef CONTEXT_THREADS
class BoostParallelContext : public BoostContext {
public:
- BoostParallelContext(xbt_main_func_t code,
- int argc, char **argv,
+ BoostParallelContext(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process)
- : BoostContext(code, argc, argv, cleanup_func, process) {}
+ : BoostContext(std::move(code), cleanup_func, process) {}
void stop() override;
void suspend() override;
void resume();
#endif
}
-smx_context_t BoostContextFactory::create_context(
- xbt_main_func_t code, int argc, char ** argv,
+smx_context_t BoostContextFactory::create_context(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func, smx_process_t process)
{
BoostContext* context = nullptr;
if (BoostContext::parallel_)
#ifdef CONTEXT_THREADS
context = this->new_context<BoostParallelContext>(
- code, argc, argv, cleanup_func, process);
+ std::move(code), cleanup_func, process);
#else
xbt_die("No support for parallel execution");
#endif
else
context = this->new_context<BoostSerialContext>(
- code, argc, argv, cleanup_func, process);
+ std::move(code), cleanup_func, process);
return context;
}
context->stop();
}
-BoostContext::BoostContext(xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup_func,
- smx_process_t process)
- : Context(code, argc, argv, cleanup_func, process)
+BoostContext::BoostContext(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup_func, smx_process_t process)
+ : Context(std::move(code), cleanup_func, process)
{
/* if the user provided a function for the process then use it,
otherwise it is the context for maestro */
- if (code) {
+ if (has_code()) {
this->stack_ = SIMIX_context_stack_new();
// We need to pass the bottom of the stack to make_fcontext,
// depending on the stack direction it may be the lower or higher address:
void* stack_ = nullptr;
public:
friend BoostContextFactory;
- BoostContext(xbt_main_func_t code,
- int argc, char **argv,
+ BoostContext(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process);
~BoostContext();
BoostContextFactory();
virtual ~BoostContextFactory();
- virtual Context* create_context(
- xbt_main_func_t, int, char **, void_pfn_smxprocess_t,
- smx_process_t process
- ) override;
+ virtual Context* create_context(std::function<void()> code,
+ void_pfn_smxprocess_t, smx_process_t process) override;
void run_all() override;
};
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
+#include <vector>
+#include <string>
+#include <cstring>
+#include <memory>
+
#include <simgrid/simix.hpp>
#include "mc/mc.h"
namespace simgrid {
namespace simix {
+class XBT_PRIVATE args {
+private:
+ int argc_;
+ char** argv_;
+public:
+
+ // Main constructors
+ args() : argc_(0), argv_(nullptr) {}
+ args(int argc, char** argv) : argc_(argc), argv_(argv) {}
+
+ // Free
+ void clear()
+ {
+ for (int i = 0; i < this->argc_; i++)
+ free(this->argv_[i]);
+ free(this->argv_);
+ this->argc_ = 0;
+ this->argv_ = nullptr;
+ }
+ ~args() { clear(); }
+
+ // Copy
+ args(args const& that) = delete;
+ args& operator=(args const& that) = delete;
+
+ // Move:
+ args(args&& that) : argc_(that.argc_), argv_(that.argv_)
+ {
+ that.argc_ = 0;
+ that.argv_ = nullptr;
+ }
+ args& operator=(args&& that)
+ {
+ this->argc_ = that.argc_;
+ this->argv_ = that.argv_;
+ that.argc_ = 0;
+ that.argv_ = nullptr;
+ return *this;
+ }
+
+ int argc() const { return argc_; }
+ char** argv() { return argv_; }
+ const char*const* argv() const { return argv_; }
+ char* operator[](std::size_t i) { return argv_[i]; }
+};
+
+}
+}
+
+static
+std::function<void()> wrap_main(xbt_main_func_t code, int argc, char **argv)
+{
+ if (code) {
+ auto arg = std::make_shared<simgrid::simix::args>(argc, argv);
+ return [=]() {
+ code(arg->argc(), arg->argv());
+ };
+ } else return std::function<void()>();
+}
+
+/**
+ * \brief creates a new context for a user level process
+ * \param code a main function
+ * \param argc the number of arguments of the main function
+ * \param argv the vector of arguments of the main function
+ * \param cleanup_func the function to call when the context stops
+ * \param cleanup_arg the argument of the cleanup_func function
+ */
+smx_context_t SIMIX_context_new(
+ xbt_main_func_t code, int argc, char **argv,
+ void_pfn_smxprocess_t cleanup_func,
+ smx_process_t simix_process)
+{
+ if (!simix_global)
+ xbt_die("simix is not initialized, please call MSG_init first");
+ return simix_global->context_factory->create_context(
+ wrap_main(code, argc, argv), cleanup_func, simix_process);
+}
+
+namespace simgrid {
+namespace simix {
+
ContextFactoryInitializer factory_initializer = nullptr;
ContextFactory::~ContextFactory() {}
#endif
}
-Context::Context(xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup_func,
- smx_process_t process)
- : process_(process), iwannadie(false)
+Context::Context(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup_func, smx_process_t process)
+ : code_(std::move(code)), process_(process), iwannadie(false)
{
/* If the user provided a function for the process then use it.
Otherwise, it is the context for maestro and we should set it as the
current context */
- if (code) {
+ if (has_code())
this->cleanup_func_ = cleanup_func;
- this->argc_ = argc;
- this->argv_ = argv;
- this->code_ = code;
- } else {
+ else
SIMIX_context_set_current(this);
- }
}
Context::~Context()
{
- if (this->argv_) {
- for (int i = 0; i < this->argc_; i++)
- free(this->argv_[i]);
- free(this->argv_);
- }
}
void Context::stop()
void* stack_top_ = nullptr;
public:
friend class RawContextFactory;
- RawContext(xbt_main_func_t code,
- int argc, char **argv,
+ RawContext(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process);
~RawContext();
public:
RawContextFactory();
~RawContextFactory();
- RawContext* create_context(
- xbt_main_func_t, int, char **, void_pfn_smxprocess_t,
- smx_process_t process
- ) override;
+ RawContext* create_context(std::function<void()> code,
+ void_pfn_smxprocess_t, smx_process_t process) override;
void run_all() override;
private:
void run_all_adaptative();
#endif
}
-RawContext* RawContextFactory::create_context(
- xbt_main_func_t code, int argc, char ** argv,
- void_pfn_smxprocess_t cleanup,
- smx_process_t process)
+RawContext* RawContextFactory::create_context(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup, smx_process_t process)
{
- return this->new_context<RawContext>(code, argc, argv,
+ return this->new_context<RawContext>(std::move(code),
cleanup, process);
}
context->stop();
}
-RawContext::RawContext(
- xbt_main_func_t code, int argc, char ** argv,
- void_pfn_smxprocess_t cleanup,
- smx_process_t process)
- : Context(code, argc, argv, cleanup, process)
+RawContext::RawContext(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup, smx_process_t process)
+ : Context(std::move(code), cleanup, process)
{
- if (code) {
+ if (has_code()) {
this->stack_ = SIMIX_context_stack_new();
this->stack_top_ = raw_makecontext(this->stack_,
smx_context_usable_stack_size,
}
ThreadContext* ThreadContextFactory::create_context(
- xbt_main_func_t code, int argc, char ** argv,
- void_pfn_smxprocess_t cleanup,
- smx_process_t process)
+ std::function<void()> code,
+ void_pfn_smxprocess_t cleanup, smx_process_t process)
{
- return this->new_context<ThreadContext>(code, argc, argv, cleanup, process);
+ return this->new_context<ThreadContext>(std::move(code), cleanup, process);
}
-ThreadContext::ThreadContext(xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup,
- smx_process_t process)
- : Context(code, argc, argv, cleanup, process)
+ThreadContext::ThreadContext(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup, smx_process_t process)
+ : Context(std::move(code), cleanup, process)
{
/* If the user provided a function for the process then use it
otherwise is the context for maestro */
- if (code) {
+ if (has_code()) {
this->begin_ = xbt_os_sem_init(0);
this->end_ = xbt_os_sem_init(0);
if (smx_context_stack_size_was_set)
class ThreadContext : public Context {
public:
friend ThreadContextFactory;
- ThreadContext(xbt_main_func_t code,
- int argc, char **argv,
+ ThreadContext(std::function<void()> code,
void_pfn_smxprocess_t cleanup_func,
smx_process_t process);
~ThreadContext();
public:
ThreadContextFactory();
~ThreadContextFactory();
- virtual ThreadContext* create_context(
- xbt_main_func_t, int, char **, void_pfn_smxprocess_t,
- smx_process_t process
- ) override;
+ virtual ThreadContext* create_context(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup_func, smx_process_t process) override;
void run_all() override;
ThreadContext* self() override;
};
char *stack_ = nullptr; /* the thread stack */
public:
friend UContextFactory;
- UContext(xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup_func,
- smx_process_t process);
+ UContext(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup_func, smx_process_t process);
~UContext();
protected:
static void wrapper(int first, ...);
class SerialUContext : public UContext {
public:
- SerialUContext(xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup_func,
- smx_process_t process)
- : UContext(code, argc, argv, cleanup_func, process)
+ SerialUContext(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup_func, smx_process_t process)
+ : UContext(std::move(code), cleanup_func, process)
{}
void stop() override;
void suspend() override;
class ParallelUContext : public UContext {
public:
- ParallelUContext(xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup_func,
- smx_process_t process)
- : UContext(code, argc, argv, cleanup_func, process)
+ ParallelUContext(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup_func, smx_process_t process)
+ : UContext(std::move(code), cleanup_func, process)
{}
void stop() override;
void suspend() override;
UContextFactory();
virtual ~UContextFactory();
- virtual Context* create_context(
- xbt_main_func_t, int, char **, void_pfn_smxprocess_t,
- smx_process_t process
- ) override;
+ virtual Context* create_context(std::function<void()> code,
+ void_pfn_smxprocess_t, smx_process_t process) override;
void run_all() override;
};
}
}
-Context* UContextFactory::create_context(
- xbt_main_func_t code, int argc, char ** argv,
- void_pfn_smxprocess_t cleanup,
- smx_process_t process
- )
+Context* UContextFactory::create_context(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup, smx_process_t process)
{
if (sysv_parallel)
- return new_context<ParallelUContext>(code, argc, argv, cleanup, process);
+ return new_context<ParallelUContext>(std::move(code), cleanup, process);
else
- return new_context<SerialUContext>(code, argc, argv, cleanup, process);
+ return new_context<SerialUContext>(std::move(code), cleanup, process);
}
-UContext::UContext(xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup_func,
- smx_process_t process)
- : Context(code, argc, argv, cleanup_func, process)
+UContext::UContext(std::function<void()> code,
+ void_pfn_smxprocess_t cleanup_func, smx_process_t process)
+ : Context(std::move(code), cleanup_func, process)
{
/* if the user provided a function for the process then use it,
otherwise it is the context for maestro */
- if (code) {
+ if (has_code()) {
this->stack_ = (char*) SIMIX_context_stack_new();
getcontext(&this->uc_);
this->uc_.uc_link = nullptr;
XBT_PRIVATE void SIMIX_context_mod_init(void);
XBT_PRIVATE void SIMIX_context_mod_exit(void);
+smx_context_t SIMIX_context_new(
+ xbt_main_func_t code, int argc, char **argv,
+ void_pfn_smxprocess_t cleanup_func,
+ smx_process_t simix_process);
+
#ifndef WIN32
XBT_PUBLIC_DATA(char sigsegv_stack[SIGSTKSZ]);
#endif
#include <simgrid/simix.hpp>
#include "smx_private.h"
-/**
- * \brief creates a new context for a user level process
- * \param code a main function
- * \param argc the number of arguments of the main function
- * \param argv the vector of arguments of the main function
- * \param cleanup_func the function to call when the context stops
- * \param cleanup_arg the argument of the cleanup_func function
- */
-static inline smx_context_t SIMIX_context_new(xbt_main_func_t code,
- int argc, char **argv,
- void_pfn_smxprocess_t cleanup_func,
- smx_process_t simix_process)
-{
- if (!simix_global)
- xbt_die("simix is not initialized, please call MSG_init first");
- return simix_global->context_factory->create_context(
- code, argc, argv, cleanup_func, simix_process);
-}
-
/**
* \brief destroy a context
* \param context the context to destroy