Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Added new functions and some modifications on the headers was made.
authordonassbr <donassbr@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Fri, 2 Mar 2007 14:11:50 +0000 (14:11 +0000)
committerdonassbr <donassbr@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Fri, 2 Mar 2007 14:11:50 +0000 (14:11 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@3192 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/include/simix/simix.h
src/simix/private.h
src/simix/smx_action.c
src/simix/smx_process.c
src/simix/smx_synchro.c

index 1a892e5..ed51809 100644 (file)
@@ -76,9 +76,9 @@ XBT_PUBLIC(SIMIX_error_t) SIMIX_get_errno(void);
 /******Mutex******/
 XBT_PUBLIC(smx_mutex_t) SIMIX_mutex_init(void);
 XBT_PUBLIC(void) SIMIX_mutex_lock(smx_mutex_t mutex);
 /******Mutex******/
 XBT_PUBLIC(smx_mutex_t) SIMIX_mutex_init(void);
 XBT_PUBLIC(void) SIMIX_mutex_lock(smx_mutex_t mutex);
-XBT_PUBLIC(void) SIMIX_mutex_trylock(smx_mutex_t mutex);
+XBT_PUBLIC(int) SIMIX_mutex_trylock(smx_mutex_t mutex);
 XBT_PUBLIC(void) SIMIX_mutex_unlock(smx_mutex_t mutex);
 XBT_PUBLIC(void) SIMIX_mutex_unlock(smx_mutex_t mutex);
-XBT_PUBLIC(void) SIMIX_mutex_destroy(smx_mutex_t mutex);
+XBT_PUBLIC(SIMIX_error_t) SIMIX_mutex_destroy(smx_mutex_t mutex);
 
 /*****Conditional*****/
 XBT_PUBLIC(smx_cond_t) SIMIX_cond_init(void);
 
 /*****Conditional*****/
 XBT_PUBLIC(smx_cond_t) SIMIX_cond_init(void);
@@ -95,6 +95,7 @@ XBT_PUBLIC(smx_action_t) SIMIX_execute(smx_host_t host,double amount);
 XBT_PUBLIC(SIMIX_error_t) SIMIX_action_cancel(smx_action_t action);
 XBT_PUBLIC(void) SIMIX_action_set_priority(smx_action_t action, double priority);
 XBT_PUBLIC(SIMIX_error_t) SIMIX_action_destroy(smx_action_t action);
 XBT_PUBLIC(SIMIX_error_t) SIMIX_action_cancel(smx_action_t action);
 XBT_PUBLIC(void) SIMIX_action_set_priority(smx_action_t action, double priority);
 XBT_PUBLIC(SIMIX_error_t) SIMIX_action_destroy(smx_action_t action);
+XBT_PUBLIC(void) SIMIX_create_link(smx_action_t action, smx_cond_t cond);
 
 //SIMIX_action_wait_for_computation(smx_process_t process, smx_action_t action);
 
 
 //SIMIX_action_wait_for_computation(smx_process_t process, smx_action_t action);
 
index 4139869..710abc5 100644 (file)
 #include "xbt/context.h"
 #include "xbt/config.h"
 
 #include "xbt/context.h"
 #include "xbt/config.h"
 
-/**************** datatypes **********************************/
+/******************************* Datatypes **********************************/
+
+
+/********************************** Host ************************************/
 
 typedef struct s_simdata_host {
   void *host;                  /* SURF modeling */
 
 typedef struct s_simdata_host {
   void *host;                  /* SURF modeling */
@@ -48,7 +51,10 @@ typedef struct s_simdata_process {
   xbt_context_t context;               /* the context that executes the scheduler fonction */
   int blocked;
   int suspended;
   xbt_context_t context;               /* the context that executes the scheduler fonction */
   int blocked;
   int suspended;
+  smx_mutex_t mutex;           /* mutex on which the process is blocked  */
+  smx_cond_t cond;             /* cond on which the process is blocked  */
   smx_host_t put_host;         /* used for debugging purposes */
   smx_host_t put_host;         /* used for debugging purposes */
+  smx_action_t block_action;   /* action that block the process when it does a mutex_lock or cond_wait */
   int argc;                     /* arguments number if any */
   char **argv;                  /* arguments table if any */
   SIMIX_error_t last_errno;       /* the last value returned by a MSG_function */
   int argc;                     /* arguments number if any */
   char **argv;                  /* arguments table if any */
   SIMIX_error_t last_errno;       /* the last value returned by a MSG_function */
@@ -68,14 +74,16 @@ typedef struct process_arg {
 /********************************* Mutex and Conditional ****************************/
 
 typedef struct s_smx_mutex {
 /********************************* Mutex and Conditional ****************************/
 
 typedef struct s_smx_mutex {
-       xbt_swag_t sleeping;
+       xbt_swag_t sleeping;                    /* list of sleeping process */
        int using;
 
 } s_smx_mutex_t;
 
 typedef struct s_smx_cond {
        int using;
 
 } s_smx_mutex_t;
 
 typedef struct s_smx_cond {
+       xbt_swag_t sleeping;                    /* list of sleeping process */
        s_smx_mutex_t * mutex;
        s_smx_mutex_t * mutex;
-       xbt_swag_t sleeping; //process
+       xbt_fifo_t actions;                     /* list of actions */
+
 } s_smx_cond_t;
 
 /********************************* Action **************************************/
 } s_smx_cond_t;
 
 /********************************* Action **************************************/
@@ -123,7 +131,7 @@ extern xbt_cfg_t _simix_cfg_set;
 /* #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-> \
 /* #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,\
+                                 get_state(SIMIX_host_self()->simdata->host)==SURF_CPU_ON,\
                                   "Host failed, you cannot call this function.")
 
 smx_host_t __SIMIX_host_create(const char *name, void *workstation, void *data);
                                   "Host failed, you cannot call this function.")
 
 smx_host_t __SIMIX_host_create(const char *name, void *workstation, void *data);
@@ -135,9 +143,11 @@ int __SIMIX_process_isBlocked(smx_process_t process);
 
 void __SIMIX_display_process_status(void);
 
 
 void __SIMIX_display_process_status(void);
 
+SIMIX_error_t __SIMIX_wait_for_action(smx_process_t process, smx_action_t action);
+
+
 /*
 void __MSG_task_execute(smx_process_t process, m_task_t task);
 /*
 void __MSG_task_execute(smx_process_t process, m_task_t task);
-MSG_error_t __MSG_wait_for_computation(smx_process_t process, m_task_t task);
 MSG_error_t __MSG_task_wait_event(smx_process_t process, m_task_t task);
 */
 
 MSG_error_t __MSG_task_wait_event(smx_process_t process, m_task_t task);
 */
 
index 540c5f7..8be954c 100644 (file)
@@ -39,3 +39,41 @@ SIMIX_error_t SIMIX_action_destroy(smx_action_t action)
 {
        return SIMIX_OK;
 }
 {
        return SIMIX_OK;
 }
+
+void SIMIX_create_link(smx_action_t action, smx_cond_t cond)
+{
+
+}
+
+SIMIX_error_t __SIMIX_wait_for_action(smx_process_t process, smx_action_t action)
+{
+       e_surf_action_state_t state = SURF_ACTION_NOT_IN_THE_SYSTEM;
+       simdata_action_t simdata = action->simdata;
+
+       xbt_assert0(((process != NULL) && (action != NULL) && (action->simdata != NULL)), "Invalid parameters");
+       
+       /* change context while the action is running  */
+       do {
+               xbt_context_yield();
+               state=surf_workstation_resource->common_public->action_get_state(simdata->surf_action);
+       } while (state==SURF_ACTION_RUNNING);
+       
+       /* action finished, we can continue */
+
+       if(state == SURF_ACTION_DONE) {
+               if(surf_workstation_resource->common_public->action_free(simdata->surf_action)) 
+                       simdata->surf_action = NULL;
+               SIMIX_RETURN(SIMIX_OK);
+       } else if(surf_workstation_resource->extension_public->
+                       get_state(SIMIX_process_get_host(process)->simdata->host) 
+                       == SURF_CPU_OFF) {
+               if(surf_workstation_resource->common_public->action_free(simdata->surf_action)) 
+                       simdata->surf_action = NULL;
+               SIMIX_RETURN(SIMIX_HOST_FAILURE);
+       } else {
+               if(surf_workstation_resource->common_public->action_free(simdata->surf_action)) 
+                       simdata->surf_action = NULL;
+               SIMIX_RETURN(SIMIX_ACTION_CANCELLED);
+       }
+
+}
index cc8b6b1..3f17ace 100644 (file)
@@ -261,52 +261,51 @@ smx_process_t SIMIX_process_self(void)
  */
 SIMIX_error_t SIMIX_process_suspend(smx_process_t process)
 {
  */
 SIMIX_error_t SIMIX_process_suspend(smx_process_t process)
 {
-/*
   simdata_process_t simdata = NULL;
   simdata_process_t simdata = NULL;
-  simdata_task_t simdata_task = NULL;
-
-  XBT_IN2("(%p(%s))", process, process->name);
-
+       smx_action_t dummy;
+       
   xbt_assert0(((process) && (process->simdata)), "Invalid parameters");
 
   xbt_assert0(((process) && (process->simdata)), "Invalid parameters");
 
-  PAJE_PROCESS_PUSH_STATE(process,"S",NULL);
-
   if(process!=SIMIX_process_self()) {
     simdata = process->simdata;
     
   if(process!=SIMIX_process_self()) {
     simdata = process->simdata;
     
-    xbt_assert0(simdata->waiting_task,"Process not waiting for anything else. Weird !");
-
-    simdata_task = simdata->waiting_task->simdata;
-
-    simdata->suspended = 1;
-    if(simdata->blocked) {
-      XBT_OUT;
-      return SIMIX_OK;
-    }
+               if ( (simdata->mutex == NULL) && (simdata->cond == NULL) ) {
+                       /* Ops, I don't know what to do yet. */
+
+               }
+               else if (simdata->mutex) {
+                       /* process blocked on a mutex, only set suspend=1 */
+                       simdata->suspended = 1;
+               }
+               else if (simdata->cond){
+                       /* process blocked cond, suspend all actions */
+                       
+                       /* temporaries variables */ 
+                       smx_cond_t c;
+                       xbt_fifo_item_t i;
+                       smx_action_t act;
+
+                       simdata->suspended = 1;
+                       c = simdata->cond;
+                       xbt_fifo_foreach(c->actions,i,act, smx_action_t) {
+                                surf_workstation_resource->common_public->suspend(act->simdata->surf_action);
+                       }
+               }
+               else xbt_assert0(0, "Unknown process status");
 
 
-    xbt_assert0(((simdata_task->compute)||(simdata_task->comm))&&
-               !((simdata_task->compute)&&(simdata_task->comm)),
-               "Got a problem in deciding which action to choose !");
-    simdata->suspended = 1;
-    if(simdata_task->compute) 
-      surf_workstation_resource->common_public->suspend(simdata_task->compute);
-    else
-      surf_workstation_resource->common_public->suspend(simdata_task->comm);
-  } else {
-    m_task_t dummy = MSG_TASK_UNINITIALIZED;
-    dummy = MSG_task_create("suspended", 0.0, 0, NULL);
-
-    simdata = process->simdata;
-    simdata->suspended = 1;
-    __MSG_task_execute(process,dummy);
-    surf_workstation_resource->common_public->suspend(dummy->simdata->compute);
-    __MSG_wait_for_computation(process,dummy);
-    simdata->suspended = 0;
-
-    MSG_task_destroy(dummy);
   }
   }
-  XBT_OUT;
-  */
+       else {
+               /* process executing, I can create an action and suspend it */
+               dummy = SIMIX_execute(SIMIX_process_get_host(process)->simdata->host, 0);
+               process->simdata->block_action = dummy;
+
+               process->simdata->suspended = 1;
+               surf_workstation_resource->common_public->suspend(dummy->simdata->surf_action);
+               __SIMIX_wait_for_action(process,dummy);
+               SIMIX_action_destroy(dummy);
+               process->simdata->suspended = 0;
+
+       }
   return SIMIX_OK;
 }
 
   return SIMIX_OK;
 }
 
@@ -318,50 +317,41 @@ SIMIX_error_t SIMIX_process_suspend(smx_process_t process)
  */
 SIMIX_error_t SIMIX_process_resume(smx_process_t process)
 {
  */
 SIMIX_error_t SIMIX_process_resume(smx_process_t process)
 {
-/*
   simdata_process_t simdata = NULL;
   simdata_process_t simdata = NULL;
-  simdata_task_t simdata_task = NULL;
 
   xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
   CHECK_HOST();
 
 
   xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
   CHECK_HOST();
 
-  XBT_IN2("(%p(%s))", process, process->name);
-
   if(process == SIMIX_process_self()) {
   if(process == SIMIX_process_self()) {
-    XBT_OUT;
     SIMIX_RETURN(SIMIX_OK);
   }
 
   simdata = process->simdata;
 
     SIMIX_RETURN(SIMIX_OK);
   }
 
   simdata = process->simdata;
 
-  if(simdata->blocked) {
-    PAJE_PROCESS_POP_STATE(process);
-
-    simdata->suspended = 0; *//* He'll wake up by itself */
-    /*XBT_OUT;
+  if(simdata->mutex) {
+    simdata->suspended = 0; /* He'll wake up by itself */
     SIMIX_RETURN(SIMIX_OK);
   }
     SIMIX_RETURN(SIMIX_OK);
   }
+       else if (simdata->cond) {
+               /* temporaries variables */ 
+               smx_cond_t c;
+               xbt_fifo_item_t i;
+               smx_action_t act;
+
+               simdata->suspended = 0;
+               c = simdata->cond;
+               xbt_fifo_foreach(c->actions,i,act, smx_action_t) {
+                       surf_workstation_resource->common_public->resume(act->simdata->surf_action);
+               }
+    SIMIX_RETURN(SIMIX_OK);
+       }
+       else if (simdata->block_action){
+               simdata->suspended = 0;
+               surf_workstation_resource->common_public->resume(simdata->block_action->simdata->surf_action);
+    SIMIX_RETURN(SIMIX_OK);
+       }
+       else xbt_assert0(0, "Unknown process status");
 
 
-  if(!(simdata->waiting_task)) {
-    xbt_assert0(0,"Process not waiting for anything else. Weird !");
-    XBT_OUT;
-    return SIMIX_WARNING;
-  }
-  simdata_task = simdata->waiting_task->simdata;
-
-
-  if(simdata_task->compute) {
-    surf_workstation_resource->common_public->resume(simdata_task->compute);
-    PAJE_PROCESS_POP_STATE(process);
-  }
-  else {
-    PAJE_PROCESS_POP_STATE(process);
-    surf_workstation_resource->common_public->resume(simdata_task->comm);
-  }
-
-  XBT_OUT;
-  */
-  SIMIX_RETURN(SIMIX_OK);
 }
 
 /** \ingroup m_process_management
 }
 
 /** \ingroup m_process_management
@@ -379,8 +369,30 @@ int SIMIX_process_is_suspended(smx_process_t process)
 
 int __SIMIX_process_block(double max_duration, const char *info)
 {
 
 int __SIMIX_process_block(double max_duration, const char *info)
 {
-/*
+
   smx_process_t process = SIMIX_process_self();
   smx_process_t process = SIMIX_process_self();
+  smx_action_t dummy = NULL;
+
+  dummy = SIMIX_execute(SIMIX_process_get_host(process)->simdata->host, 0);
+       process->simdata->block_action = dummy;
+
+  process->simdata->blocked=1;
+
+  surf_workstation_resource->common_public->suspend(dummy->simdata->surf_action);
+  if(max_duration>=0)
+    surf_workstation_resource->common_public->set_max_duration(dummy->simdata->surf_action, 
+                                                              max_duration);
+       __SIMIX_wait_for_action(process,dummy);
+       SIMIX_action_destroy(dummy);
+       process->simdata->blocked=0;
+
+  if(process->simdata->suspended) {
+    DEBUG0("I've been suspended in the meantime");    
+    SIMIX_process_suspend(process);
+    DEBUG0("I've been resumed, let's keep going");    
+  }
+
+/*
   m_task_t dummy = SIMIX_TASK_UNINITIALIZED;
   char blocked_name[512];
   snprintf(blocked_name,512,"blocked [%s] (%s:%s)",
   m_task_t dummy = SIMIX_TASK_UNINITIALIZED;
   char blocked_name[512];
   snprintf(blocked_name,512,"blocked [%s] (%s:%s)",
@@ -417,6 +429,22 @@ int __SIMIX_process_block(double max_duration, const char *info)
 
 SIMIX_error_t __SIMIX_process_unblock(smx_process_t process)
 {
 
 SIMIX_error_t __SIMIX_process_unblock(smx_process_t process)
 {
+  simdata_process_t simdata = NULL;
+  simdata_action_t simdata_action = NULL;
+
+  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  CHECK_HOST();
+
+       simdata = process->simdata;
+  if(!(simdata->block_action)) {
+    xbt_assert0(0,"Process is not blocked !");
+    return SIMIX_WARNING;
+  }
+       simdata_action = simdata->block_action->simdata;
+  xbt_assert0(simdata->blocked,"Process not blocked");
+  surf_workstation_resource->common_public->resume(simdata_action->surf_action);
+  SIMIX_RETURN(SIMIX_OK);
+
 /*
   simdata_process_t simdata = NULL;
   simdata_task_t simdata_task = NULL;
 /*
   simdata_process_t simdata = NULL;
   simdata_task_t simdata_task = NULL;
@@ -440,7 +468,6 @@ SIMIX_error_t __SIMIX_process_unblock(smx_process_t process)
 
   XBT_OUT;
 */
 
   XBT_OUT;
 */
-  SIMIX_RETURN(SIMIX_OK);
 }
 
 int __SIMIX_process_isBlocked(smx_process_t process)
 }
 
 int __SIMIX_process_isBlocked(smx_process_t process)
