Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
making some field names more explicit (e.g. void * -> sim_data_task_t) even though...
authoralegrand <alegrand@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 16 Dec 2004 20:50:39 +0000 (20:50 +0000)
committeralegrand <alegrand@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 16 Dec 2004 20:50:39 +0000 (20:50 +0000)
starting to reimplement MSG

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@669 48e7efb5-ca39-0410-a469-dd3cf9ba447f

include/msg/datatypes.h
src/Makefile.am
src/msg/private.h [new file with mode: 0644]
src/msg/task.c [new file with mode: 0644]

index fe6cf11..beba7c6 100644 (file)
 
 /********************************* Host **************************************/
 
 
 /********************************* Host **************************************/
 
-struct s_m_host {
+typedef struct sim_data_host *sim_data_host_t;
+typedef struct m_host {
   char *name;                  /* host name if any */
   char *name;                  /* host name if any */
-  void *simdata;               /* simulator data */
+  sim_data_host_t simdata;     /* simulator data */
   void *data;                  /* user data */
   void *data;                  /* user data */
-};
+} s_m_host_t;
 /** \brief Host datatype  
     \ingroup m_datatypes_management
 
 /** \brief Host datatype  
     \ingroup m_datatypes_management
 
@@ -27,15 +28,17 @@ struct s_m_host {
 
     \see m_host_management
 */
 
     \see m_host_management
 */
-typedef struct s_m_host *m_host_t;
+typedef s_m_host_t *m_host_t;
 
 /********************************* Task **************************************/
 
 
 /********************************* Task **************************************/
 
-struct s_m_task {
+typedef struct sim_data_task *sim_data_task_t;
+typedef struct m_task {
   char *name;                  /* host name if any */
   char *name;                  /* host name if any */
-  void *simdata;               /* simulator data */
+  sim_data_task_t simdata;     /* simulator data */
   void *data;                  /* user data */
   void *data;                  /* user data */
-};
+} s_m_task_t;
+
 /** \brief Task datatype  
     \ingroup m_datatypes_management 
 
 /** \brief Task datatype  
     \ingroup m_datatypes_management 
 
@@ -44,26 +47,27 @@ struct s_m_task {
     data</em>.
     \see m_task_management
 */
     data</em>.
     \see m_task_management
 */
-typedef struct s_m_task *m_task_t;
+typedef s_m_task_t *m_task_t;
 
 /** \brief Default value for an uninitialized #m_task_t.
     \ingroup m_datatypes_management 
 */
 #define MSG_TASK_UNINITIALIZED NULL
 
 /** \brief Default value for an uninitialized #m_task_t.
     \ingroup m_datatypes_management 
 */
 #define MSG_TASK_UNINITIALIZED NULL
-/******************************* Process *************************************/
 
 
-struct s_m_process {
+/******************************* Process *************************************/
+typedef struct sim_data_process *sim_data_process_t;
+typedef struct m_process {
   char *name;                  /* process name if any */
   char *name;                  /* process name if any */
-  void *simdata;               /* simulator data */
+  sim_data_process_t simdata;  /* simulator data */
   void *data;                  /* user data */
   void *data;                  /* user data */
-};
+} s_m_process_t;
 /** \brief Agent datatype  
     \ingroup m_datatypes_management 
     An agent may be defined as a <em>code</em>, with some <em>private
     data</em>, executing in a <em>location</em>.
     \see m_process_management
 */
 /** \brief Agent datatype  
     \ingroup m_datatypes_management 
     An agent may be defined as a <em>code</em>, with some <em>private
     data</em>, executing in a <em>location</em>.
     \see m_process_management
 */
