Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[simix] More generic mapping between function name and actor code
authorGabriel Corona <gabriel.corona@loria.fr>
Wed, 22 Jun 2016 08:35:39 +0000 (10:35 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Wed, 22 Jun 2016 13:03:11 +0000 (15:03 +0200)
It was only possible to associate main() style function to function
names. Now we can associate any kind of function which will be useful
in order for S4U-style code registration.

include/simgrid/msg.h
include/simgrid/simix.h
src/mc/mc_smx.cpp
src/msg/msg_deployment.cpp
src/simix/smx_deployment.cpp
src/simix/smx_global.cpp
src/simix/smx_private.h
src/surf/sg_platf.cpp

index 2759482..681572d 100644 (file)
@@ -197,7 +197,6 @@ XBT_PUBLIC(msg_error_t) MSG_main(void);
 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,
index 9beaaf8..87ba0bc 100644 (file)
@@ -177,7 +177,6 @@ XBT_PUBLIC(void) SIMIX_create_environment(const char *file);
 
 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);
 
index daf6b83..b7135d6 100644 (file)
@@ -84,7 +84,7 @@ void Process::refresh_simix()
   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));
 
index af82087..015d748 100644 (file)
@@ -52,18 +52,6 @@ void MSG_function_register_default(xbt_main_func_t code)
   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
  */
index 44ccbb8..b5e84b1 100644 (file)
@@ -56,6 +56,14 @@ void SIMIX_launch_application(const char *file)
   }
 }
 
+// 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.
  *
@@ -66,11 +74,11 @@ void SIMIX_launch_application(const char *file)
  */
 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.
  *
@@ -80,8 +88,7 @@ static xbt_main_func_t default_function = nullptr;
 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);
 }
 
 /**
@@ -92,17 +99,18 @@ void SIMIX_function_register_default(xbt_main_func_t 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
  */
@@ -132,14 +140,14 @@ void SIMIX_process_set_function(const char *process_host,
   }
   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);
 }
index ab8d595..6549bdb 100644 (file)
@@ -44,7 +44,7 @@
 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 */
@@ -194,17 +194,14 @@ void SIMIX_global_init(int *argc, char **argv)
 #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;
@@ -299,7 +296,6 @@ void SIMIX_clean(void)
   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;
@@ -315,9 +311,7 @@ void SIMIX_clean(void)
 
   surf_exit();
 
-  xbt_free(simix_global);
   simix_global = nullptr;
-
   return;
 }
 
index feb9990..6906a08 100644 (file)
@@ -8,6 +8,10 @@
 #define _SIMIX_PRIVATE_H
 
 #include <functional>
+#include <memory>
+#include <unordered_map>
+
+#include <xbt/functional.hpp>
 
 #include "src/internal_config.h"
 #include "simgrid/simix.h"
@@ -58,26 +62,46 @@ typedef struct s_smx_context_factory *smx_context_factory_t;
 
 #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);
@@ -153,6 +177,8 @@ XBT_PRIVATE void SIMIX_post_create_environment(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
index 036b9ca..7b85965 100644 (file)
@@ -570,14 +570,14 @@ void sg_platf_new_process(sg_platf_process_cbarg_t process)
     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;