DEBUG0("Communication request found!");
xbt_fifo_shift(rdv->comm_fifo);
SIMIX_communication_use(comm);
+ comm->rdv = NULL;
return comm;
}
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 */
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);
}
/**
/**
* \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)
{
comm->act->data = comm;
SIMIX_register_action_to_condition(comm->act, comm->cond);
- }else{
- DEBUG1("Communication %p cannot be started, peer missing", comm);
}
}
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);
}
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);
*/
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;
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;
/******************************************************************************/
/* 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
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
/* 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;
+}