From 106facfd0f20f0321e561401f6e3de3fffbeadfb Mon Sep 17 00:00:00 2001 From: donassbr Date: Wed, 21 Mar 2007 14:51:27 +0000 Subject: [PATCH] MSG/SIMIX Initial files. Only functions prototypes, not implemented yet. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3323 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/msg_simix/deployment.c | 55 ++++++ src/msg_simix/environment.c | 48 +++++ src/msg_simix/global.c | 136 ++++++++++++++ src/msg_simix/gos.c | 343 ++++++++++++++++++++++++++++++++++++ src/msg_simix/host.c | 145 +++++++++++++++ src/msg_simix/m_process.c | 265 ++++++++++++++++++++++++++++ src/msg_simix/msg_config.c | 20 +++ src/msg_simix/private.h | 176 ++++++++++++++++++ src/msg_simix/task.c | 183 +++++++++++++++++++ 9 files changed, 1371 insertions(+) create mode 100644 src/msg_simix/deployment.c create mode 100644 src/msg_simix/environment.c create mode 100644 src/msg_simix/global.c create mode 100644 src/msg_simix/gos.c create mode 100644 src/msg_simix/host.c create mode 100644 src/msg_simix/m_process.c create mode 100644 src/msg_simix/msg_config.c create mode 100644 src/msg_simix/private.h create mode 100644 src/msg_simix/task.c diff --git a/src/msg_simix/deployment.c b/src/msg_simix/deployment.c new file mode 100644 index 0000000000..aab4aac3c2 --- /dev/null +++ b/src/msg_simix/deployment.c @@ -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 index 0000000000..ff3fa42f1e --- /dev/null +++ b/src/msg_simix/environment.c @@ -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 \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 index 0000000000..cdd32d61e6 --- /dev/null +++ b/src/msg_simix/global.c @@ -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 \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 \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 + +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 index 0000000000..cdf0e18e4f --- /dev/null +++ b/src/msg_simix/gos.c @@ -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 index 0000000000..92174919d5 --- /dev/null +++ b/src/msg_simix/host.c @@ -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 \endhtmlonly + * (#m_host_t) and the functions for managing it. + * + * A location (or host) is any possible place where + * a process may run. Thus it may be represented as a + * physical resource with computing capabilities, some + * mailboxes to enable running process to communicate with + * remote ones, and some private data 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 index 0000000000..4641f0c9b2 --- /dev/null +++ b/src/msg_simix/m_process.c @@ -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 \endhtmlonly + * + * We need to simulate many independent scheduling decisions, so + * the concept of process is at the heart of the + * simulator. A process may be defined as a code, with + * some private data, executing in a location. + * \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 index 0000000000..37c81ca6ba --- /dev/null +++ b/src/msg_simix/msg_config.c @@ -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 index 0000000000..d4b9d6e22a --- /dev/null +++ b/src/msg_simix/private.h @@ -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 index 0000000000..b166e7e559 --- /dev/null +++ b/src/msg_simix/task.c @@ -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 \endhtmlonly + * + * Since most scheduling algorithms rely on a concept of task + * that can be either computed locally or + * transferred on another processor, it seems to be the + * right level of abstraction for our purposes. A task + * may then be defined by a computing amount, a + * message size and some private data. + */ + +/********************************* 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)); +} -- 2.30.2