index 14a2e3a..a15d28c 100644 (file)
@@ -19,27 +19,74 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_synchro, simix,
 /*********************************** Mutex ************************************/
 smx_mutex_t SIMIX_mutex_init()
 {
 /*********************************** Mutex ************************************/
 smx_mutex_t SIMIX_mutex_init()
 {
-       return xbt_new0(s_smx_mutex_t,1);
+       smx_mutex_t m = xbt_new0(s_smx_mutex_t,1);
+       s_smx_process_t p; /* useful to initialize sleeping swag */
+       /* structures initialization */
+       m->using = 0;
+       m->sleeping = xbt_swag_new(xbt_swag_offset(p, synchro_hookup));
+       return m;
 }
 
 void SIMIX_mutex_lock(smx_mutex_t mutex)
 {
 }
 
 void SIMIX_mutex_lock(smx_mutex_t mutex)
 {
+       smx_process_t self = SIMIX_process_self();
+
+       xbt_assert0((mutex != NULL), "Invalid parameters");
+       
+       if (mutex->using) {
+               /* somebody using the mutex, block */
+               xbt_swag_insert(self, mutex->sleeping);
+               self->simdata->mutex = mutex;
+               __SIMIX_process_block(-1,"");
+               self->simdata->mutex = NULL;
+               mutex->using = 1;
+       }
+       else {
+               /* mutex free */
+               mutex->using = 1;
+       }
        return;
 }
        return;
 }
