Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add SIMIX_rdv_{set,get}_data; tiny fixups
[simgrid.git] / src / simix / smx_network.c
index 41a86d0..9c421ab 100644 (file)
@@ -82,6 +82,7 @@ smx_comm_t SIMIX_rdv_get_request(smx_rdv_t rdv, smx_comm_type_t type)
     DEBUG0("Communication request found!");
     xbt_fifo_shift(rdv->comm_fifo);
     SIMIX_communication_use(comm);
+    comm->rdv = NULL;    
     return comm;
   }
 
@@ -122,6 +123,14 @@ smx_comm_t SIMIX_rdv_get_head(smx_rdv_t rdv)
   return (smx_comm_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(rdv->comm_fifo));
 }
 
+/** @brief adds some API-related data to the rendez-vous point */
+void SIMIX_rdv_set_data(smx_rdv_t rdv,void *data) {
+  rdv->data=data;
+}
+/** @brief gets API-related data from the rendez-vous point */
+void *SIMIX_rdv_get_data(smx_rdv_t rdv) {
+  return rdv->data;
+}
 
 /******************************************************************************/
 /*                           Communication Requests                           */
@@ -150,13 +159,20 @@ smx_comm_t SIMIX_communication_new(smx_comm_type_t type)
 void SIMIX_communication_destroy(smx_comm_t comm)
 {
   comm->refcount--;
-  if(comm->refcount == 0){
-    if(comm->act != NULL)
-      SIMIX_action_destroy(comm->act);
+  if(comm->refcount > 0)
+    return;
 
-    xbt_free(comm->cond);
-    xbt_free(comm);
+  if(comm->cond){
+    SIMIX_cond_destroy(comm->cond);
+    comm->cond = NULL;
   }
+  
+  if(comm->act){
+    SIMIX_action_destroy(comm->act);
+    comm->act = NULL;
+  }
+  
+  xbt_free(comm);
 }
 
 /**
@@ -174,7 +190,7 @@ static inline void SIMIX_communication_use(smx_comm_t comm)
 
 /**
  *  \brief Start the simulation of a communication request
- *  \param comm The communication request
+ *  \param comm The   comm->rdv = NULL;communication request
  */
 static inline void SIMIX_communication_start(smx_comm_t comm)
 {
@@ -196,8 +212,6 @@ static inline void SIMIX_communication_start(smx_comm_t comm)
     comm->act->data = comm;
     
     SIMIX_register_action_to_condition(comm->act, comm->cond);
-  }else{
-    DEBUG1("Communication %p cannot be started, peer missing", comm);
   }
 }
 
