Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
* Cleanup the DTD by renaming:
[simgrid.git] / src / msg / m_process.c
index 6e025d3..6bd53d0 100644 (file)
@@ -1,17 +1,18 @@
 /*     $Id$      */
-  
+
 /* Copyright (c) 2002-2007 Arnaud Legrand.                                  */
 /* Copyright (c) 2007 Bruno Donassolo.                                      */
 /* All rights reserved.                                                     */
 
 /* 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 "msg/private.h"
 #include "xbt/sysdep.h"
 #include "xbt/log.h"
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_process, msg, "Logging specific to MSG (process)");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_process, msg,
+                               "Logging specific to MSG (process)");
 
 /** \defgroup m_process_management Management Functions of Agents
  *  \brief This section describes the agent structure of MSG
@@ -36,27 +37,49 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_process, msg, "Logging specific to MSG (proc
  * \sa MSG_process_create_with_arguments
  */
 m_process_t MSG_process_create(const char *name,
-                              m_process_code_t code, void *data,
+                              xbt_main_func_t code, void *data,
                               m_host_t host)
 {
-  return MSG_process_create_with_arguments(name, code, data, host, -1, NULL);
+  return MSG_process_create_with_arguments(name, code, data, host, -1,
+                                          NULL);
 }
 
-static void MSG_process_cleanup(void *arg)
+void __MSG_process_cleanup(void *arg)
 {
-       /* arg is a pointer to a simix process, we can get the msg process with the field data */
-       m_process_t proc = ((smx_process_t)arg)->data;
+  /* arg is a pointer to a simix process, we can get the msg process with the field data */
+  m_process_t proc = ((smx_process_t) arg)->data;
   xbt_fifo_remove(msg_global->process_list, proc);
-       SIMIX_process_cleanup(arg);
+  SIMIX_process_cleanup(arg);
   free(proc->name);
   proc->name = NULL;
   free(proc->simdata);
   proc->simdata = NULL;
   free(proc);
 
-       return;
+  return;
+}
+
+/* This function creates a MSG process. It has the prototype by SIMIX_function_register_process_create */
+void *_MSG_process_create_from_SIMIX(const char *name,
+                                    xbt_main_func_t code, void *data,
+                                    char *hostname, int argc, char **argv)
+{
+  m_host_t host = MSG_get_host_by_name(hostname);
+  return (void *) MSG_process_create_with_arguments(name, code, data, host,
+                                                   argc, argv);
+}
+
+/* This function creates a MSG process with properties. It has the prototype by SIMIX_function_register_process_create */
+void *_MSG_process_create_with_env_from_SIMIX(const char *name,
+                                    xbt_main_func_t code, void *data,
+                                    char *hostname, int argc, char **argv, xbt_dict_t properties)
+{
+  m_host_t host = MSG_get_host_by_name(hostname);
+  return (void *) MSG_process_create_with_environment(name, code, data, host,
+                                                   argc, argv,properties);
 }
 
+
 /** \ingroup m_process_management
  * \brief Creates and runs a new #m_process_t.
 
@@ -82,47 +105,109 @@ static void MSG_process_cleanup(void *arg)
  * \return The new corresponding object.
  */
 