-
-void SIMIX_mutex_trylock(smx_mutex_t mutex)
+/* return 1 if the process got the mutex, else 0. */
+int SIMIX_mutex_trylock(smx_mutex_t mutex)
 {
 {
-       return;
+       xbt_assert0((mutex != NULL), "Invalid parameters");
+       
+       if (mutex->using) 
+               return 0;
+       else {
+               mutex->using = 1;
+               return 1;
+       }
 }
 
 void SIMIX_mutex_unlock(smx_mutex_t mutex)
 {
 }
 
 void SIMIX_mutex_unlock(smx_mutex_t mutex)
 {
+       smx_process_t p;        /*process to wake up */
+       
+       xbt_assert0((mutex != NULL), "Invalid parameters");
+       
+       if (xbt_swag_size(mutex->sleeping) > 0) {
+               p = xbt_swag_extract(mutex->sleeping);
+               mutex->using = 0;
+               __SIMIX_process_unblock(p);
+       }
+       else {
+               /* nobody to wape up */
+               mutex->using = 0;
+       }
        return;
 }
 
        return;
 }
 
-void SIMIX_mutex_destroy(smx_mutex_t mutex)
+SIMIX_error_t SIMIX_mutex_destroy(smx_mutex_t mutex)
 {
 {
-       return;
+       if ( mutex == NULL )
+               return SIMIX_WARNING;
+       else {
+               xbt_swag_free(mutex->sleeping);
+               xbt_free(mutex);
+               return SIMIX_OK;
+       }
 }
 
 /******************************** Conditional *********************************/
 }
 
 /******************************** Conditional *********************************/