Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MSG/SIMIX Initial files. Only functions prototypes, not implemented yet.
authordonassbr <donassbr@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Wed, 21 Mar 2007 14:51:27 +0000 (14:51 +0000)
committerdonassbr <donassbr@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Wed, 21 Mar 2007 14:51:27 +0000 (14:51 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3323 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/msg_simix/deployment.c [new file with mode: 0644]
src/msg_simix/environment.c [new file with mode: 0644]
src/msg_simix/global.c [new file with mode: 0644]
src/msg_simix/gos.c [new file with mode: 0644]
src/msg_simix/host.c [new file with mode: 0644]
src/msg_simix/m_process.c [new file with mode: 0644]
src/msg_simix/msg_config.c [new file with mode: 0644]
src/msg_simix/private.h [new file with mode: 0644]
src/msg_simix/task.c [new file with mode: 0644]

diff --git a/src/msg_simix/deployment.c b/src/msg_simix/deployment.c
new file mode 100644 (file)
index 0000000..aab4aac
--- /dev/null
@@ -0,0 +1,55 @@
+
+#include "private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+
+
+/** \ingroup msg_easier_life
+ * \brief An application deployer.
+ *
+ * Creates the process described in \a file.
+ * \param file a filename of a xml description of the application. This file 
+ * follows this DTD :
+ *
+ *     \include surfxml.dtd
+ *
+ * Here is a small example of such a platform 
+ *
+ *     \include small_deployment.xml
+ *
+ * Have a look in the directory examples/msg/ to have a bigger example.
+ */
+void MSG_launch_application(const char *file) 
+{
+
+       return;
+}
+
+/** \ingroup msg_easier_life
+ * \brief Registers a #m_process_code_t code in a global table.
+ *
+ * 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.
+ * \param code the function
+ */
+void MSG_function_register(const char *name,m_process_code_t code)
+{
+       return;
+}
+
+/** \ingroup msg_easier_life
+ * \brief Registers a #m_process_t code in a global table.
+ *
+ * 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.
+ */
+m_process_code_t MSG_get_registered_function(const char *name)
+{
+  m_process_code_t code = NULL;
+
+
+  return code;
+}
+
diff --git a/src/msg_simix/environment.c b/src/msg_simix/environment.c
new file mode 100644 (file)
index 0000000..ff3fa42
--- /dev/null
@@ -0,0 +1,48 @@
+
+#include "private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+
+/** \defgroup msg_easier_life      Platform and Application management
+ *  \brief This section describes functions to manage the platform creation
+ *  and the application deployment. You should also have a look at 
+ *  \ref MSG_examples  to have an overview of their usage.
+ *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Platforms and Applications" --> \endhtmlonly
+ * 
+ */
+
+/********************************* MSG **************************************/
+
+/** \ingroup msg_easier_life
+ * \brief A name directory service...
+ *
+ * Finds a m_host_t using its name.
+ * \param name the name of an host.
+ * \return the corresponding host
+ */
+m_host_t MSG_get_host_by_name(const char *name)
+{
+       return NULL;
+}
+
+/** \ingroup msg_easier_life
+ * \brief A platform constructor.
+ *
+ * Creates a new platform, including hosts, links and the
+ * routing_table. 
+ * \param file a filename of a xml description of a platform. This file 
+ * follows this DTD :
+ *
+ *     \include surfxml.dtd
+ *
+ * Here is a small example of such a platform 
+ *
+ *     \include small_platform.xml
+ *
+ * Have a look in the directory examples/msg/ to have a big example.
+ */
+void MSG_create_environment(const char *file) 
+{
+  return;
+}
+
diff --git a/src/msg_simix/global.c b/src/msg_simix/global.c
new file mode 100644 (file)
index 0000000..cdd32d6
--- /dev/null
@@ -0,0 +1,136 @@
+#include "private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+#include "xbt/ex.h" /* ex_backtrace_display */
+
+MSG_Global_t msg_global = NULL;
+
+/* static void MarkAsFailed(m_task_t t, TBX_HashTable_t failedProcessList); */
+/* static xbt_fifo_t MSG_buildFailedHostList(double a, double b); */
+
+/** \defgroup msg_simulation   MSG simulation Functions
+ *  \brief This section describes the functions you need to know to
+ *  set up a simulation. You should have a look at \ref MSG_examples 
+ *  to have an overview of their usage.
+ *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Simulation functions" --> \endhtmlonly
+ */
+
+/********************************* MSG **************************************/
+
+/** \ingroup msg_simulation
+ * \brief Initialize some MSG internal data.
+ */
+void MSG_global_init_args(int *argc, char **argv)
+{
+  MSG_global_init(argc,argv);
+}
+
+/** \ingroup msg_simulation
+ * \brief Initialize some MSG internal data.
+ */
+void MSG_global_init(int *argc, char **argv)
+{
+       return;
+
+}
+
+/** \ingroup msg_easier_life
+ * \brief Traces MSG events in the Paje format.
+ */
+void MSG_paje_output(const char *filename)
+{
+       return;
+}
+
+/** \defgroup m_channel_management    Understanding channels
+ *  \brief This section briefly describes the channel notion of MSG
+ *  (#m_channel_t).
+ *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Channels" --> \endhtmlonly
+ * 
+ *
+ *  For convenience, the simulator provides the notion of channel
+ *  that is close to the tag notion in MPI. A channel is not a
+ *  socket. It doesn't need to be opened neither closed. It rather
+ *  corresponds to the ports opened on the different machines.
+ */
+
+
+/** \ingroup m_channel_management
+ * \brief Set the number of channel in the simulation.
+ *
+ * This function has to be called to fix the number of channel in the
+   simulation before creating any host. Indeed, each channel is
+   represented by a different mailbox on each #m_host_t. This
+   function can then be called only once. This function takes only one
+   parameter.
+ * \param number the number of channel in the simulation. It has to be >0
+ */
+MSG_error_t MSG_set_channel_number(int number)
+{
+
+  return MSG_OK;
+}
+
+/** \ingroup m_channel_management
+ * \brief Return the number of channel in the simulation.
+ *
+ * This function has to be called once the number of channel is fixed. I can't 
+   figure out a reason why anyone would like to call this function but nevermind.
+ * \return the number of channel in the simulation.
+ */
+int MSG_get_channel_number(void)
+{
+       return 0;
+}
+
+void __MSG_display_process_status(void)
+{
+}
+
+/* FIXME: Yeah, I'll do it in a portable maner one day [Mt] */
+#include <signal.h>
+
+static void _XBT_CALL inthandler(int ignored)
+{
+   INFO0("CTRL-C pressed. Displaying status and bailing out");
+   __MSG_display_process_status();
+   exit(1);
+}
+
+/** \ingroup msg_simulation
+ * \brief Launch the MSG simulation
+ */
+MSG_error_t MSG_main(void)
+{
+  return MSG_OK;
+}
+
+/** \ingroup msg_simulation
+ * \brief Kill all running process
+
+ * \param reset_PIDs should we reset the PID numbers. A negative
+ *   number means no reset and a positive number will be used to set the PID
+ *   of the next newly created process.
+ */
+int MSG_process_killall(int reset_PIDs)
+{
+  return 0;
+}
+
+/** \ingroup msg_simulation
+ * \brief Clean the MSG simulation
+ */
+MSG_error_t MSG_clean(void)
+{
+  return MSG_OK;
+}
+
+
+/** \ingroup msg_easier_life
+ * \brief A clock (in second).
+ */
+double MSG_get_clock(void) 
+{
+       return 0.0;
+}
+
diff --git a/src/msg_simix/gos.c b/src/msg_simix/gos.c
new file mode 100644 (file)
index 0000000..cdf0e18
--- /dev/null
@@ -0,0 +1,343 @@
+#include "private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+
+/** \defgroup msg_gos_functions MSG Operating System Functions
+ *  \brief This section describes the functions that can be used
+ *  by an agent for handling some task.
+ */
+
+static MSG_error_t __MSG_task_get_with_time_out_from_host(m_task_t * task,
+                                                       m_channel_t channel,
+                                                       double max_duration,
+                                                       m_host_t host)
+{
+
+       MSG_RETURN(MSG_OK);
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Listen on a channel and wait for receiving a task.
+ *
+ * It takes two parameters.
+ * \param task a memory location for storing a #m_task_t. It will
+   hold a task when this function will return. Thus \a task should not
+   be equal to \c NULL and \a *task should be equal to \c NULL. If one of
+   those two condition does not hold, there will be a warning message.
+ * \param channel the channel on which the agent should be
+   listening. This value has to be >=0 and < than the maximal
+   number of channels fixed with MSG_set_channel_number().
+ * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
+ * if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
+ */
+MSG_error_t MSG_task_get(m_task_t * task,
+                        m_channel_t channel)
+{
+  return MSG_task_get_with_time_out(task, channel, -1);
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Listen on a channel and wait for receiving a task with a timeout.
+ *
+ * It takes three parameters.
+ * \param task a memory location for storing a #m_task_t. It will
+   hold a task when this function will return. Thus \a task should not
+   be equal to \c NULL and \a *task should be equal to \c NULL. If one of
+   those two condition does not hold, there will be a warning message.
+ * \param channel the channel on which the agent should be
+   listening. This value has to be >=0 and < than the maximal
+   number of channels fixed with MSG_set_channel_number().
+ * \param max_duration the maximum time to wait for a task before giving
+    up. In such a case, #MSG_TRANSFER_FAILURE will be returned, \a task 
+    will not be modified and will still be
+    equal to \c NULL when returning. 
+ * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
+   if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
+ */
+MSG_error_t MSG_task_get_with_time_out(m_task_t * task,
+                                      m_channel_t channel,
+                                      double max_duration)
+{
+  return __MSG_task_get_with_time_out_from_host(task, channel, max_duration, NULL);
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Listen on \a channel and waits for receiving a task from \a host.
+ *
+ * It takes three parameters.
+ * \param task a memory location for storing a #m_task_t. It will
+   hold a task when this function will return. Thus \a task should not
+   be equal to \c NULL and \a *task should be equal to \c NULL. If one of
+   those two condition does not hold, there will be a warning message.
+ * \param channel the channel on which the agent should be
+   listening. This value has to be >=0 and < than the maximal
+   number of channels fixed with MSG_set_channel_number().
+ * \param host the host that is to be watched.
+ * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
+   if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
+ */
+MSG_error_t MSG_task_get_from_host(m_task_t * task, int channel, 
+                                  m_host_t host)
+{
+  return __MSG_task_get_with_time_out_from_host(task, channel, -1, host);
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Test whether there is a pending communication on a channel.
+ *
+ * It takes one parameter.
+ * \param channel the channel on which the agent should be
+   listening. This value has to be >=0 and < than the maximal
+   number of channels fixed with MSG_set_channel_number().
+ * \return 1 if there is a pending communication and 0 otherwise
+ */
+int MSG_task_Iprobe(m_channel_t channel)
+{
+       return 0;
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Test whether there is a pending communication on a channel, and who sent it.
+ *
+ * It takes one parameter.
+ * \param channel the channel on which the agent should be
+   listening. This value has to be >=0 and < than the maximal
+   number of channels fixed with MSG_set_channel_number().
+ * \return -1 if there is no pending communication and the PID of the process who sent it otherwise
+ */
+int MSG_task_probe_from(m_channel_t channel)
+{
+       return 0;
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Wait for at most \a max_duration second for a task reception
+   on \a channel. *\a PID is updated with the PID of the first process
+   that triggered this event if any.
+ *
+ * It takes three parameters:
+ * \param channel the channel on which the agent should be
+   listening. This value has to be >=0 and < than the maximal.
+   number of channels fixed with MSG_set_channel_number().
+ * \param PID a memory location for storing an int.
+ * \param max_duration the maximum time to wait for a task before
+    giving up. In the case of a reception, *\a PID will be updated
+    with the PID of the first process to send a task.
+ * \return #MSG_HOST_FAILURE if the host is shut down in the meantime
+   and #MSG_OK otherwise.
+ */
+MSG_error_t MSG_channel_select_from(m_channel_t channel, double max_duration,
+                                   int *PID)
+{
+       MSG_RETURN(MSG_OK);
+}
+
+
+/** \ingroup msg_gos_functions
+
+ * \brief Return the number of tasks waiting to be received on a \a
+   channel and sent by \a host.
+ *
+ * It takes two parameters.
+ * \param channel the channel on which the agent should be
+   listening. This value has to be >=0 and < than the maximal
+   number of channels fixed with MSG_set_channel_number().
+ * \param host the host that is to be watched.
+ * \return the number of tasks waiting to be received on \a channel
+   and sent by \a host.
+ */
+int MSG_task_probe_from_host(int channel, m_host_t host)
+{
+       return 0;
+}
+
+/** \ingroup msg_gos_functions \brief Put a task on a channel of an
+ * host (with a timeout on the waiting of the destination host) and
+ * waits for the end of the transmission.
+ *
+ * This function is used for describing the behavior of an agent. It
+ * takes four parameter.
+ * \param task a #m_task_t to send on another location. This task
+   will not be usable anymore when the function will return. There is
+   no automatic task duplication and you have to save your parameters
+   before calling this function. Tasks are unique and once it has been
+   sent to another location, you should not access it anymore. You do
+   not need to call MSG_task_destroy() but to avoid using, as an
+   effect of inattention, this task anymore, you definitely should
+   renitialize it with #MSG_TASK_UNINITIALIZED. Note that this task
+   can be transfered iff it has been correctly created with
+   MSG_task_create().
+ * \param dest the destination of the message
+ * \param channel the channel on which the agent should put this
+   task. This value has to be >=0 and < than the maximal number of
+   channels fixed with MSG_set_channel_number().
+ * \param max_duration the maximum time to wait for a task before giving
+    up. In such a case, #MSG_TRANSFER_FAILURE will be returned, \a task 
+    will not be modified 
+ * \return #MSG_FATAL if \a task is not properly initialized and
+   #MSG_OK otherwise. Returns #MSG_HOST_FAILURE if the host on which
+   this function was called was shut down. Returns
+   #MSG_TRANSFER_FAILURE if the transfer could not be properly done
+   (network failure, dest failure, timeout...)
+ */
+MSG_error_t MSG_task_put_with_timeout(m_task_t task, m_host_t dest, 
+                                     m_channel_t channel, double max_duration)
+{
+       MSG_RETURN(MSG_OK);
+}
+/** \ingroup msg_gos_functions
+ * \brief Put a task on a channel of an host and waits for the end of the
+ * transmission.
+ *
+ * This function is used for describing the behavior of an agent. It
+ * takes three parameter.
+ * \param task a #m_task_t to send on another location. This task
+   will not be usable anymore when the function will return. There is
+   no automatic task duplication and you have to save your parameters
+   before calling this function. Tasks are unique and once it has been
+   sent to another location, you should not access it anymore. You do
+   not need to call MSG_task_destroy() but to avoid using, as an
+   effect of inattention, this task anymore, you definitely should
+   renitialize it with #MSG_TASK_UNINITIALIZED. Note that this task
+   can be transfered iff it has been correctly created with
+   MSG_task_create().
+ * \param dest the destination of the message
+ * \param channel the channel on which the agent should put this
+   task. This value has to be >=0 and < than the maximal number of
+   channels fixed with MSG_set_channel_number().
+ * \return #MSG_FATAL if \a task is not properly initialized and
+ * #MSG_OK otherwise. Returns #MSG_HOST_FAILURE if the host on which
+ * this function was called was shut down. Returns
+ * #MSG_TRANSFER_FAILURE if the transfer could not be properly done
+ * (network failure, dest failure)
+ */
+MSG_error_t MSG_task_put(m_task_t task,
+                        m_host_t dest, m_channel_t channel)
+{
+  return MSG_task_put_with_timeout(task, dest, channel, -1.0);
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Does exactly the same as MSG_task_put but with a bounded transmition 
+ * rate.
+ *
+ * \sa MSG_task_put
+ */
+MSG_error_t MSG_task_put_bounded(m_task_t task,
+                                m_host_t dest, m_channel_t channel,
+                                double max_rate)
+{
+  MSG_error_t res = MSG_OK;
+  task->simdata->rate=max_rate;
+  res = MSG_task_put(task, dest, channel);
+  return(res);
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Executes a task and waits for its termination.
+ *
+ * This function is used for describing the behavior of an agent. It
+ * takes only one parameter.
+ * \param task a #m_task_t to execute on the location on which the
+   agent is running.
+ * \return #MSG_FATAL if \a task is not properly initialized and
+ * #MSG_OK otherwise.
+ */
+MSG_error_t MSG_task_execute(m_task_t task)
+{
+       MSG_RETURN(MSG_OK);
+}
+
+void __MSG_task_execute(m_process_t process, m_task_t task)
+{
+
+}
+
+MSG_error_t __MSG_wait_for_computation(m_process_t process, m_task_t task)
+{
+       MSG_RETURN(MSG_OK);
+}
+/** \ingroup m_task_management
+ * \brief Creates a new #m_task_t (a parallel one....).
+ *
+ * A constructor for #m_task_t taking six arguments and returning the 
+   corresponding object.
+ * \param name a name for the object. It is for user-level information
+   and can be NULL.
+ * \param host_nb the number of hosts implied in the parallel task.
+ * \param host_list an array of \p host_nb m_host_t.
+ * \param computation_amount an array of \p host_nb
+   doubles. computation_amount[i] is the total number of operations
+   that have to be performed on host_list[i].
+ * \param communication_amount an array of \p host_nb* \p host_nb doubles.
+ * \param data a pointer to any data 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_task_get_data.
+ * \see m_task_t
+ * \return The new corresponding object.
+ */
+m_task_t MSG_parallel_task_create(const char *name, 
+                                 int host_nb,
+                                 const m_host_t *host_list,
+                                 double *computation_amount,
+                                 double *communication_amount,
+                                 void *data)
+{
+  m_task_t task = xbt_new0(s_m_task_t,1);
+  return task;
+}
+
+
+static void __MSG_parallel_task_execute(m_process_t process, m_task_t task)
+{
+       return;
+}
+
+MSG_error_t MSG_parallel_task_execute(m_task_t task)
+{
+  m_process_t process = MSG_process_self();
+  MSG_error_t res;
+
+  DEBUG0("Computing on a tons of guys");
+  
+  __MSG_parallel_task_execute(process, task);
+
+  if(task->simdata->compute)
+    res = __MSG_wait_for_computation(process,task);
+  else 
+    res = MSG_OK;
+
+  return res;  
+}
+
+
+/** \ingroup msg_gos_functions
+ * \brief Sleep for the specified number of seconds
+ *
+ * Makes the current process sleep until \a time seconds have elapsed.
+ *
+ * \param nb_sec a number of second
+ */
+MSG_error_t MSG_process_sleep(double nb_sec)
+{
+       MSG_RETURN(MSG_OK);
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Return the number of MSG tasks currently running on
+ * the host of the current running process.
+ */
+static int MSG_get_msgload(void) 
+{
+       return 0;
+}
+
+/** \ingroup msg_gos_functions
+ *
+ * \brief Return the last value returned by a MSG function (except
+ * MSG_get_errno...).
+ */
+MSG_error_t MSG_get_errno(void)
+{
+  return PROCESS_GET_ERRNO();
+}
diff --git a/src/msg_simix/host.c b/src/msg_simix/host.c
new file mode 100644 (file)
index 0000000..9217491
--- /dev/null
@@ -0,0 +1,145 @@
+#include "private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+
+/** \defgroup m_host_management Management functions of Hosts
+ *  \brief This section describes the host structure of MSG
+ * 
+ *     \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Hosts" --> \endhtmlonly
+ * (#m_host_t) and the functions for managing it.
+ *  
+ *  A <em>location</em> (or <em>host</em>) is any possible place where
+ *  a process may run. Thus it may be represented as a
+ *  <em>physical resource with computing capabilities</em>, some
+ *  <em>mailboxes</em> to enable running process to communicate with
+ *  remote ones, and some <em>private data</em> that can be only
+ *  accessed by local process.
+ *  \see m_host_t
+ */
+
+/********************************* Host **************************************/
+m_host_t __MSG_host_create(const char *name,
+                        void *workstation,
+                        void *data)
+{
+  m_host_t host = xbt_new0(s_m_host_t,1);
+
+  return host;
+}
+
+/** \ingroup m_host_management
+ *
+ * \brief Set the user data of a #m_host_t.
+ *
+ * This functions checks whether some data has already been associated to \a host 
+   or not and attach \a data to \a host if it is possible.
+ */
+MSG_error_t MSG_host_set_data(m_host_t host, void *data)
+{
+  xbt_assert0((host!=NULL), "Invalid parameters");
+  xbt_assert0((host->data == NULL), "Data already set");
+
+  /* Assign data */
+  host->data = data;
+
+  return MSG_OK;
+}
+
+/** \ingroup m_host_management
+ *
+ * \brief Return the user data of a #m_host_t.
+ *
+ * This functions checks whether \a host is a valid pointer or not and return
+   the user data associated to \a host if it is possible.
+ */
+void *MSG_host_get_data(m_host_t host)
+{
+
+  xbt_assert0((host != NULL), "Invalid parameters");
+
+  /* Return data */
+  return (host->data);
+}
+
+/** \ingroup m_host_management
+ *
+ * \brief Return the name of the #m_host_t.
+ *
+ * This functions checks whether \a host is a valid pointer or not and return
+   its name.
+ */
+const char *MSG_host_get_name(m_host_t host)
+{
+
+  xbt_assert0((host != NULL) && (host->simdata != NULL), "Invalid parameters");
+
+  /* Return data */
+  return (host->name);
+}
+
+/** \ingroup m_host_management
+ *
+ * \brief Return the location on which the current process is executed.
+ */
+m_host_t MSG_host_self(void)
+{
+  return MSG_process_get_host(MSG_process_self());
+}
+
+/*
+ * Real function for destroy a host.
+ * MSG_host_destroy is just  a front_end that also removes it from 
+ * msg_global->host
+ */
+void __MSG_host_destroy(m_host_t host)
+{
+  return;
+}
+
+/** \ingroup m_host_management
+ * \brief Return the current number of #m_host_t.
+ */
+int MSG_get_host_number(void)
+{
+  return (xbt_fifo_size(msg_global->host));
+}
+
+/** \ingroup m_host_management
+ * \brief Return a array of all the #m_host_t.
+ */
+m_host_t *MSG_get_host_table(void)
+{
+  return ((m_host_t *)xbt_fifo_to_array(msg_global->host));
+}
+
+/** \ingroup m_host_management
+ * \brief Return the number of MSG tasks currently running on a
+ * #m_host_t. The external load is not taken in account.
+ */
+int MSG_get_host_msgload(m_host_t h)
+{
+  xbt_assert0((h!= NULL), "Invalid parameters");
+  xbt_assert0(0, "Not implemented yet");
+
+  return(0);
+/*   return(surf_workstation_resource->extension_public->get_load(h->simdata->host)); */
+}
+
+/** \ingroup m_host_management
+ * \brief Return the speed of the processor (in flop/s), regardless of 
+    the current load on the machine.
+ */
+double MSG_get_host_speed(m_host_t h)
+{
+       return 0.0;
+}
+
+/** \ingroup msg_gos_functions
+ * \brief Determine if a host is available.
+ *
+ * \param h host to test
+ */
+int MSG_host_is_avail (m_host_t h)
+{
+       return 0;
+}
diff --git a/src/msg_simix/m_process.c b/src/msg_simix/m_process.c
new file mode 100644 (file)
index 0000000..4641f0c
--- /dev/null
@@ -0,0 +1,265 @@
+
+#include "private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+
+/** \defgroup m_process_management Management Functions of Agents
+ *  \brief This section describes the agent structure of MSG
+ *  (#m_process_t) and the functions for managing it.
+ *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Agents" --> \endhtmlonly
+ * 
+ *  We need to simulate many independent scheduling decisions, so
+ *  the concept of <em>process</em> is at the heart of the
+ *  simulator. A process may be defined as a <em>code</em>, with
+ *  some <em>private data</em>, executing in a <em>location</em>.
+ *  \see m_process_t
+ */
+
+/******************************** Process ************************************/
+/** \ingroup m_process_management
+ * \brief Creates and runs a new #m_process_t.
+ *
+ * Does exactly the same as #MSG_process_create_with_arguments but without 
+   providing standard arguments (\a argc, \a argv, \a start_time, \a kill_time).
+ * \sa MSG_process_create_with_arguments
+ */
+m_process_t MSG_process_create(const char *name,
+                              m_process_code_t code, void *data,
+                              m_host_t host)
+{
+  return MSG_process_create_with_arguments(name, code, data, host, -1, NULL);
+}
+
+static void MSG_process_cleanup(void *arg)
+{
+       return;
+}
+
+/** \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
+ * \see m_process_t
+ * \return The new corresponding object.
+ */
+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)
+{
+  m_process_t process = xbt_new0(s_m_process_t,1);
+   return process;
+}
+
+/** \ingroup m_process_management
+ * \param process poor victim
+ *
+ * This function simply kills a \a process... scarry isn't it ? :)
+ */
+void MSG_process_kill(m_process_t process)
+{
+       return;
+}
+
+/** \ingroup m_process_management
+ * \brief Migrates an agent to another location.
+ *
+ * This functions checks whether \a process and \a host are valid pointers
+   and change the value of the #m_host_t on which \a process is running.
+ */
+MSG_error_t MSG_process_change_host(m_process_t process, m_host_t host)
+{
+  return MSG_OK;
+}
+
+/** \ingroup m_process_management
+ * \brief Return the user data of a #m_process_t.
+ *
+ * This functions checks whether \a process is a valid pointer or not 
+   and return the user data associated to \a process if it is possible.
+ */
+void *MSG_process_get_data(m_process_t process)
+{
+  xbt_assert0((process != NULL), "Invalid parameters");
+
+  return (process->data);
+}
+
+/** \ingroup m_process_management
+ * \brief Set the user data of a #m_process_t.
+ *
+ * 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)
+{
+  xbt_assert0((process != NULL), "Invalid parameters");
+  xbt_assert0((process->data == NULL), "Data already set");
+  
+  process->data = data;
+   
+  return MSG_OK;
+}
+
+/** \ingroup m_process_management
+ * \brief Return the location on which an agent is running.
+ *
+ * This functions checks whether \a process is a valid pointer or not 
+   and return the m_host_t corresponding to the location on which \a 
+   process is running.
+ */
+m_host_t MSG_process_get_host(m_process_t process)
+{
+  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+
+  return (((simdata_process_t) process->simdata)->host);
+}
+
+/** \ingroup m_process_management
+ *
+ * \brief Return a #m_process_t given its PID.
+ *
+ * This functions search in the list of all the created m_process_t for a m_process_t 
+   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(int PID)
+{
+
+  return NULL;
+}
+
+/** \ingroup m_process_management
+ * \brief Returns the process ID of \a process.
+ *
+ * This functions checks whether \a process is a valid pointer or not 
+   and return its PID.
+ */
+int MSG_process_get_PID(m_process_t process)
+{
+  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+
+  return (((simdata_process_t) process->simdata)->PID);
+}
+
+/** \ingroup m_process_management
+ * \brief Returns the process ID of the parent of \a process.
+ *
+ * This functions checks whether \a process is a valid pointer or not 
+   and return its PID. Returns -1 if the agent has not been created by 
+   another agent.
+ */
+int MSG_process_get_PPID(m_process_t process)
+{
+  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+
+  return (((simdata_process_t) process->simdata)->PPID);
+}
+
+/** \ingroup m_process_management
+ * \brief Return the name of an agent.
+ *
+ * This functions checks whether \a process is a valid pointer or not 
+   and return its name.
+ */
+const char *MSG_process_get_name(m_process_t process)
+{
+  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+
+  return (process->name);
+}
+
+/** \ingroup m_process_management
+ * \brief Return the PID of the current agent.
+ *
+ * This functions returns the PID of the currently running #m_process_t.
+ */
+int MSG_process_self_PID(void)
+{
+  return (MSG_process_get_PID(MSG_process_self()));
+}
+
+/** \ingroup m_process_management
+ * \brief Return the PPID of the current agent.
+ *
+ * This functions returns the PID of the parent of the currently
+ * running #m_process_t.
+ */
+int MSG_process_self_PPID(void)
+{
+  return (MSG_process_get_PPID(MSG_process_self()));
+}
+
+/** \ingroup m_process_management
+ * \brief Return the current agent.
+ *
+ * This functions returns the currently running #m_process_t.
+ */
+m_process_t MSG_process_self(void)
+{
+       return NULL;
+}
+
+/** \ingroup m_process_management
+ * \brief Suspend the process.
+ *
+ * This functions suspend the process by suspending the task on which
+ * it was waiting for the completion.
+ */
+MSG_error_t MSG_process_suspend(m_process_t process)
+{
+   return MSG_OK;
+}
+
+/** \ingroup m_process_management
+ * \brief Resume a suspended process.
+ *
+ * This functions resume a suspended process by resuming the task on
+ * which it was waiting for the completion.
+ */
+MSG_error_t MSG_process_resume(m_process_t process)
+{
+       MSG_RETURN(MSG_OK);
+}
+
+/** \ingroup m_process_management
+ * \brief Returns true if the process is suspended .
+ *
+ * This checks whether a process is suspended or not by inspecting the
+ * task on which it was waiting for the completion.
+ */
+int MSG_process_is_suspended(m_process_t process)
+{
+ return 0;
+}
+
+int __MSG_process_block(double max_duration, const char *info)
+{
+    return 1;
+}
+
+MSG_error_t __MSG_process_unblock(m_process_t process)
+{
+    MSG_RETURN(MSG_OK);
+}
+
+int __MSG_process_isBlocked(m_process_t process)
+{
+       return 0;
+}
diff --git a/src/msg_simix/msg_config.c b/src/msg_simix/msg_config.c
new file mode 100644 (file)
index 0000000..37c81ca
--- /dev/null
@@ -0,0 +1,20 @@
+
+#include "private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+
+/** \brief set a configuration variable
+ * 
+ * Currently existing configuation variable:
+ *   - surf_workstation_model (string): Model of workstation to use.  
+ *     Possible values (defaults to "KCCFLN05"):
+ *     - "CLM03": realistic TCP behavior + basic CPU model (see [CML03 at CCGrid03]) + support for parallel tasks
+ *     - "KCCFLN05": realistic TCP behavior + basic CPU model (see [CML03 at CCGrid03]) + failure handling + interference between communications and computations if precised in the platform file.
+ * 
+ * Example:
+ * MSG_config("surf_workstation_model","KCCFLN05");
+ */
+void MSG_config(const char *name, ...) 
+{
+       return;
+}
diff --git a/src/msg_simix/private.h b/src/msg_simix/private.h
new file mode 100644 (file)
index 0000000..d4b9d6e
--- /dev/null
@@ -0,0 +1,176 @@
+/*     $Id$     */
+
+/* Copyright (c) 2002,2004,2004 Arnaud Legrand. 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. */
+
+#ifndef METASIMGRID_PRIVATE_H
+#define METASIMGRID_PRIVATE_H
+
+#include "msg/msg.h"
+#include "surf/surf.h"
+#include "xbt/fifo.h"
+#include "xbt/dynar.h"
+#include "xbt/swag.h"
+#include "xbt/dict.h"
+#include "xbt/context.h"
+#include "xbt/config.h"
+#include "xbt/mallocator.h"
+
+/**************** datatypes **********************************/
+
+typedef struct simdata_host {
+  void *host;                  /* SURF modeling */
+  xbt_fifo_t *mbox;            /* array of FIFOs used as a mailboxes  */
+  m_process_t *sleeping;       /* array of process used to know whether a local process is
+                                  waiting for a communication on a channel */
+  xbt_fifo_t process_list;
+} s_simdata_host_t;
+
+/********************************* Task **************************************/
+
+typedef struct simdata_task {
+  surf_action_t compute;       /* SURF modeling of computation  */
+  surf_action_t comm;          /* SURF modeling of communication  */
+  double message_size;         /* Data size  */
+  double computation_amount;   /* Computation size  */
+  xbt_dynar_t sleeping;                /* process to wake-up */
+  m_process_t sender;
+  m_host_t source;
+  double priority;
+  double rate;
+  int using;
+  /*******  Parallel Tasks Only !!!! *******/
+  int host_nb;
+  void * *host_list;            /* SURF modeling */
+  double *comp_amount;
+  double *comm_amount;
+} s_simdata_task_t;
+
+/******************************* Process *************************************/
+
+typedef struct simdata_process {
+  m_host_t host;                /* the host on which the process is running */
+  xbt_context_t context;               /* the context that executes the scheduler fonction */
+  int PID;                     /* used for debugging purposes */
+  int PPID;                    /* The parent PID */
+  m_task_t waiting_task;        
+  int blocked;
+  int suspended;
+  m_host_t put_host;           /* used for debugging purposes */
+  m_channel_t put_channel;     /* used for debugging purposes */
+  int argc;                     /* arguments number if any */
+  char **argv;                  /* arguments table if any */
+  MSG_error_t last_errno;       /* the last value returned by a MSG_function */
+  int paje_state;               /* the number of states stacked with Paje */
+} s_simdata_process_t;
+
+typedef struct process_arg {
+  const char *name;
+  m_process_code_t code;
+  void *data;
+  m_host_t host;
+  int argc;
+  char **argv;
+  double kill_time;
+} s_process_arg_t, *process_arg_t;
+
+/************************** Global variables ********************************/
+typedef struct MSG_Global {
+  xbt_fifo_t host;
+  xbt_fifo_t process_to_run;
+  xbt_fifo_t process_list;
+  int max_channel;
+  m_process_t current_process;
+  xbt_dict_t registered_functions;
+  FILE *paje_output;
+  int paje_maxPID;
+  int PID;
+  int session;
+  xbt_mallocator_t task_mallocator;
+  xbt_mallocator_t task_simdata_mallocator;
+} s_MSG_Global_t, *MSG_Global_t;
+
+extern MSG_Global_t msg_global;
+      
+/************************** Configuration support ********************************/
+void msg_config_init(void); /* create the config set, call this before use! */
+void msg_config_finalize(void); /* destroy the config set, call this at cleanup. */
+extern int _msg_init_status; /* 0: beginning of time; 
+                                1: pre-inited (cfg_set created); 
+                                2: inited (running) */
+extern xbt_cfg_t _msg_cfg_set;
+
+/*************************************************************/
+
+#define PROCESS_SET_ERRNO(val) (MSG_process_self()->simdata->last_errno=val)
+#define PROCESS_GET_ERRNO() (MSG_process_self()->simdata->last_errno)
+#define MSG_RETURN(val) do {PROCESS_SET_ERRNO(val);return(val);} while(0)
+/* #define CHECK_ERRNO()  ASSERT((PROCESS_GET_ERRNO()!=MSG_HOST_FAILURE),"Host failed, you cannot call this function.") */
+
+#define CHECK_HOST()  xbt_assert0(surf_workstation_resource->extension_public-> \
+                                 get_state(MSG_host_self()->simdata->host)==SURF_CPU_ON,\
+                                  "Host failed, you cannot call this function.")
+
+m_host_t __MSG_host_create(const char *name, void *workstation,
+                          void *data);
+void __MSG_host_destroy(m_host_t host);
+void __MSG_task_execute(m_process_t process, m_task_t task);
+MSG_error_t __MSG_wait_for_computation(m_process_t process, m_task_t task);
+MSG_error_t __MSG_task_wait_event(m_process_t process, m_task_t task);
+
+int __MSG_process_block(double max_duration, const char *info);
+MSG_error_t __MSG_process_unblock(m_process_t process);
+int __MSG_process_isBlocked(m_process_t process);
+
+void __MSG_display_process_status(void);
+
+m_task_t task_mallocator_new_f(void);
+void task_mallocator_free_f(m_task_t task);
+void task_mallocator_reset_f(m_task_t task);
+
+
+
+#define PAJE_PROCESS_STATE(process,state)\
+  if(msg_global->paje_output) \
+    fprintf(msg_global->paje_output,"10 %f S_t %p %s\n",\
+            surf_get_clock(), (process),(state))
+#define PAJE_PROCESS_PUSH_STATE(process,state,task)\
+  if(msg_global->paje_output) \
+    fprintf(msg_global->paje_output,"11 %f S_t %p %s \"%s\"\n",\
+            surf_get_clock(), (process),(state),(task)?((m_task_t)(task))->name:" ")
+#define PAJE_PROCESS_POP_STATE(process)\
+  if(msg_global->paje_output) \
+    fprintf(msg_global->paje_output,"12 %f S_t %p\n",\
+            surf_get_clock(), (process))
+
+#define PAJE_PROCESS_FREE(process)\
+  if(msg_global->paje_output) \
+    fprintf(msg_global->paje_output,"8 %f %p P_t\n", \
+           surf_get_clock(), (process))
+#define PAJE_PROCESS_NEW(process)\
+  if(msg_global->paje_output) \
+    fprintf(msg_global->paje_output,"7 %f %p P_t %p \"%s %d (%d)\"\n", \
+            surf_get_clock(), (process), (process)->simdata->host, \
+            (process)->name, (process)->simdata->PID, msg_global->session)
+#define PAJE_COMM_START(process,task,channel)\
+  if(msg_global->paje_output) \
+    fprintf(msg_global->paje_output,\
+           "16 %f      Comm    CUR     \"CHANNEL_%d %s\"       %p      %p\n", \
+            surf_get_clock(), channel, task->name, (process), task)
+#define PAJE_COMM_STOP(process,task,channel)\
+  if(msg_global->paje_output) \
+    fprintf(msg_global->paje_output,\
+           "17 %f      Comm    CUR     \"CHANNEL_%d %s\"       %p      %p\n", \
+            surf_get_clock(), channel, task->name, (process), task)
+#define PAJE_HOST_NEW(host)\
+  if(msg_global->paje_output)\
+    fprintf(msg_global->paje_output,"7 %f %p H_t CUR \"%s\"\n",surf_get_clock(), \
+           host, host->name)
+#define PAJE_HOST_FREE(host)\
+  if(msg_global->paje_output)\
+    fprintf(msg_global->paje_output,"8 %f %p H_t\n",surf_get_clock(), host);
+
+
+#endif
diff --git a/src/msg_simix/task.c b/src/msg_simix/task.c
new file mode 100644 (file)
index 0000000..b166e7e
--- /dev/null
@@ -0,0 +1,183 @@
+#include "private.h"
+#include "xbt/sysdep.h"
+#include "xbt/log.h"
+
+/** \defgroup m_task_management Managing functions of Tasks
+ *  \brief This section describes the task structure of MSG
+ *  (#m_task_t) and the functions for managing it.
+ *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Tasks" --> \endhtmlonly
+ * 
+ *  Since most scheduling algorithms rely on a concept of task
+ *  that can be either <em>computed</em> locally or
+ *  <em>transferred</em> on another processor, it seems to be the
+ *  right level of abstraction for our purposes. A <em>task</em>
+ *  may then be defined by a <em>computing amount</em>, a
+ *  <em>message size</em> and some <em>private data</em>.
+ */
+
+/********************************* Task **************************************/
+/** \ingroup m_task_management
+ * \brief Creates a new #m_task_t.
+ *
+ * A constructor for #m_task_t taking four arguments and returning the 
+   corresponding object.
+ * \param name a name for the object. It is for user-level information
+   and can be NULL.
+ * \param compute_duration a value of the processing amount (in flop)
+   needed to process this new task. If 0, then it cannot be executed with
+   MSG_task_execute(). This value has to be >=0.
+ * \param message_size a value of the amount of data (in bytes) needed to
+   transfer this new task. If 0, then it cannot be transfered with
+   MSG_task_get() and MSG_task_put(). This value has to be >=0.
+ * \param data a pointer to any data 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_task_get_data.
+ * \see m_task_t
+ * \return The new corresponding object.
+ */
+m_task_t MSG_task_create(const char *name, double compute_duration,
+                        double message_size, void *data)
+{
+  m_task_t task = xbt_mallocator_get(msg_global->task_mallocator);
+
+  return task;
+}
+
+/** \ingroup m_task_management
+ * \brief Return the user data of a #m_task_t.
+ *
+ * This functions checks whether \a task is a valid pointer or not and return
+   the user data associated to \a task if it is possible.
+ */
+void *MSG_task_get_data(m_task_t task)
+{
+  xbt_assert0((task != NULL), "Invalid parameter");
+
+  return (task->data);
+}
+
+/** \ingroup m_task_management
+ * \brief Return the sender of a #m_task_t.
+ *
+ * This functions returns the #m_process_t which sent this task
+ */
+m_process_t MSG_task_get_sender(m_task_t task)
+{
+   xbt_assert0(task, "Invalid parameters");
+   return ((simdata_task_t) task->simdata)->sender;
+}
+
+/** \ingroup m_task_management
+ * \brief Return the source of a #m_task_t.
+ *
+ * This functions returns the #m_host_t from which this task was sent
+ */
+m_host_t MSG_task_get_source(m_task_t task)
+{
+   xbt_assert0(task, "Invalid parameters");
+   return ((simdata_task_t) task->simdata)->source;
+}
+
+/** \ingroup m_task_management
+ * \brief Return the name of a #m_task_t.
+ *
+ * This functions returns the name of a #m_task_t as specified on creation
+ */
+const char *MSG_task_get_name(m_task_t task)
+{
+   xbt_assert0(task, "Invalid parameters");
+   return task->name;
+}
+
+
+/** \ingroup m_task_management
+ * \brief Destroy a #m_task_t.
+ *
+ * Destructor for #m_task_t. Note that you should free user data, if any, \b 
+   before calling this function.
+ */
+MSG_error_t MSG_task_destroy(m_task_t task)
+{
+  return MSG_OK;
+}
+
+
+/** \ingroup m_task_management
+ * \brief Cancel a #m_task_t.
+ * \param task the taskt to cancel. If it was executed or transfered, it 
+          stops the process that were working on it.
+ */
+MSG_error_t MSG_task_cancel(m_task_t task)
+{
+  return MSG_FATAL;
+}
+
+/** \ingroup m_task_management
+ * \brief Returns the computation amount needed to process a task #m_task_t.
+ *        Once a task has been processed, this amount is thus set to 0...
+ */
+double MSG_task_get_compute_duration(m_task_t task) 
+{
+       return 0.0;
+}
+
+/** \ingroup m_task_management
+ * \brief Returns the remaining computation amount of a task #m_task_t.
+ *
+ */
+double MSG_task_get_remaining_computation(m_task_t task)
+{
+       return 0.0;
+}
+
+/** \ingroup m_task_management
+ * \brief Returns the size of the data attached to a task #m_task_t.
+ *
+ */
+double MSG_task_get_data_size(m_task_t task) 
+{
+  xbt_assert0((task != NULL) && (task->simdata != NULL), "Invalid parameter");
+
+  return task->simdata->message_size;
+}
+
+MSG_error_t __MSG_task_wait_event(m_process_t process, m_task_t task)
+{
+  return MSG_OK;
+}
+
+
+/** \ingroup m_task_management
+ * \brief Changes the priority of a computation task. This priority doesn't affect 
+ *        the transfer rate. A priority of 2 will make a task receive two times more
+ *        cpu power than the other ones.
+ *
+ */
+void MSG_task_set_priority(m_task_t task, double priority) 
+{
+
+}
+
+/* Mallocator functions */
+m_task_t task_mallocator_new_f(void) 
+{
+  m_task_t task = xbt_new(s_m_task_t, 1);
+  simdata_task_t simdata = xbt_new0(s_simdata_task_t, 1);
+  task->simdata = simdata;
+  return task;
+}
+
+void task_mallocator_free_f(m_task_t task) 
+{
+  xbt_assert0((task != NULL), "Invalid parameter");
+
+  xbt_free(task->simdata);
+  xbt_free(task);
+
+  return;
+}
+
+void task_mallocator_reset_f(m_task_t task) 
+{
+  memset(task->simdata, 0, sizeof(s_simdata_task_t));  
+}