+m_process_t MSG_process_create_with_arguments(const char *name,
+                                             xbt_main_func_t code,
+                                             void *data, m_host_t host,
+                                             int argc, char **argv)
+{
+  simdata_process_t simdata = xbt_new0(s_simdata_process_t, 1);
+  m_process_t process = xbt_new0(s_m_process_t, 1);
+  xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters");
 
+  /* Simulator Data */
+  simdata->PID = msg_global->PID++;
+  simdata->waiting_task = NULL;
+  simdata->m_host = host;
+  simdata->argc = argc;
+  simdata->argv = argv;
+  simdata->s_process = SIMIX_process_create(name, code,
+                                           (void *) process, host->name,
+                                           argc, argv, NULL);
+
+  if (SIMIX_process_self()) {
+    simdata->PPID = MSG_process_get_PID(SIMIX_process_self()->data);
+  } else {
+    simdata->PPID = -1;
+  }
+  simdata->last_errno = MSG_OK;
 
-m_process_t __MSG_process_create_with_arguments(const char *name,
-                                             m_process_code_t code, void *data,
-                                             char * hostname, int argc, char **argv)
-{
-       m_host_t host = MSG_get_host_by_name(hostname);
-       return MSG_process_create_with_arguments(name,code,data,host,argc,argv);
+
+  /* Process structure */
+  process->name = xbt_strdup(name);
+  process->simdata = simdata;
+  process->data = data ;
+
+  xbt_fifo_unshift(msg_global->process_list, process);
+
+  return process;
 }
 
-m_process_t MSG_process_create_with_arguments(const char *name,
-                                             m_process_code_t code, void *data,
-                                             m_host_t host, int argc, char **argv)
+/** \ingroup m_process_management
+ * \brief Creates and runs a new #m_process_t.
+
+ * A constructor for #m_process_t taking four arguments and returning the 
+ * corresponding object. The structure (and the corresponding thread) is
+ * created, and put in the list of ready process.
+ * \param name a name for the object. It is for user-level information
+   and can be NULL.
+ * \param code is a function describing the behavior of the agent. It
+   should then only use functions described in \ref
+   m_process_management (to create a new #m_process_t for example),
+   in \ref m_host_management (only the read-only functions i.e. whose
+   name contains the word get), in \ref m_task_management (to create
+   or destroy some #m_task_t for example) and in \ref
+   msg_gos_functions (to handle file transfers and task processing).
+ * \param data a pointer to any data one may want to attach to the new
+   object.  It is for user-level information and can be NULL. It can
+   be retrieved with the function \ref MSG_process_get_data.
+ * \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 properties list a properties defined for this process
+ * \see m_process_t
+ * \return The new corresponding object.
+ */
+m_process_t MSG_process_create_with_environment(const char *name,
+                                             xbt_main_func_t code,
+                                             void *data, m_host_t host,
+                                             int argc, char **argv, xbt_dict_t properties)
 {
-  simdata_process_t simdata = xbt_new0(s_simdata_process_t,1);
-  m_process_t process = xbt_new0(s_m_process_t,1);
+  simdata_process_t simdata = xbt_new0(s_simdata_process_t, 1);
+  m_process_t process = xbt_new0(s_m_process_t, 1);
   xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters");
 
   /* Simulator Data */
   simdata->PID = msg_global->PID++;
-       simdata->waiting_task = NULL;
-  simdata->host = host;
+  simdata->waiting_task = NULL;
+  simdata->m_host = host;
   simdata->argc = argc;
   simdata->argv = argv;
-       simdata->smx_process = SIMIX_process_create(name, (smx_process_code_t)code, (void*)process, host->name, argc, argv, MSG_process_cleanup );
-
-       if (SIMIX_process_self()) {
-               simdata->PPID = MSG_process_get_PID(SIMIX_process_self()->data);
-       }
-       else simdata->PPID = -1;
-  simdata->last_errno=MSG_OK;
+  simdata->s_process = SIMIX_process_create(name, code,
+                                           (void *) process, host->name,
+                                           argc, argv, properties);
+
+  if (SIMIX_process_self()) {
+    simdata->PPID = MSG_process_get_PID(SIMIX_process_self()->data);
+  } else {
+    simdata->PPID = -1;
+  }
+  simdata->last_errno = MSG_OK;
 
 
   /* Process structure */
   process->name = xbt_strdup(name);
   process->simdata = simdata;
-  process->data = data;
+  process->data = data ;
 
-       xbt_fifo_unshift(msg_global->process_list, process); 
+  xbt_fifo_unshift(msg_global->process_list, process);
 
   return process;
+
+}
+
+void _MSG_process_kill_from_SIMIX(void *p)
+{
+  MSG_process_kill((m_process_t) p);
 }
 
 /** \ingroup m_process_management
@@ -134,22 +219,22 @@ void MSG_process_kill(m_process_t process)
 {
   simdata_process_t p_simdata = process->simdata;
 
-  DEBUG3("Killing %s(%ld) on %s",process->name, p_simdata->PID, p_simdata->host->name);
+  DEBUG3("Killing %s(%d) on %s",
+        process->name, p_simdata->PID, p_simdata->m_host->name);
 
-       if(p_simdata->waiting_task) {
-               DEBUG1("Canceling waiting task %s",p_simdata->waiting_task->name);
-    if(p_simdata->waiting_task->simdata->compute) {
-                       SIMIX_action_cancel(p_simdata->waiting_task->simdata->compute);
-               }
-    else if (p_simdata->waiting_task->simdata->comm) {
-                       SIMIX_action_cancel(p_simdata->waiting_task->simdata->comm);
-    } 
+  if (p_simdata->waiting_task) {
+    DEBUG1("Canceling waiting task %s", p_simdata->waiting_task->name);
+    if (p_simdata->waiting_task->simdata->compute) {
+      SIMIX_action_cancel(p_simdata->waiting_task->simdata->compute);
+    } else if (p_simdata->waiting_task->simdata->comm) {
+      SIMIX_action_cancel(p_simdata->waiting_task->simdata->comm);
+    }
   }
 
-  xbt_fifo_remove(msg_global->process_list,process);
-       SIMIX_process_kill(process->simdata->smx_process);
+  xbt_fifo_remove(msg_global->process_list, process);
+  SIMIX_process_kill(process->simdata->s_process);
 
-       return;
+  return;
 }
 
 /** \ingroup m_process_management
@@ -160,7 +245,8 @@ void MSG_process_kill(m_process_t process)
  */
 MSG_error_t MSG_process_change_host(m_process_t process, m_host_t host)
 {
-       xbt_die("MSG_process_change_host - not implemented yet - maybe useless function");
+  xbt_die
+      ("MSG_process_change_host - not implemented yet - maybe useless function");
   return MSG_OK;
 }
 
@@ -183,13 +269,13 @@ void *MSG_process_get_data(m_process_t process)
  * This functions checks whether \a process is a valid pointer or not 
    and set the user data associated to \a process if it is possible.
  */
-MSG_error_t MSG_process_set_data(m_process_t process,void *data)
+MSG_error_t MSG_process_set_data(m_process_t process, void *data)
 {
   xbt_assert0((process != NULL), "Invalid parameters");
   xbt_assert0((process->data == NULL), "Data already set");
-  
+
   process->data = data;
-   
+
   return MSG_OK;
 }
 
@@ -202,9 +288,10 @@ MSG_error_t MSG_process_set_data(m_process_t process,void *data)
  */
 m_host_t MSG_process_get_host(m_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  xbt_assert0(((process != NULL)
+              && (process->simdata)), "Invalid parameters");
 
-  return (((simdata_process_t) process->simdata)->host);
+  return (((simdata_process_t) process->simdata)->m_host);
 }
 
 /** \ingroup m_process_management
@@ -215,13 +302,14 @@ m_host_t MSG_process_get_host(m_process_t process)
    whose PID is equal to \a PID. If no host is found, \c NULL is returned. 
    Note that the PID are uniq in the whole simulation, not only on a given host.
  */
-m_process_t MSG_process_from_PID(long int PID)
+m_process_t MSG_process_from_PID(int PID)
 {
   xbt_fifo_item_t i = NULL;
   m_process_t process = NULL;
 
-  xbt_fifo_foreach(msg_global->process_list,i,process,m_process_t) {
-    if(MSG_process_get_PID(process) == PID) return process;
+  xbt_fifo_foreach(msg_global->process_list, i, process, m_process_t) {
+    if (MSG_process_get_PID(process) == PID)
+      return process;
   }
   return NULL;
 }
@@ -230,11 +318,14 @@ m_process_t MSG_process_from_PID(long int PID)
  * \brief Returns the process ID of \a process.
  *
  * This functions checks whether \a process is a valid pointer or not 
-   and return its PID.
+   and return its PID (or 0 in case of problem).
  */
-long int MSG_process_get_PID(m_process_t process)
+int MSG_process_get_PID(m_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  /* Do not raise an exception here: this function is used in the logs, 
+     and it will be called back by the exception handling stuff */
+  if (process == NULL || process->simdata == NULL)
+    return 0;
 
   return (((simdata_process_t) process->simdata)->PID);
 }
@@ -246,9 +337,10 @@ long int MSG_process_get_PID(m_process_t process)
    and return its PID. Returns -1 if the agent has not been created by 
    another agent.
  */
-long int MSG_process_get_PPID(m_process_t process)
+int MSG_process_get_PPID(m_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  xbt_assert0(((process != NULL)
+              && (process->simdata)), "Invalid parameters");
 
   return (((simdata_process_t) process->simdata)->PPID);
 }
@@ -261,17 +353,43 @@ long int MSG_process_get_PPID(m_process_t process)
  */
 const char *MSG_process_get_name(m_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  xbt_assert0(((process != NULL)
+              && (process->simdata)), "Invalid parameters");
 
   return (process->name);
 }
 
+/** \ingroup m_process_management
+ * \brief Returns the value of a certain process property
+ *
+ * \param process a process
+ * \param name a property name
+ * \return value of a property
+ */
+const char* MSG_process_get_property_value(m_process_t process, char* name)
+{
+  return xbt_dict_get_or_null(MSG_process_get_properties(process), name);
+}
+
+/** \ingroup m_process_management
+ * \brief Return the list of properties
+ *
+ * This functions returns all the parameters associated with a process
+ */
+xbt_dict_t MSG_process_get_properties(m_process_t process)
+{
+   xbt_assert0((process != NULL), "Invalid parameters");
+
+  return (SIMIX_process_get_properties(((simdata_process_t)process->simdata)->s_process));
+
+}
+
 /** \ingroup m_process_management
  * \brief Return the PID of the current agent.
  *
  * This functions returns the PID of the currently running #m_process_t.
  */
-long int MSG_process_self_PID(void)
+int MSG_process_self_PID(void)
 {
   return (MSG_process_get_PID(MSG_process_self()));
 }
@@ -282,7 +400,7 @@ long int MSG_process_self_PID(void)
  * This functions returns the PID of the parent of the currently
  * running #m_process_t.
  */
-long int MSG_process_self_PPID(void)
+int MSG_process_self_PPID(void)
 {
   return (MSG_process_get_PPID(MSG_process_self()));
 }
@@ -294,13 +412,12 @@ long int MSG_process_self_PPID(void)
  */
 m_process_t MSG_process_self(void)
 {
-       smx_process_t proc = SIMIX_process_self();
-       if (proc != NULL) {
-               return (m_process_t)proc->data;
-       }
-       else { 
-               return NULL;
-       }
+  smx_process_t proc = SIMIX_process_self();
+  if (proc != NULL) {
+    return (m_process_t) proc->data;
+  } else {
+    return NULL;
+  }
 
 }
 
@@ -312,10 +429,11 @@ m_process_t MSG_process_self(void)
  */
 MSG_error_t MSG_process_suspend(m_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  xbt_assert0(((process != NULL)
+              && (process->simdata)), "Invalid parameters");
   CHECK_HOST();
 
-       SIMIX_process_suspend(process->simdata->smx_process);
+  SIMIX_process_suspend(process->simdata->s_process);
   MSG_RETURN(MSG_OK);
 }
 
@@ -328,10 +446,11 @@ MSG_error_t MSG_process_suspend(m_process_t process)
 MSG_error_t MSG_process_resume(m_process_t process)
 {
 
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  xbt_assert0(((process != NULL)
+              && (process->simdata)), "Invalid parameters");
   CHECK_HOST();
 
-       SIMIX_process_resume(process->simdata->smx_process);
+  SIMIX_process_resume(process->simdata->s_process);
   MSG_RETURN(MSG_OK);
 }
 
@@ -343,7 +462,7 @@ MSG_error_t MSG_process_resume(m_process_t process)
  */
 int MSG_process_is_suspended(m_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
-       return SIMIX_process_is_suspended(process->simdata->smx_process);
+  xbt_assert0(((process != NULL)
+              && (process->simdata)), "Invalid parameters");
+  return SIMIX_process_is_suspended(process->simdata->s_process);
 }
-