-typedef struct s_m_process *m_process_t;
+typedef s_m_process_t *m_process_t;
 /** \brief Agent code datatype  
     \ingroup m_datatypes_management 
     The code of an agent is a m_process_code_t, i.e. a function with no arguments 
 /** \brief Agent code datatype  
     \ingroup m_datatypes_management 
     The code of an agent is a m_process_code_t, i.e. a function with no arguments 
index b39ca5f..03a5e47 100644 (file)
@@ -32,6 +32,8 @@ EXTRA_DIST= \
        surf/surf_parse.l surf/surf_parse.h \
        surf/network_private.h \
        \
        surf/surf_parse.l surf/surf_parse.h \
        surf/network_private.h \
        \
+       msg/private.h \
+       \
        gras/Transport/transport_interface.h \
        gras/Virtu/virtu_interface.h \
        gras/Virtu/virtu_rl.h \
        gras/Transport/transport_interface.h \
        gras/Virtu/virtu_interface.h \
        gras/Virtu/virtu_rl.h \
@@ -107,6 +109,8 @@ COMMON_S=\
   surf/surf_parse.c                                                          \
   surf/cpu.c   surf/network.c   surf/workstation.c                           \
   \
   surf/surf_parse.c                                                          \
   surf/cpu.c   surf/network.c   surf/workstation.c                           \
   \
+  msg/task.c  \
+  \
   gras/gras.c \
   \
   gras/Transport/transport.c          gras/Transport/transport_private.h   gras/Transport/transport_plugin_buf.c  \
   gras/gras.c \
   \
   gras/Transport/transport.c          gras/Transport/transport_private.h   gras/Transport/transport_plugin_buf.c  \
diff --git a/src/msg/private.h b/src/msg/private.h
new file mode 100644 (file)
index 0000000..ccb9e34
--- /dev/null
@@ -0,0 +1,84 @@
+/**** MSG_LICENCE DO NOT REMOVE ****/
+
+#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"
+
+/**************** datatypes **********************************/
+
+typedef enum {
+  HOST_DOWN = 0,
+  HOST_ALIVE = 1
+} m_host_state_t;
+
+typedef struct sim_data_host {
+  void *host;                  /* SURF modeling */
+  xbt_fifo_t *mbox;            /* array of FIFOs used as a mailboxes  */
+  xbt_context_t *sleeping;     /* array of context used to know whether a process is
+                                  waiting for a communication on a channel */
+  m_host_state_t state;
+  s_xbt_swag_t process_list;
+} s_sim_data_host_t;
+
+/********************************* Task **************************************/
+
+typedef struct sim_data_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 */
+} s_sim_data_task_t;
+
+/******************************* Process *************************************/
+
+typedef struct sim_data_process {
+  s_xbt_swag_hookup_t host_hookup; /* link to other process running on the same location */
+  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;        /* used for debugging purposes */
+  m_host_t put_host;            /* used for debugging purposes */
+  int 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 */
+} s_sim_data_process_t;
+
+/************************** Global variables ********************************/
+typedef struct MSG_Global {
+  xbt_fifo_t host;
+  xbt_fifo_t link;
+  xbt_fifo_t process_to_run;
+  xbt_fifo_t process;
+  int max_channel;
+  m_process_t current_process;
+  xbt_dict_t registered_functions;
+} s_MSG_global_t, *MSG_Global_t;
+
+extern MSG_Global_t msg_global;
+
+/*************************************************************/
+
+#define PROCESS_SET_ERRNO(val) (((sim_data_process_t)(MSG_process_self()->simdata))->last_errno=val)
+#define PROCESS_GET_ERRNO() (((sim_data_process_t)(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((((sim_data_host_t) MSG_host_self()->simdata)->state==HOST_ALIVE),"Host failed, you cannot call this function.")
+
+m_task_t __MSG_task_copy(m_task_t task);
+MSG_error_t __MSG_task_wait_event(m_process_t process, m_task_t task);
+
+MSG_error_t __MSG_task_check(m_task_t task);
+
+
+#endif
diff --git a/src/msg/task.c b/src/msg/task.c
new file mode 100644 (file)
index 0000000..01e15ef
--- /dev/null
@@ -0,0 +1,161 @@
+/*     $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(task, msg,
+                               "Logging specific to MSG module (task)");
+
+static char sprint_buffer[64];
+
+/********************************* 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 Mflop)
+   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 Mb) 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, long double compute_duration,
+                        long double message_size, void *data)
+{
+  sim_data_task_t sim_data = xbt_new0(s_sim_data_task_t,1);
+  m_task_t task = xbt_new0(s_m_task_t,1);
+  
+  /* Task structure */
+  task->name = xbt_strdup(name);
+  task->simdata = sim_data;
+  task->data = data;
+
+  /* Simulator Data */
+  sim_data->sleeping = xbt_dynar_new(sizeof(m_process_t),NULL);
+  sim_data->computation_amount = compute_duration;
+  sim_data->message_size = message_size;
+
+  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 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)
+{
+  sim_data_task_t sim_data = NULL;
+  surf_action_t action = NULL;
+  int i;
+
+  xbt_assert0((task != NULL), "Invalid parameter");
+  xbt_assert0((xbt_dynar_length(task->simdata->sleeping)==0), 
+             "Task still used. Cannot destroy it now!");
+
+  if(task->name) xbt_free(task->name);
+
+  xbt_dynar_free(&(task->simdata->sleeping));
+
+  action = task->simdata->compute;
+  if(action) action->resource_type->common_public->action_free(action);
+  action = task->simdata->comm;
+  if(action) action->resource_type->common_public->action_free(action);
+
+
+  xbt_free(task->simdata);
+  xbt_free(task);
+
+  return MSG_OK;
+}
+
+/* static MSG_error_t __MSG_task_check(m_task_t task) */
+/* { */
+/*   sim_data_task_t sim_data = NULL; */
+/*   int warning = 0; */
+
+/*   if (task == NULL) {               /\* Fatal *\/ */
+/*     WARNING("Task uninitialized"); */
+/*     return MSG_FATAL; */
+/*   } */
+/*   sim_data = task->simdata; */
+
+/*   if (sim_data == NULL) {   /\* Fatal *\/ */
+/*     WARNING("Simulator Data uninitialized"); */
+/*     return MSG_FATAL; */
+/*   } */
+
+/*   if (sim_data->compute == NULL) {  /\* Fatal if execute ... *\/ */
+/*     WARNING("No duration set for this task"); */
+/*     warning++; */
+/*   } */
+
+/*   if (sim_data->message_size == 0) {        /\* Fatal if transfered ... *\/ */
+/*     WARNING("No message_size set for this task"); */
+/*     warning++; */
+/*   } */
+
+/* /\*    if (task->data == NULL) { *\/ */
+/* /\*      WARNING("User Data uninitialized"); *\/ */
+/* /\*      warning++; *\/ */
+/* /\*    } *\/ */
+
+/*   if (warning) */
+/*     return MSG_WARNING; */
+/*   return MSG_OK; */
+/* } */
+
+/* static m_task_t __MSG_task_copy(m_task_t src) */
+/* { */
+/*   m_task_t copy = NULL; */
+/*   sim_data_task_t sim_data = NULL; */
+
+/*   __MSG_task_check(src); */
+
+/*   sim_data = src->simdata; */
+/*   copy = MSG_task_create(src->name, SG_getTaskCost(sim_data->compute), */
+/*                      sim_data->message_size, MSG_task_get_data(src)); */
+
+/*   return (copy); */
+/* } */
+
+MSG_error_t __MSG_task_wait_event(m_process_t process, m_task_t task)
+{
+  xbt_assert0(((task != NULL)
+              && (task->simdata != NULL)), "Invalid parameters");
+
+  xbt_dynar_push(task->simdata->sleeping, process);
+  process->simdata->waiting_task = task;
+  xbt_context_yield(process->simdata->context);
+  process->simdata->waiting_task = NULL;
+
+  return MSG_OK;
+}