XBT_PUBLIC(void) MSG_function_register(const char *name,
xbt_main_func_t code);
XBT_PUBLIC(void) MSG_function_register_default(xbt_main_func_t code);
-XBT_PUBLIC(xbt_main_func_t) MSG_get_registered_function(const char *name);
XBT_PUBLIC(void) MSG_launch_application(const char *file);
/*Bypass the parser */
XBT_PUBLIC(void) MSG_set_function(const char *host_id,
XBT_PUBLIC(void) SIMIX_function_register(const char *name, xbt_main_func_t code);
XBT_PUBLIC(void) SIMIX_function_register_default(xbt_main_func_t code);
-XBT_PUBLIC(xbt_main_func_t) SIMIX_get_registered_function(const char *name);
XBT_PUBLIC(void) SIMIX_init_application(void);
XBT_PUBLIC(void) SIMIX_launch_application(const char *file);
this->read_variable("simix_global", &simix_global_p, sizeof(simix_global_p));
// simix_global = REMOTE(*simix_global)
- s_smx_global_t simix_global;
+ simgrid::simix::Global simix_global;
this->read_bytes(&simix_global, sizeof(simix_global),
remote(simix_global_p));
SIMIX_function_register_default(code);
}
-/** \ingroup msg_simulation
- * \brief Retrieves a registered main function
- *
- * Registers a code function in a global table.
- * This table is then used by #MSG_launch_application.
- * \param name the reference name of the function.
- */
-xbt_main_func_t MSG_get_registered_function(const char *name)
-{
- return SIMIX_get_registered_function(name);
-}
-
/**
* \brief register functions bypassing the parser
*/
}
}
+// Wrap a main() function into a ActorCodeFactory:
+static simgrid::simix::ActorCodeFactory toActorCodeFactory(xbt_main_func_t code)
+{
+ return [code](simgrid::xbt::args args) {
+ return simgrid::xbt::wrapMain(code, std::move(args));
+ };
+}
+
/**
* \brief Registers a #xbt_main_func_t code in a global table.
*
*/
void SIMIX_function_register(const char *name, xbt_main_func_t code)
{
- xbt_assert(simix_global, "SIMIX_global_init has to be called before SIMIX_function_register.");
- xbt_dict_set(simix_global->registered_functions, name, (void*) code, nullptr);
+ xbt_assert(simix_global,
+ "SIMIX_global_init has to be called before SIMIX_function_register.");
+ simix_global->registered_functions[name] = toActorCodeFactory(code);
}
-static xbt_main_func_t default_function = nullptr;
/**
* \brief Registers a #xbt_main_func_t code as default value.
*
void SIMIX_function_register_default(xbt_main_func_t code)
{
xbt_assert(simix_global, "SIMIX_global_init has to be called before SIMIX_function_register.");
-
- default_function = code;
+ simix_global->default_function = toActorCodeFactory(code);
}
/**
* \param name the reference name of the function.
* \return The #smx_process_t or nullptr.
*/
-xbt_main_func_t SIMIX_get_registered_function(const char *name)
+simgrid::simix::ActorCodeFactory& SIMIX_get_actor_code_factory(const char *name)
{
- xbt_main_func_t res = nullptr;
xbt_assert(simix_global,
- "SIMIX_global_init has to be called before SIMIX_get_registered_function.");
+ "SIMIX_global_init has to be called before SIMIX_get_actor_code_factory.");
- res = (xbt_main_func_t)xbt_dict_get_or_null(simix_global->registered_functions, name);
- return res ? res : default_function;
+ 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
*/
}
process.argv[process.argc] = nullptr;
- xbt_main_func_t parse_code = SIMIX_get_registered_function(process_function);
+ // Check we know how to handle this function name:
+ simgrid::simix::ActorCodeFactory& parse_code = SIMIX_get_actor_code_factory(process_function);
xbt_assert(parse_code, "Function '%s' unknown", process_function);
- process.function = process_function;
+ process.function = process_function;
process.host = process_host;
process.kill_time = process_kill_time;
process.start_time = process_start_time;
process.on_failure = SURF_PROCESS_ON_FAILURE_DIE;
-
sg_platf_new_process(&process);
}
XBT_LOG_NEW_CATEGORY(simix, "All SIMIX categories");
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_kernel, simix, "Logging specific to SIMIX (kernel)");
-smx_global_t simix_global = nullptr;
+std::unique_ptr<simgrid::simix::Global> simix_global;
static xbt_heap_t simix_timers = nullptr;
/** @brief Timer datatype */
#endif
if (!simix_global) {
- simix_global = xbt_new0(s_smx_global_t, 1);
+ simix_global = std::unique_ptr<simgrid::simix::Global>(new simgrid::simix::Global());
simgrid::simix::Process proc;
simix_global->process_to_run = xbt_dynar_new(sizeof(smx_process_t), nullptr);
simix_global->process_that_ran = xbt_dynar_new(sizeof(smx_process_t), nullptr);
simix_global->process_list = xbt_swag_new(xbt_swag_offset(proc, process_hookup));
simix_global->process_to_destroy = xbt_swag_new(xbt_swag_offset(proc, destroy_hookup));
-
simix_global->maestro_process = nullptr;
- simix_global->registered_functions = xbt_dict_new_homogeneous(nullptr);
-
simix_global->create_process_function = &SIMIX_process_create;
simix_global->kill_process_function = &kill_process;
simix_global->cleanup_process_function = &SIMIX_process_cleanup;
xbt_swag_free(simix_global->process_list);
simix_global->process_list = nullptr;
simix_global->process_to_destroy = nullptr;
- xbt_dict_free(&(simix_global->registered_functions));
xbt_os_mutex_destroy(simix_global->mutex);
simix_global->mutex = nullptr;
surf_exit();
- xbt_free(simix_global);
simix_global = nullptr;
-
return;
}
#define _SIMIX_PRIVATE_H
#include <functional>
+#include <memory>
+#include <unordered_map>
+
+#include <xbt/functional.hpp>
#include "src/internal_config.h"
#include "simgrid/simix.h"
#endif
-SG_BEGIN_DECL()
-
/********************************** Simix Global ******************************/
-typedef struct s_smx_global {
- smx_context_factory_t context_factory;
- xbt_dynar_t process_to_run;
- xbt_dynar_t process_that_ran;
- xbt_swag_t process_list;
- xbt_swag_t process_to_destroy;
- smx_process_t maestro_process;
- xbt_dict_t registered_functions;
- smx_creation_func_t create_process_function;
- void_pfn_smxprocess_t kill_process_function;
+
+namespace simgrid {
+namespace simix {
+
+// What's executed as SIMIX actor code:
+typedef std::function<void()> ActorCode;
+
+// Create ActorCode based on argv:
+typedef std::function<ActorCode(simgrid::xbt::args args)> ActorCodeFactory;
+
+class Global {
+public:
+ smx_context_factory_t context_factory = nullptr;
+ xbt_dynar_t process_to_run = nullptr;
+ xbt_dynar_t process_that_ran = nullptr;
+ xbt_swag_t process_list = nullptr;
+ xbt_swag_t process_to_destroy = nullptr;
+ smx_process_t maestro_process = nullptr;
+
+ // Maps function names to actor code:
+ std::unordered_map<std::string, simgrid::simix::ActorCodeFactory> registered_functions;
+
+ // This might be used when no corresponding function name is registered:
+ simgrid::simix::ActorCodeFactory default_function;
+
+ smx_creation_func_t create_process_function = nullptr;
+ void_pfn_smxprocess_t kill_process_function = nullptr;
/** Callback used when killing a SMX_process */
- void_pfn_smxprocess_t cleanup_process_function;
+ void_pfn_smxprocess_t cleanup_process_function = nullptr;
+ xbt_os_mutex_t mutex = nullptr;
+};
- xbt_os_mutex_t mutex;
-} s_smx_global_t, *smx_global_t;
+}
+}
+
+SG_BEGIN_DECL()
+
+XBT_PUBLIC_DATA(std::unique_ptr<simgrid::simix::Global>) simix_global;
-XBT_PUBLIC_DATA(smx_global_t) simix_global;
extern XBT_PRIVATE unsigned long simix_process_maxpid;
XBT_PUBLIC(void) SIMIX_clean(void);
// FIXME, Dirty hack for SMPI+MSG
XBT_PRIVATE void SIMIX_process_set_cleanup_function(smx_process_t process, void_pfn_smxprocess_t cleanup);
+XBT_PRIVATE simgrid::simix::ActorCodeFactory& SIMIX_get_actor_code_factory(const char *name);
+
SG_END_DECL()
#endif
msg->data[msg->used-3]='\0';
xbt_die("%s", msg->data);
}
- xbt_main_func_t parse_code = SIMIX_get_registered_function(process->function);
- xbt_assert(parse_code, "Function '%s' unknown", process->function);
+ simgrid::simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(process->function);
+ xbt_assert(factory, "Function '%s' unknown", process->function);
double start_time = process->start_time;
double kill_time = process->kill_time;
int auto_restart = process->on_failure == SURF_PROCESS_ON_FAILURE_DIE ? 0 : 1;
- std::function<void()> code = simgrid::xbt::wrapMain(parse_code, process->argc, process->argv);
+ std::function<void()> code = factory(simgrid::xbt::args(process->argc, process->argv));
smx_process_arg_t arg = nullptr;
smx_process_t process_created = nullptr;