#ifdef __cplusplus
#include <boost/intrusive_ptr.hpp>
+#include <vector>
namespace simgrid {
namespace actor {
class ActorImpl;
typedef boost::intrusive_ptr<ActorImpl> ActorImplPtr;
+
+// What's executed as an actor code:
+typedef std::function<void()> ActorCode;
+// Create an ActorCode from the parameters parsed in the XML file (or elsewhere)
+typedef std::function<ActorCode(std::vector<std::string> args)> ActorCodeFactory;
} // namespace actor
namespace activity {
* This is a singleton containing all the main functions of the simulation.
*/
class XBT_PUBLIC Engine {
+ friend simgrid::kernel::EngineImpl;
+
public:
/** Constructor, taking the command line parameters of your main function */
explicit Engine(int* argc, char** argv);
XBT_ATTRIB_DEPRECATED_v330("Please change the return code of your actors to void") void register_default(
int (*code)(int, char**));
void register_default(void (*code)(int, char**));
+ void register_default(kernel::actor::ActorCodeFactory factory);
+ void register_function(const std::string& name, kernel::actor::ActorCodeFactory factory);
template <class F> void register_actor(const std::string& name)
{
- simix::register_function(name, [](std::vector<std::string> args) {
- return simix::ActorCode([args] {
+ register_function(name, [](std::vector<std::string> args) {
+ return kernel::actor::ActorCode([args] {
F code(std::move(args));
code();
});
});
}
-
template <class F> void register_actor(const std::string& name, F code)
{
- simix::register_function(name, [code](std::vector<std::string> args) {
- return simix::ActorCode([code, args] { code(std::move(args)); });
+ register_function(name, [code](std::vector<std::string> args) {
+ return kernel::actor::ActorCode([code, args] { code(std::move(args)); });
});
}
namespace simgrid {
namespace simix {
-// What's executed as SIMIX actor code:
-typedef std::function<void()> ActorCode;
-
-// Create an ActorCode based on a std::string
-typedef std::function<ActorCode(std::vector<std::string> args)> ActorCodeFactory;
-
-XBT_PUBLIC void register_function(const std::string& name, const ActorCodeFactory& factory);
typedef std::pair<double, Timer*> TimerQelt;
static boost::heap::fibonacci_heap<TimerQelt, boost::heap::compare<xbt::HeapComparator<TimerQelt>>> simix_timers;
} // namespace simix
} // namespace simgrid
-XBT_PUBLIC smx_actor_t simcall_process_create(const std::string& name, const simgrid::simix::ActorCode& code,
- void* data, sg_host_t host,
- std::unordered_map<std::string, std::string>* properties);
-
#endif
jobject jprocess = jprocess_ref(jprocess_arg, env);
/* Actually build the MSG process */
- jstring jname = (jstring)env->GetObjectField(jprocess, jprocess_field_Process_name);
- const char* name = env->GetStringUTFChars(jname, 0);
- simgrid::simix::ActorCode function = [jprocess]() { simgrid::kernel::context::java_main_jprocess(jprocess); };
- smx_actor_t self = SIMIX_process_self();
- sg_host_t host = jhost_get_native(env, jhost);
- smx_actor_t actor = simgrid::kernel::actor::simcall([name, function, host, self] {
- return simgrid::kernel::actor::ActorImpl::create(std::move(name), std::move(function), nullptr, host, nullptr, self)
+ jstring jname = (jstring)env->GetObjectField(jprocess, jprocess_field_Process_name);
+ const char* name = env->GetStringUTFChars(jname, 0);
+ auto actor_code = [jprocess]() { simgrid::kernel::context::java_main_jprocess(jprocess); };
+ smx_actor_t self = SIMIX_process_self();
+ sg_host_t host = jhost_get_native(env, jhost);
+ smx_actor_t actor = simgrid::kernel::actor::simcall([name, actor_code, host, self] {
+ return simgrid::kernel::actor::ActorImpl::create(std::move(name), std::move(actor_code), nullptr, host, nullptr,
+ self)
.get();
});
MSG_process_yield();
surf_parse();
surf_parse_close();
}
-void EngineImpl::register_function(const std::string& name, int (*code)(int, char**)) // deprecated
-{
- simix_global->registered_functions[name] = [code](std::vector<std::string> args) {
- return xbt::wrap_main(code, std::move(args));
- };
-}
-void EngineImpl::register_function(const std::string& name, xbt_main_func_t code)
-{
- simix_global->registered_functions[name] = [code](std::vector<std::string> args) {
- return xbt::wrap_main(code, std::move(args));
- };
-}
-
-void EngineImpl::register_function(const std::string& name, void (*code)(std::vector<std::string>))
-{
- simix_global->registered_functions[name] = [code](std::vector<std::string> args) {
- return std::bind(std::move(code), std::move(args));
- };
-}
-void EngineImpl::register_default(int (*code)(int, char**)) // deprecated
+void EngineImpl::register_function(const std::string& name, actor::ActorCodeFactory code)
{
- simix_global->default_function = [code](std::vector<std::string> args) {
- return xbt::wrap_main(code, std::move(args));
- };
+ registered_functions[name] = code;
}
-void EngineImpl::register_default(xbt_main_func_t code)
+void EngineImpl::register_default(actor::ActorCodeFactory code)
{
- simix_global->default_function = [code](std::vector<std::string> args) {
- return xbt::wrap_main(code, std::move(args));
- };
+ default_function = code;
}
} // namespace kernel
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <map>
+#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/NetZone.hpp>
#include <simgrid/simix.hpp>
#include <string>
std::map<std::string, resource::LinkImpl*> links_;
std::map<std::string, resource::StorageImpl*> storages_;
std::unordered_map<std::string, routing::NetPoint*> netpoints_;
+ std::unordered_map<std::string, actor::ActorCodeFactory> registered_functions; // Maps function names to actor code
+ actor::ActorCodeFactory default_function; // Function to use as a fallback when the provided name matches nothing
+
friend s4u::Engine;
public:
virtual ~EngineImpl();
void load_deployment(const std::string& file);
- void register_function(const std::string& name, int (*code)(int, char**)); // deprecated
- void register_function(const std::string& name, xbt_main_func_t code);
- void register_function(const std::string& name, void (*code)(std::vector<std::string>));
- void register_default(int (*code)(int, char**)); // deprecated
- void register_default(xbt_main_func_t code);
+ void register_function(const std::string& name, actor::ActorCodeFactory code);
+ void register_default(actor::ActorCodeFactory code);
routing::NetZoneImpl* netzone_root_ = nullptr;
+ static EngineImpl* get_instance() { return simgrid::s4u::Engine::get_instance()->pimpl; }
+ actor::ActorCodeFactory get_function(const std::string& name)
+ {
+ auto res = registered_functions.find(name);
+ if (res == registered_functions.end())
+ return default_function;
+ else
+ return res->second;
+ }
};
} // namespace kernel
return ActorImplPtr(actor);
}
-ActorImpl* ActorImpl::start(const simix::ActorCode& code)
+ActorImpl* ActorImpl::start(const ActorCode& code)
{
xbt_assert(code && host_ != nullptr, "Invalid parameters");
this->code_ = code;
XBT_VERB("Create context %s", get_cname());
- context_.reset(simix_global->context_factory->create_context(simix::ActorCode(code), this));
+ context_.reset(simix_global->context_factory->create_context(ActorCode(code), this));
XBT_DEBUG("Start context '%s'", get_cname());
return this;
}
-ActorImplPtr ActorImpl::create(const std::string& name, const simix::ActorCode& code, void* data, s4u::Host* host,
+ActorImplPtr ActorImpl::create(const std::string& name, const ActorCode& code, void* data, s4u::Host* host,
const std::unordered_map<std::string, std::string>* properties, ActorImpl* parent_actor)
{
XBT_DEBUG("Start actor %s@'%s'", name.c_str(), host->get_cname());
ActorImpl* maestro = new ActorImpl(xbt::string(""), /*host*/ nullptr);
if (not code) {
- maestro->context_.reset(simix_global->context_factory->create_context(simix::ActorCode(), maestro));
+ maestro->context_.reset(simix_global->context_factory->create_context(ActorCode(), maestro));
} else {
- maestro->context_.reset(simix_global->context_factory->create_maestro(simix::ActorCode(code), maestro));
+ maestro->context_.reset(simix_global->context_factory->create_maestro(ActorCode(code), maestro));
}
maestro->simcall.issuer_ = maestro;
* @param host where the new agent is executed.
* @param properties the properties of the process
*/
-smx_actor_t simcall_process_create(const std::string& name, const simgrid::simix::ActorCode& code, void* data,
+smx_actor_t simcall_process_create(const std::string& name, const simgrid::kernel::actor::ActorCode& code, void* data,
sg_host_t host, std::unordered_map<std::string, std::string>* properties)
{
smx_actor_t self = simgrid::kernel::actor::ActorImpl::self();
s4u::Actor* ciface() { return &piface_; }
ActorImplPtr init(const std::string& name, s4u::Host* host);
- ActorImpl* start(const simix::ActorCode& code);
+ ActorImpl* start(const ActorCode& code);
- static ActorImplPtr create(const std::string& name, const simix::ActorCode& code, void* data, s4u::Host* host,
+ static ActorImplPtr create(const std::string& name, const ActorCode& code, void* data, s4u::Host* host,
const std::unordered_map<std::string, std::string>* properties, ActorImpl* parent_actor);
static ActorImplPtr attach(const std::string& name, void* data, s4u::Host* host,
const std::unordered_map<std::string, std::string>* properties);
extern void (*SMPI_switch_data_segment)(simgrid::s4u::ActorPtr actor);
+XBT_PUBLIC smx_actor_t simcall_process_create(const std::string& name, const simgrid::kernel::actor::ActorCode& code,
+ void* data, sg_host_t host,
+ std::unordered_map<std::string, std::string>* properties);
+
#endif
#ifndef WIN32
XBT_PUBLIC_DATA unsigned char sigsegv_stack[SIGSTKSZ];
#endif
-
-XBT_PRIVATE simgrid::simix::ActorCodeFactory& SIMIX_get_actor_code_factory(const std::string& name);
-
#endif
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/Exception.hpp"
+#include "simgrid/s4u/Engine.hpp"
#include "src/msg/msg_private.hpp"
+#include "xbt/functional.hpp"
#define MSG_CALL(type, oldname, args)
}
void MSG_function_register(const char* name, int (*code)(int, char**))
{
- simgrid_register_function(name, (void (*)(int, char**))code);
+ simgrid::s4u::Engine::get_instance()->register_function(
+ name, [code](std::vector<std::string> args) { return simgrid::xbt::wrap_main(code, std::move(args)); });
}
void MSG_function_register_default(int (*code)(int, char**))
{
- simgrid_register_default((void (*)(int, char**))code);
+ simgrid::s4u::Engine::get_instance()->register_default(
+ [code](std::vector<std::string> args) { return simgrid::xbt::wrap_main(code, std::move(args)); });
}
double MSG_get_clock()
{
xbt_dict_foreach (properties, cursor, key, value)
actor->set_property(key, value);
}
- sg_actor_start(actor, (void (*)(int, char**))code, argc, argv);
+ actor->start(std::move(simgrid::xbt::wrap_main(code, argc, argv)));
} catch (simgrid::HostFailureException const&) {
xbt_die("Could not launch a new process on failed host %s.", host->get_cname());
}
#include "simgrid/s4u/Host.hpp"
#include "simgrid/s4u/VirtualMachine.hpp"
#include "src/include/mc/mc.h"
+#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/activity/ExecImpl.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/surf/HostImpl.hpp"
ActorPtr Actor::create(const std::string& name, s4u::Host* host, const std::string& function,
std::vector<std::string> args)
{
- const simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(function);
+ const simgrid::kernel::actor::ActorCodeFactory& factory =
+ simgrid::kernel::EngineImpl::get_instance()->get_function(function);
return create(name, host, factory(std::move(args)));
}
void sg_actor_start(sg_actor_t actor, xbt_main_func_t code, int argc, const char* const* argv)
{
- simgrid::simix::ActorCode function;
+ simgrid::kernel::actor::ActorCode function;
if (code)
function = simgrid::xbt::wrap_main(code, argc, argv);
actor->start(std::move(function));
void Engine::register_function(const std::string& name, int (*code)(int, char**)) // deprecated
{
- pimpl->register_function(name, code);
+ register_function(name, [code](std::vector<std::string> args) { return xbt::wrap_main(code, std::move(args)); });
}
void Engine::register_default(int (*code)(int, char**)) // deprecated
{
- pimpl->register_default(code);
+ register_default([code](std::vector<std::string> args) { return xbt::wrap_main(code, std::move(args)); });
}
/** Registers the main function of an actor that will be launched from the deployment file */
void Engine::register_function(const std::string& name, void (*code)(int, char**))
{
- pimpl->register_function(name, code);
+ register_function(name, [code](std::vector<std::string> args) { return xbt::wrap_main(code, std::move(args)); });
}
/** Registers the main function of an actor that will be launched from the deployment file */
void Engine::register_function(const std::string& name, void (*code)(std::vector<std::string>))
{
- pimpl->register_function(name, code);
+ register_function(name,
+ [code](std::vector<std::string> args) { return std::bind(std::move(code), std::move(args)); });
}
/** Registers a function as the default main function of actors
*
*/
void Engine::register_default(void (*code)(int, char**))
{
- pimpl->register_default(code);
+ register_default([code](std::vector<std::string> args) { return xbt::wrap_main(code, std::move(args)); });
+}
+void Engine::register_default(kernel::actor::ActorCodeFactory code)
+{
+ simgrid::kernel::actor::simcall([this, code]() { pimpl->register_default(code); });
+}
+
+void Engine::register_function(const std::string& name, kernel::actor::ActorCodeFactory code)
+{
+ simgrid::kernel::actor::simcall([this, name, code]() { pimpl->register_function(name, code); });
}
/** Load a deployment file and launch the actors that it contains
#include "simgrid/s4u/Host.hpp"
#include "smx_private.hpp"
+#include "src/kernel/EngineImpl.hpp"
#include "src/surf/xml/platf_private.hpp" // FIXME: KILLME. There must be a better way than mimicking XML here
#include <simgrid/engine.h>
#include <simgrid/s4u/Engine.hpp>
simgrid::s4u::Engine::get_instance()->register_default(code);
}
-/**
- * @brief Gets a #smx_actor_t code from the global table.
- *
- * Gets a code function from the global table. Returns nullptr if there are no function registered with the name.
- * This table is then used by #SIMIX_launch_application.
- * @param name the reference name of the function.
- * @return The #smx_actor_t or nullptr.
- */
-simgrid::simix::ActorCodeFactory& SIMIX_get_actor_code_factory(const std::string& name)
-{
- xbt_assert(simix_global,
- "SIMIX_global_init has to be called before SIMIX_get_actor_code_factory.");
-
- auto i = simix_global->registered_functions.find(name);
- if (i == simix_global->registered_functions.end())
- return simix_global->default_function;
- else
- return i->second;
-}
-
/** @brief Bypass the parser, get arguments, and set function to each process */
-
void SIMIX_process_set_function(const char* process_host, const char* process_function, xbt_dynar_t arguments,
double process_start_time, double process_kill_time) // XBT_ATTRIB_DEPRECATED_v329
{
}
// Check we know how to handle this function name:
- const simgrid::simix::ActorCodeFactory& parse_code = SIMIX_get_actor_code_factory(process_function);
+ const simgrid::kernel::actor::ActorCodeFactory& parse_code =
+ simgrid::kernel::EngineImpl::get_instance()->get_function(process_function);
xbt_assert(parse_code, "Function '%s' unknown", process_function);
actor.function = process_function;
actor.restart_on_failure = false;
sg_platf_new_actor(&actor);
}
-
-namespace simgrid {
-namespace simix {
-
-void register_function(const std::string& name, const ActorCodeFactory& factory)
-{
- simix_global->registered_functions[name] = factory;
-}
-
-}
-}
} // namespace simix
} // namespace simgrid
-static simgrid::simix::ActorCode maestro_code;
+static simgrid::kernel::actor::ActorCode maestro_code;
void SIMIX_set_maestro(void (*code)(void*), void* data)
{
#ifdef _WIN32
#endif
kernel::actor::ActorImpl* maestro_ = nullptr;
- // Maps function names to actor code:
- std::unordered_map<std::string, simix::ActorCodeFactory> registered_functions;
-
- // This might be used when no corresponding function name is registered:
- simix::ActorCodeFactory default_function;
-
std::mutex mutex;
std::vector<xbt::Task<void()>> tasks;
}
}
- simix_global->default_function = [executable, fdin_size](std::vector<std::string> args) {
+ simgrid::s4u::Engine::get_instance()->register_default([executable, fdin_size](std::vector<std::string> args) {
return std::function<void()>([executable, fdin_size, args] {
static std::size_t rank = 0;
// Copy the dynamic library:
xbt_assert(entry_point, "Could not resolve entry point");
smpi_run_entry_point(entry_point, executable, args);
});
- };
+ });
}
static void smpi_init_privatization_no_dlopen(const std::string& executable)
smpi_backup_global_memory_segment();
// Execute the same entry point for each simulated process:
- simix_global->default_function = [entry_point, executable](std::vector<std::string> args) {
+ simgrid::s4u::Engine::get_instance()->register_default([entry_point, executable](std::vector<std::string> args) {
return std::function<void()>(
[entry_point, executable, args] { smpi_run_entry_point(entry_point, executable, args); });
- };
+ });
}
int smpi_main(const char* executable, int argc, char* argv[])
}
xbt_die("%s", msg.c_str());
}
- const simgrid::simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(actor->function);
+ const simgrid::kernel::actor::ActorCodeFactory& factory =
+ simgrid::kernel::EngineImpl::get_instance()->get_function(actor->function);
xbt_assert(factory, "Error while creating an actor from the XML file: Function '%s' not registered", actor->function);
double start_time = actor->start_time;
bool auto_restart = actor->restart_on_failure;
std::string actor_name = actor->args[0];
- simgrid::simix::ActorCode code = factory(std::move(actor->args));
+ simgrid::kernel::actor::ActorCode code = factory(std::move(actor->args));
std::shared_ptr<std::unordered_map<std::string, std::string>> properties(actor->properties);
simgrid::kernel::actor::ProcessArg* arg =
set_property(TARGET simgrid
APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}")
-# Don't complain when we cast (int (*)(int,char**)) into (void(*)(int,char**))
-# This will stop when MSG goes away
-if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- set_property(SOURCE ${CMAKE_HOME_DIRECTORY}/src/msg/msg_legacy.cpp PROPERTY COMPILE_FLAGS -Wno-error=bad-function-cast)
- set_property(SOURCE ${CMAKE_HOME_DIRECTORY}/src/msg/msg_process.cpp PROPERTY COMPILE_FLAGS -Wno-error=bad-function-cast)
-elseif(CMAKE_COMPILER_IS_GNUCXX)
- set_property(SOURCE ${CMAKE_HOME_DIRECTORY}/src/msg/msg_legacy.cpp PROPERTY COMPILE_FLAGS -Wno-error=cast-function-type)
- set_property(SOURCE ${CMAKE_HOME_DIRECTORY}/src/msg/msg_process.cpp PROPERTY COMPILE_FLAGS -Wno-error=cast-function-type)
-endif()
-
add_dependencies(simgrid maintainer_files)
if(enable_model-checking)