Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
First running version after the relocation of the context module [Cristian]
[simgrid.git] / src / simix / smx_process.c
index f8d8337..0615265 100644 (file)
@@ -8,33 +8,51 @@
 #include "private.h"
 #include "xbt/sysdep.h"
 #include "xbt/log.h"
 #include "private.h"
 #include "xbt/sysdep.h"
 #include "xbt/log.h"
+#include "xbt/dict.h"
+#include "msg/mailbox.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_process, simix,
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_process, simix,
-                               "Logging specific to SIMIX (process)");
+                                "Logging specific to SIMIX (process)");
 
 /******************************** Process ************************************/
 /**
  * \brief Creates and runs a new #smx_process_t.
  *
 
 /******************************** Process ************************************/
 /**
  * \brief Creates and runs a new #smx_process_t.
  *
- * Does exactly the same as #SIMIX_process_create_with_arguments but without 
+ * Does exactly the same as #SIMIX_process_create_with_arguments but without
    providing standard arguments (\a argc, \a argv).
  * \see SIMIX_process_create_with_arguments
  */
 
    providing standard arguments (\a argc, \a argv).
  * \see SIMIX_process_create_with_arguments
  */
 
-
 void SIMIX_process_cleanup(void *arg)
 {
 void SIMIX_process_cleanup(void *arg)
 {
-  xbt_swag_remove(arg, simix_global->process_list);
   xbt_swag_remove(arg, simix_global->process_to_run);
   xbt_swag_remove(arg, simix_global->process_to_run);
-  xbt_swag_remove(arg,
-                 ((smx_process_t) arg)->simdata->s_host->simdata->
-                 process_list);
-  free(((smx_process_t) arg)->name);
-  ((smx_process_t) arg)->name = NULL;
-
-  free(((smx_process_t) arg)->simdata);
-  ((smx_process_t) arg)->simdata = NULL;
-  free(arg);
+  xbt_swag_remove(arg, simix_global->process_list);
+  xbt_swag_remove(arg, ((smx_process_t)arg)->smx_host->process_list);
+  xbt_swag_insert(arg, simix_global->process_to_destroy);
+}
+
+
+/**
+ * \brief Creates and runs the maestro process
+ *
+ */
+
+void __SIMIX_create_maestro_process()
+{
+  smx_process_t process = NULL;
+  process = xbt_new0(s_smx_process_t, 1);
+
+  /* Process data */
+  process->name = (char *)"maestro";
+
+  /*Create the right context type (FIXME: check the return value for success)*/
+  SIMIX_context_create_maestro(&process);
+
+  /* Set it as the maestro process */
+  simix_global->maestro_process = process;
+  simix_global->current_process = process;
+  
+  return;
 }
 
 /** 
 }
 
 /** 
@@ -47,45 +65,56 @@ void SIMIX_process_cleanup(void *arg)
  * \param host the location where the new agent is executed.
  * \param argc first argument passed to \a code
  * \param argv second argument passed to \a code
  * \param host the location where the new agent is executed.
  * \param argc first argument passed to \a code
  * \param argv second argument passed to \a code
- * \param clean_process_function The cleanup function of user process. It will be called when the process finish. This function have to call the SIMIX_process_cleanup.        
+ * \param clean_process_function The cleanup function of user process. It will be called when the process finish. This function have to call the SIMIX_process_cleanup.
  * \see smx_process_t
  * \return The new corresponding object.
  */
 smx_process_t SIMIX_process_create(const char *name,
  * \see smx_process_t
  * \return The new corresponding object.
  */
 smx_process_t SIMIX_process_create(const char *name,
-                                  xbt_main_func_t code, void *data,
-                                  const char *hostname, int argc,
-                                  char **argv)
+                                   xbt_main_func_t code, void *data,
+                                   const char *hostname, int argc,
+                                   char **argv, xbt_dict_t properties)
 {
 {
-  smx_simdata_process_t simdata = xbt_new0(s_smx_simdata_process_t, 1);
-  smx_process_t process = xbt_new0(s_smx_process_t, 1);
+  smx_process_t process = NULL;
   smx_process_t self = NULL;
   smx_host_t host = SIMIX_host_get_by_name(hostname);
 
   smx_process_t self = NULL;
   smx_host_t host = SIMIX_host_get_by_name(hostname);
 
+  DEBUG2("Start process %s on host %s", name, hostname);
+
+  if (!SIMIX_host_get_state(host)) {
+    WARN2("Cannot launch process '%s' on failed host '%s'", name, hostname);
+    return NULL;
+  }
+  process = xbt_new0(s_smx_process_t, 1);
+
   xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters");
   xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters");
-  /* Simulator Data */
-
-  simdata->s_host = host;
-  simdata->mutex = NULL;
-  simdata->cond = NULL;
-  simdata->argc = argc;
-  simdata->argv = argv;
-  simdata->context = xbt_context_new(name,code, NULL, NULL,
-                                    simix_global->
-                                    cleanup_process_function, process,
-                                    simdata->argc, simdata->argv);
-
-  /* Process structure */
+
+  /* Process data */
   process->name = xbt_strdup(name);
   process->name = xbt_strdup(name);
-  process->simdata = simdata;
+  process->smx_host = host;
+  process->argc = argc;
+  process->argv = argv;
+  process->mutex = NULL;
+  process->cond = NULL;
+
+  /*Create the right context type (FIXME: check the return value for success)*/
+  SIMIX_context_new(&process, code);
+
   process->data = data;
   process->data = data;
+  process->cleanup_func = simix_global->cleanup_process_function;
+  process->cleanup_arg = process;
 
 
-  xbt_swag_insert(process, host->simdata->process_list);
+  /* Add properties */
+  process->properties = properties;
 
 
-  /* fix current_process, about which xbt_context_start mocks around */
+  /* Add the process to it's host process list */
+  xbt_swag_insert(process, host->process_list);
+
+  /* fix current_process, about which SIMIX_context_start mocks around */
   self = simix_global->current_process;
   self = simix_global->current_process;
-  xbt_context_start(process->simdata->context);
+  SIMIX_context_start(process);
   simix_global->current_process = self;
 
   simix_global->current_process = self;
 
+  /* Now insert it in the global process list and in the process to run list */
   xbt_swag_insert(process, simix_global->process_list);
   DEBUG2("Inserting %s(%s) in the to_run list", process->name, host->name);
   xbt_swag_insert(process, simix_global->process_to_run);
   xbt_swag_insert(process, simix_global->process_list);
   DEBUG2("Inserting %s(%s) in the to_run list", process->name, host->name);
   xbt_swag_insert(process, simix_global->process_to_run);
@@ -93,26 +122,25 @@ smx_process_t SIMIX_process_create(const char *name,
   return process;
 }
 
   return process;
 }
 
-/** 
+/**
  * \brief Creates and runs a new #smx_process_t hosting a JAVA thread
  *
  * Warning: this should only be used in libsimgrid4java, since it create
  * \brief Creates and runs a new #smx_process_t hosting a JAVA thread
  *
  * Warning: this should only be used in libsimgrid4java, since it create
- * a context with no code, which leads to segfaults in plain libsimgrid 
+ * a context with no code, which leads to segfaults in plain libsimgrid
  */
 void SIMIX_jprocess_create(const char *name, smx_host_t host,
  */
 void SIMIX_jprocess_create(const char *name, smx_host_t host,
-                          void *data,
-                          void *jprocess, void *jenv, smx_process_t * res)
+                           void *data,
+                           void *jprocess, void *jenv, smx_process_t * res)
 {
 {
-  smx_simdata_process_t simdata = xbt_new0(s_smx_simdata_process_t, 1);
   smx_process_t process = xbt_new0(s_smx_process_t, 1);
   smx_process_t self = NULL;
 
   /* HACK: We need this trick because when we xbt_context_new() do
   smx_process_t process = xbt_new0(s_smx_process_t, 1);
   smx_process_t self = NULL;
 
   /* HACK: We need this trick because when we xbt_context_new() do
-     syncronization stuff, the s_process field in the m_process needs 
-     to have a valid value, and we call xbt_context_new() before 
-     returning, of course, ie, before providing a right value to the 
-     caller (Java_simgrid_msg_Msg_processCreate) have time to store it  
-     in place. This way, we initialize the m_process->simdata->s_process 
+     syncronization stuff, the s_process field in the m_process needs
+     to have a valid value, and we call xbt_context_new() before
+     returning, of course, ie, before providing a right value to the
+     caller (Java_simgrid_msg_Msg_processCreate) have time to store it
+     in place. This way, we initialize the m_process->simdata->s_process
      field ourself ASAP.
 
      All this would be much simpler if the synchronization stuff would be done
      field ourself ASAP.
 
      All this would be much simpler if the synchronization stuff would be done
@@ -120,44 +148,34 @@ void SIMIX_jprocess_create(const char *name, smx_host_t host,
    */
   *res = process;
 
    */
   *res = process;
 
-
-
   DEBUG5("jprocess_create(name=%s,host=%p,data=%p,jproc=%p,jenv=%p)",
   DEBUG5("jprocess_create(name=%s,host=%p,data=%p,jproc=%p,jenv=%p)",
-        name, host, data, jprocess, jenv);
+         name, host, data, jprocess, jenv);
   xbt_assert0(host, "Invalid parameters");
   xbt_assert0(host, "Invalid parameters");
-  /* Simulator Data */
-  simdata->s_host = host;
-  simdata->mutex = NULL;
-  simdata->cond = NULL;
-  simdata->argc = 0;
-  simdata->argv = NULL;
-
-  simdata->context = xbt_context_new(name,NULL, NULL, NULL,
-                                    simix_global->
-                                    cleanup_process_function, process,
-                                    /* argc/argv */ 0, NULL);
-
-  /* Process structure */
+
+  /* Process data */
   process->name = xbt_strdup(name);
   process->name = xbt_strdup(name);
-  process->simdata = simdata;
+  process->smx_host = host;
+  process->argc = 0;
+  process->argv = NULL;
+  process->mutex = NULL;
+  process->cond = NULL;
+  SIMIX_context_new(&process, jprocess);
   process->data = data;
   process->data = data;
-  SIMIX_process_set_jprocess(process, jprocess);
-  SIMIX_process_set_jenv(process, jenv);
 
 
-  xbt_swag_insert(process, host->simdata->process_list);
+  /* Add the process to it's host process list */
+  xbt_swag_insert(&process, host->process_list);
 
   /* fix current_process, about which xbt_context_start mocks around */
   self = simix_global->current_process;
 
   /* fix current_process, about which xbt_context_start mocks around */
   self = simix_global->current_process;
-  xbt_context_start(process->simdata->context);
+  SIMIX_context_start(process);
   simix_global->current_process = self;
 
   simix_global->current_process = self;
 
+  /* Now insert it in the global process list and in the process to run list */
   xbt_swag_insert(process, simix_global->process_list);
   DEBUG2("Inserting %s(%s) in the to_run list", process->name, host->name);
   xbt_swag_insert(process, simix_global->process_to_run);
   xbt_swag_insert(process, simix_global->process_list);
   DEBUG2("Inserting %s(%s) in the to_run list", process->name, host->name);
   xbt_swag_insert(process, simix_global->process_to_run);
-
 }
 
 }
 
-
 /** \brief Kill a SIMIX process
  *
  * This function simply kills a \a process... scarry isn't it ? :).
 /** \brief Kill a SIMIX process
  *
  * This function simply kills a \a process... scarry isn't it ? :).
@@ -166,26 +184,22 @@ void SIMIX_jprocess_create(const char *name, smx_host_t host,
  */
 void SIMIX_process_kill(smx_process_t process)
 {
  */
 void SIMIX_process_kill(smx_process_t process)
 {
-  smx_simdata_process_t p_simdata = process->simdata;
-
   DEBUG2("Killing process %s on %s", process->name,
   DEBUG2("Killing process %s on %s", process->name,
-        p_simdata->s_host->name);
+         process->smx_host->name);
 
   /* Cleanup if we were waiting for something */
 
   /* Cleanup if we were waiting for something */
-  if (p_simdata->mutex)
-    xbt_swag_remove(process, p_simdata->mutex->sleeping);
+  if (process->mutex)
+    xbt_swag_remove(process, process->mutex->sleeping);
 
 
-  if (p_simdata->cond)
-    xbt_swag_remove(process, p_simdata->cond->sleeping);
+  if (process->cond)
+    xbt_swag_remove(process, process->cond->sleeping);
 
 
-  xbt_swag_remove(process, simix_global->process_to_run);
-  xbt_swag_remove(process, simix_global->process_list);
   DEBUG2("%p here! killing %p", simix_global->current_process, process);
   DEBUG2("%p here! killing %p", simix_global->current_process, process);
-  xbt_context_kill(process->simdata->context);
+  SIMIX_context_kill(process);
 
   if (process == SIMIX_process_self()) {
     /* I just killed myself */
 
   if (process == SIMIX_process_self()) {
     /* I just killed myself */
-    xbt_context_yield();
+    SIMIX_context_yield();
   }
 }
 
   }
 }
 
@@ -213,10 +227,8 @@ void *SIMIX_process_get_data(smx_process_t process)
 void SIMIX_process_set_data(smx_process_t process, void *data)
 {
   xbt_assert0((process != NULL), "Invalid parameters");
 void SIMIX_process_set_data(smx_process_t process, void *data)
 {
   xbt_assert0((process != NULL), "Invalid parameters");
-  //xbt_assert0((process->data == NULL), "Data already set");
 
   process->data = data;
 
   process->data = data;
-
   return;
 }
 
   return;
 }
 
@@ -229,10 +241,8 @@ void SIMIX_process_set_data(smx_process_t process, void *data)
  */
 smx_host_t SIMIX_process_get_host(smx_process_t process)
 {
  */
 smx_host_t SIMIX_process_get_host(smx_process_t process)
 {
-  xbt_assert0(((process != NULL)
-              && (process->simdata)), "Invalid parameters");
-
-  return (process->simdata->s_host);
+  xbt_assert0((process != NULL), "Invalid parameters");
+  return (process->smx_host);
 }
 
 /**
 }
 
 /**
@@ -244,12 +254,33 @@ smx_host_t SIMIX_process_get_host(smx_process_t process)
  */
 const char *SIMIX_process_get_name(smx_process_t process)
 {
  */
 const char *SIMIX_process_get_name(smx_process_t process)
 {
-  xbt_assert0(((process != NULL)
-              && (process->simdata)), "Invalid parameters");
-
+  xbt_assert0((process != NULL), "Invalid parameters");
   return (process->name);
 }
 
   return (process->name);
 }
 
+/**
+ * \brief Changes the name of an agent.
+ *
+ * This functions checks whether \a process is a valid pointer or not and return its name.
+ * \param process SIMIX process
+ * \param name The new process name
+ */
+void SIMIX_process_set_name(smx_process_t process, char *name)
+{
+  xbt_assert0((process != NULL), "Invalid parameters");
+  process->name = name;
+}
+
+/** \ingroup m_process_management
+ * \brief Return the properties
+ *
+ * This functions returns the properties associated with this process
+ */
+xbt_dict_t SIMIX_process_get_properties(smx_process_t process)
+{
+  return process->properties;
+}
+
 /**
  * \brief Return the current agent.
  *
 /**
  * \brief Return the current agent.
  *
@@ -271,17 +302,14 @@ smx_process_t SIMIX_process_self(void)
  */
 void SIMIX_process_suspend(smx_process_t process)
 {
  */
 void SIMIX_process_suspend(smx_process_t process)
 {
-  smx_simdata_process_t simdata = NULL;
-
-  xbt_assert0(((process) && (process->simdata)), "Invalid parameters");
+  xbt_assert0(process, "Invalid parameters");
 
   if (process != SIMIX_process_self()) {
 
   if (process != SIMIX_process_self()) {
-    simdata = process->simdata;
 
 
-    if (simdata->mutex) {
+    if (process->mutex) {
       /* process blocked on a mutex, only set suspend=1 */
       /* process blocked on a mutex, only set suspend=1 */
-      simdata->suspended = 1;
-    } else if (simdata->cond) {
+      process->suspended = 1;
+    } else if (process->cond) {
       /* process blocked cond, suspend all actions */
 
       /* temporaries variables */
       /* process blocked cond, suspend all actions */
 
       /* temporaries variables */
@@ -289,31 +317,29 @@ void SIMIX_process_suspend(smx_process_t process)
       xbt_fifo_item_t i;
       smx_action_t act;
 
       xbt_fifo_item_t i;
       smx_action_t act;
 
-      simdata->suspended = 1;
-      c = simdata->cond;
+      process->suspended = 1;
+      c = process->cond;
       xbt_fifo_foreach(c->actions, i, act, smx_action_t) {
       xbt_fifo_foreach(c->actions, i, act, smx_action_t) {
-       surf_workstation_model->common_public->suspend(act->simdata->
-                                                         surf_action);
+        surf_workstation_model->suspend(act->surf_action);
       }
     } else {
       }
     } else {
-      simdata->suspended = 1;
+      process->suspended = 1;
     }
   } else {
     /* process executing, I can create an action and suspend it */
     }
   } else {
     /* process executing, I can create an action and suspend it */
-    process->simdata->suspended = 1;
     smx_action_t dummy;
     smx_cond_t cond;
     char name[] = "dummy";
     smx_action_t dummy;
     smx_cond_t cond;
     char name[] = "dummy";
+    process->suspended = 1;
 
     cond = SIMIX_cond_init();
     dummy = SIMIX_action_execute(SIMIX_process_get_host(process), name, 0);
 
     cond = SIMIX_cond_init();
     dummy = SIMIX_action_execute(SIMIX_process_get_host(process), name, 0);
-    surf_workstation_model->common_public->set_priority(dummy->simdata->
-                                                          surf_action,
-                                                          0.0);
+    surf_workstation_model->suspend(dummy->surf_action);
     SIMIX_register_action_to_condition(dummy, cond);
     __SIMIX_cond_wait(cond);
     SIMIX_register_action_to_condition(dummy, cond);
     __SIMIX_cond_wait(cond);
-    //SIMIX_action_destroy(dummy);
-    //SIMIX_cond_destroy(cond);
+    SIMIX_unregister_action_to_condition(dummy, cond);
+    SIMIX_action_destroy(dummy);
+    SIMIX_cond_destroy(cond);
   }
   return;
 }
   }
   return;
 }
@@ -326,39 +352,48 @@ void SIMIX_process_suspend(smx_process_t process)
  */
 void SIMIX_process_resume(smx_process_t process)
 {
  */
 void SIMIX_process_resume(smx_process_t process)
 {
-  smx_simdata_process_t simdata = NULL;
-
-  xbt_assert0(((process != NULL)
-              && (process->simdata)), "Invalid parameters");
+  xbt_assert0((process != NULL), "Invalid parameters");
   SIMIX_CHECK_HOST();
 
   SIMIX_CHECK_HOST();
 
-  if (process == SIMIX_process_self()) {
+  if (process == SIMIX_process_self())
     return;
     return;
-  }
 
 
-  simdata = process->simdata;
-  if (simdata->mutex) {
+  if (process->mutex) {
     DEBUG0("Resume process blocked on a mutex");
     DEBUG0("Resume process blocked on a mutex");
-    simdata->suspended = 0;    /* He'll wake up by itself */
+    process->suspended = 0;     /* It'll wake up by itself when mutex releases */
     return;
     return;
-  } else if (simdata->cond) {
-    DEBUG0("Resume process blocked on a conditional");
+  } else if (process->cond) {
     /* temporaries variables */
     smx_cond_t c;
     xbt_fifo_item_t i;
     smx_action_t act;
     /* temporaries variables */
     smx_cond_t c;
     xbt_fifo_item_t i;
     smx_action_t act;
-    simdata->suspended = 0;
-    c = simdata->cond;
+    DEBUG0("Resume process blocked on a conditional");
+    process->suspended = 0;
+    c = process->cond;
     xbt_fifo_foreach(c->actions, i, act, smx_action_t) {
     xbt_fifo_foreach(c->actions, i, act, smx_action_t) {
-      surf_workstation_model->common_public->resume(act->simdata->
-                                                      surf_action);
+      surf_workstation_model->resume(act->surf_action);
     }
     }
+    SIMIX_cond_signal(c);
     return;
   } else {
     return;
   } else {
-    simdata->suspended = 0;
+    process->suspended = 0;
     xbt_swag_insert(process, simix_global->process_to_run);
   }
     xbt_swag_insert(process, simix_global->process_to_run);
   }
+}
 
 
+/**
+ * \brief Migrates an agent to another location.
+ *
+ * This function changes the value of the host on which \a process is running.
+ */
+void SIMIX_process_change_host(smx_process_t process, char *source, char *dest)
+{
+  xbt_assert0((process != NULL), "Invalid parameters");
+  smx_host_t h1 = SIMIX_host_get_by_name(source);
+  smx_host_t h2 = SIMIX_host_get_by_name(dest);
+  process->smx_host = h2;
+  xbt_swag_remove(process, h1->process_list);
+  xbt_swag_insert(process, h2->process_list);
 }
 
 /**
 }
 
 /**
@@ -370,52 +405,17 @@ void SIMIX_process_resume(smx_process_t process)
  */
 int SIMIX_process_is_suspended(smx_process_t process)
 {
  */
 int SIMIX_process_is_suspended(smx_process_t process)
 {
-  xbt_assert0(((process != NULL)
-              && (process->simdata)), "Invalid parameters");
+  xbt_assert0(((process != NULL), "Invalid parameters");
 
 
-  return (process->simdata->suspended);
+  return (process->suspended);
 }
 
 }
 
-
-/* Helper functions for jMSG: manipulate the context data without breaking the module separation */
-#include "xbt/context.h"       /* to pass java objects from MSG to the context */
-
-void SIMIX_process_set_jprocess(smx_process_t process, void *jp)
-{
-  xbt_context_set_jprocess(process->simdata->context, jp);
-}
-
-void *SIMIX_process_get_jprocess(smx_process_t process)
-{
-  return xbt_context_get_jprocess(process->simdata->context);
-}
-
-void SIMIX_process_set_jmutex(smx_process_t process, void *jm)
-{
-  xbt_context_set_jmutex(process->simdata->context, jm);
-}
-
-void *SIMIX_process_get_jmutex(smx_process_t process)
-{
-  return xbt_context_get_jmutex(process->simdata->context);
-}
-
-void SIMIX_process_set_jcond(smx_process_t process, void *jc)
-{
-  xbt_context_set_jcond(process->simdata->context, jc);
-}
-
-void *SIMIX_process_get_jcond(smx_process_t process)
-{
-  return xbt_context_get_jcond(process->simdata->context);
-}
-
-void SIMIX_process_set_jenv(smx_process_t process, void *je)
-{
-  xbt_context_set_jenv(process->simdata->context, je);
-}
-
-void *SIMIX_process_get_jenv(smx_process_t process)
+/**
+ * \brief Returns the amount of SIMIX processes in the system
+ *
+ * Maestro internal process is not counted, only user code processes are
+ */
+int SIMIX_process_count()
 {
 {
-  return xbt_context_get_jenv(process->simdata->context);
+  return xbt_swag_size(simix_global->process_list);
 }
 }