@@ -222,14 +236,16 @@ static inline void SIMIX_communication_wait_for_completion(smx_comm_t comm, doub
       SIMIX_cond_wait_timeout(comm->cond, NULL, timeout);
     }
     CATCH(e){
-      /* If it's a timeout then cancel the communication and signal the other peer */
+      /* If there is a timeout then cancel the communication if it is running or 
+         remove it from the rendez-vous otherwise. Then signal the other peer,
+         destroy the communication and retrow the exception. */
       if(e.category == timeout_error){
         DEBUG1("Communication timeout! %p", comm);
         if(comm->act && SIMIX_action_get_state(comm->act) == SURF_ACTION_RUNNING)
           SIMIX_communication_cancel(comm);
         else
           SIMIX_rdv_remove(comm->rdv, comm);
-          
+
         SIMIX_cond_signal(comm->cond);
         SIMIX_communication_destroy(comm);
       }
@@ -241,23 +257,31 @@ static inline void SIMIX_communication_wait_for_completion(smx_comm_t comm, doub
 
   DEBUG1("Communication %p complete! Let's check for errors", comm);
   
-  /* Check for errors */
+  /* Check for errors other than timeouts (they are catched above) */
   if(!SIMIX_host_get_state(SIMIX_host_self())){
+    if(comm->rdv)
+      SIMIX_rdv_remove(comm->rdv, comm);
     SIMIX_communication_destroy(comm);
     THROW0(host_error, 0, "Host failed");
   } else if (SIMIX_action_get_state(comm->act) == SURF_ACTION_FAILED){
     SIMIX_communication_destroy(comm);
     THROW0(network_error, 0, "Link failure");
   }
-
-  SIMIX_unregister_action_to_condition(comm->act, comm->cond);
 }
 
+/**
+ *  \brief Cancels a communication
+ *  \brief comm The communication to cancel
+ */
 void SIMIX_communication_cancel(smx_comm_t comm)
 {
   SIMIX_action_cancel(comm->act);
 }
 
+/**
+ *  \brief get the amount remaining from the communication
+ *  \param comm The communication
+ */
 double SIMIX_communication_get_remains(smx_comm_t comm)
 {
   return SIMIX_action_get_remains(comm->act);
@@ -269,6 +293,10 @@ double SIMIX_communication_get_remains(smx_comm_t comm)
  */
 void SIMIX_network_copy_data(smx_comm_t comm)
 {
+  /* If there is no data to be copy then return */
+  if(!comm->src_buff || !comm->dst_buff)
+    return;
+  
   size_t src_buff_size = comm->src_buff_size;
   size_t dst_buff_size = *comm->dst_buff_size;
   
@@ -276,7 +304,8 @@ void SIMIX_network_copy_data(smx_comm_t comm)
   dst_buff_size = MIN(dst_buff_size, src_buff_size);
   
   /* Update the receiver's buffer size to the copied amount */
-  *comm->dst_buff_size = dst_buff_size;
+  if (comm->dst_buff_size)
+    *comm->dst_buff_size = dst_buff_size;
 
   if(dst_buff_size == 0)
     return;
@@ -301,7 +330,18 @@ void *SIMIX_communication_get_data(smx_comm_t comm)
 /******************************************************************************/
 /*                        Synchronous Communication                           */
 /******************************************************************************/
-/*  Throws:
+/**
+ *  \brief Put a send communication request in a rendez-vous point and waits for
+ *         its completion (blocking)
+ *  \param rdv The rendez-vous point
+ *  \param task_size The size of the communication action (for surf simulation)
+ *  \param rate The rate of the communication action (for surf)
+ *  \param timeout The timeout used for the waiting the completion 
+ *  \param src_buff The source buffer containing the message to be sent
+ *  \param src_buff_size The size of the source buffer
+ *  \param comm_ref The communication object used for the send
+ *  \param data User data associated to the communication object
+ *  Throws:
  *   - host_error if peer failed
  *   - timeout_error if communication reached the timeout specified
  *   - network_error if network failed or peer issued a timeout
@@ -340,7 +380,15 @@ void SIMIX_network_send(smx_rdv_t rdv, double task_size, double rate,
   SIMIX_communication_destroy(comm);
 }
 
-/*  Throws:
+/**
+ *  \brief Put a receive communication request in a rendez-vous point and waits
+ *         for its completion (blocking)
+ *  \param rdv The rendez-vous point
+ *  \param timeout The timeout used for the waiting the completion 
+ *  \param dst_buff The destination buffer to copy the received message
+ *  \param src_buff_size The size of the destination buffer
+ *  \param comm_ref The communication object used for the send
+ *  Throws:
  *   - host_error if peer failed
  *   - timeout_error if communication reached the timeout specified
  *   - network_error if network failed or peer issued a timeout
@@ -379,16 +427,16 @@ void SIMIX_network_recv(smx_rdv_t rdv, double timeout, void *dst_buff,
 /*                        Asynchronous Communication                          */
 /******************************************************************************/
 
-/*
+
 void SIMIX_network_wait(smx_action_t comm, double timeout)
 {
-  TO BE IMPLEMENTED
+  THROW_UNIMPLEMENTED;
 }
 
 XBT_PUBLIC(int) SIMIX_network_test(smx_action_t comm)
 {
-  TO BE IMPLEMENTED
-}*/
+  THROW_UNIMPLEMENTED;
+}