--- /dev/null
+
+#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;
+}
+
--- /dev/null
+
+#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;
+}
+
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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();
+}
--- /dev/null
+#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;
+}
--- /dev/null
+
+#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;
+}
--- /dev/null
+
+#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;
+}
--- /dev/null
+/* $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
--- /dev/null
+#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));
+}