From: alegrand Date: Fri, 17 Dec 2004 05:46:56 +0000 (+0000) Subject: Keeping rewriting MSG X-Git-Tag: v3.3~4673 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/dd89516cade805920cd23e69dd7eadabe83cad85 Keeping rewriting MSG git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@677 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/src/msg/m_process.c b/src/msg/m_process.c new file mode 100644 index 0000000000..d3e1dbd1f8 --- /dev/null +++ b/src/msg/m_process.c @@ -0,0 +1,335 @@ +/* $Id$ */ + +/* Copyright (c) 2002,2003,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. */ + +#include"private.h" +#include"xbt/sysdep.h" +#include "xbt/error.h" +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(m_process, msg, + "Logging specific to MSG (process)"); + +/******************************** Process ************************************/ +/** \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 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. + * \see m_process_t + * \return The new corresponding object. + */ +m_process_t MSG_process_create(const char *name, + m_process_code_t code, void *data, + m_host_t host) +{ + simdata_process_t simdata = xbt_new0(s_simdata_process_t,1); + m_process_t process = xbt_new0(s_m_process_t,1); + m_process_t self = NULL; + static int PID = 1; + + xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters"); + /* Simulator Data */ + + simdata->PID = PID++; + simdata->host = host; + simdata->waiting_task = NULL; + simdata->put_host = NULL; + simdata->put_channel = -1; + simdata->argc = -1; + simdata->argv = NULL; + simdata->context = xbt_context_new(code, simdata->argc, simdata->argv); + + if((self=msg_global->current_process)) { + simdata->PPID = MSG_process_get_PID(self); + } else { + simdata->PPID = -1; + } + simdata->last_errno=MSG_OK; + + + /* Process structure */ + process->name = xbt_strdup(name); + process->simdata = simdata; + process->data = data; + + xbt_fifo_push(host->simdata->process_list, process); + + /* /////////////// FIX du current_process !!! ////////////// */ + self = msg_global->current_process; + xbt_context_start(process->simdata->context); + msg_global->current_process = self; + return process; +} + +/** \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) +{ + simdata_process_t simdata = NULL; + + /* Sanity check */ + + xbt_assert0(((process) && (process->simdata) + && (host)), "Invalid parameters"); + simdata = process->simdata; + + xbt_fifo_remove(simdata->host->simdata->process_list,process); + simdata->host = host; + xbt_fifo_push(host->simdata->process_list,process); + + 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) +{ + xbt_fifo_item_t i = NULL; + m_process_t process = NULL; + + xbt_fifo_foreach(msg_global->process_list,i,process,m_process_t) { + if(MSG_process_get_PID(process) == PID) return process; + } + 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 msg_global->current_process; +} + +/** \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) +{ + simdata_process_t simdata = NULL; + simdata_task_t simdata_task = NULL; + int i; + + xbt_assert0(((process) && (process->simdata)), "Invalid parameters"); + + if(process!=MSG_process_self()) { + simdata = process->simdata; + + xbt_assert0(simdata->waiting_task,"Process not waiting for anything else. Weird !"); + + simdata_task = simdata->waiting_task->simdata; + + xbt_assert0(((simdata_task->compute)||(simdata_task->comm))&& + !((simdata_task->comm)&&(simdata_task->comm)), + "Got a problem in deciding which action to choose !"); + if(simdata_task->compute) + surf_workstation_resource->extension_public->suspend(simdata_task->compute); + else + surf_workstation_resource->extension_public->suspend(simdata_task->comm); + + } else { + m_task_t dummy = MSG_TASK_UNINITIALIZED; + dummy = MSG_task_create("suspended", 0.01, 0, NULL); + + __MSG_task_execute(process,dummy); + surf_workstation_resource->extension_public->suspend(dummy->simdata->compute); + __MSG_wait_for_computation(process,dummy); + + MSG_task_destroy(dummy); + } + 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) +{ + simdata_process_t simdata = NULL; + simdata_task_t simdata_task = NULL; + int i; + + xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters"); + CHECK_HOST(); + + simdata = process->simdata; + if(!(simdata->waiting_task)) { + xbt_assert0(0,"Process not waiting for anything else. Weird !"); + return MSG_WARNING; + } + simdata_task = simdata->waiting_task->simdata; + + if(simdata_task->compute) + surf_workstation_resource->extension_public->resume(simdata_task->compute); + else + surf_workstation_resource->extension_public->resume(simdata_task->comm); + + 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_isSuspended(m_process_t process) +{ + simdata_process_t simdata = NULL; + simdata_task_t simdata_task = NULL; + int i; + + xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters"); + + simdata = process->simdata; + if(!(simdata->waiting_task)) { + xbt_assert0(0,"Process not waiting for anything else. Weird !"); + return 0; + } + + simdata_task = simdata->waiting_task->simdata; + + if(simdata_task->compute) + return surf_workstation_resource->extension_public->is_suspended(simdata_task->compute); + else + return surf_workstation_resource->extension_public->is_suspended(simdata_task->comm); +} diff --git a/src/msg/private.h b/src/msg/private.h index bc4a6db2a2..ad8c31ead6 100644 --- a/src/msg/private.h +++ b/src/msg/private.h @@ -49,7 +49,7 @@ typedef struct simdata_process { 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; /* used for debugging purposes */ + m_task_t waiting_task; m_host_t put_host; /* used for debugging purposes */ int put_channel; /* used for debugging purposes */ int argc; /* arguments number if any */ @@ -62,7 +62,7 @@ typedef struct MSG_Global { xbt_fifo_t host; xbt_fifo_t link; xbt_fifo_t process_to_run; - xbt_fifo_t process; + xbt_fifo_t process_list; int max_channel; m_process_t current_process; xbt_dict_t registered_functions; @@ -72,16 +72,18 @@ extern MSG_Global_t msg_global; /*************************************************************/ -#define PROCESS_SET_ERRNO(val) (((simdata_process_t)(MSG_process_self()->simdata))->last_errno=val) -#define PROCESS_GET_ERRNO() (((simdata_process_t)(MSG_process_self()->simdata))->last_errno) +#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() ASSERT((((simdata_host_t) MSG_host_self()->simdata)->state==HOST_ALIVE),"Host failed, you cannot call this function.") +#define CHECK_HOST() xbt_assert0((MSG_host_self()->simdata->state==HOST_ALIVE),"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); #endif