-/* $Id$ */
-
-/* Copyright (c) 2009 Cristian Rosa.
- All rights reserved. */
+/* Copyright (c) 2009, 2010. The SimGrid Team.
+ * 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/log.h"
+#include "mc/mc.h"
#include "xbt/dict.h"
/* Pimple to get an histogram of message sizes in the simulation */
DEBUG0("Communication request found!");
xbt_fifo_shift(rdv->comm_fifo);
SIMIX_communication_use(comm);
- comm->rdv = NULL;
+ comm->rdv = NULL;
return comm;
}
/**
* \brief Start the simulation of a communication request
- * \param comm The comm->rdv = NULL;communication request
+ * \param comm The communication request
*/
static inline void SIMIX_communication_start(smx_comm_t comm)
{
* \param timeout The max amount of time to wait for the communication to finish
*
* Throws:
- * - host_error if peer failed
- * - timeout_error if communication reached the timeout specified
- * - network_error if network failed or peer issued a timeout
+ * - host_error if local peer failed
+ * - timeout_error if communication reached the timeout specified (either because of local peer or remote peer)
+ * - network_error if network failed or remote peer failed
*/
static inline void SIMIX_communication_wait_for_completion(smx_comm_t comm, double timeout)
{
SIMIX_sem_release_forever(comm->sem);
/* Check for errors other than timeouts (they are catched above) */
- if(!SIMIX_host_get_state(SIMIX_host_self())){
+ if (!SIMIX_host_get_state(SIMIX_host_self())){
if(comm->rdv)
SIMIX_rdv_remove(comm->rdv, comm);
SIMIX_communication_destroy(comm);
} else if (SIMIX_action_get_state(comm->act) == SURF_ACTION_FAILED){
SIMIX_communication_destroy(comm);
THROW0(network_error, 0, "Link failure");
+ } else if (!SIMIX_host_get_state(SIMIX_process_get_host(comm->dst_proc)) ||
+ !SIMIX_host_get_state(SIMIX_process_get_host(comm->src_proc))) {
+ /* We test both src&dst because we dunno who we are today, and we already tested myself above.
+ * So, at the end, we test the remote peer only
+ * Moreover, we have to test it because if the remote peer fails, the action comm->act is not done nor failed.
+ * In that case, we got awaken by the little endless actions created in the SIMIX_sem_acquire(comm->sem)
+ * at the beginning of this function. */
+ SIMIX_communication_destroy(comm);
+ THROW0(network_error, 0, "Remote peer failed");
+
}
SIMIX_communication_destroy(comm);
}
void *src_buff, size_t src_buff_size, void *data)
{
smx_comm_t comm;
+ mc_transition_t trans=NULL;
+ if (_surf_do_model_check) {
+ /* Let's intercept the communication and control it from the model-checker */
+ trans = MC_create_transition(mc_isend, SIMIX_process_self(), rdv, NULL);
+ SIMIX_process_yield();
+ }
+
/* Look for communication request matching our needs.
If it is not found then create it and push it into the rendez-vous point */
comm = SIMIX_rdv_get_request(rdv, comm_recv);
comm->src_buff_size = src_buff_size;
comm->data = data;
+ /* Associate the simix communication to the mc transition */
+ if (_surf_do_model_check)
+ MC_transition_set_comm(trans, comm);
+
SIMIX_communication_start(comm);
return comm;
}
smx_comm_t SIMIX_network_irecv(smx_rdv_t rdv, void *dst_buff, size_t *dst_buff_size) {
smx_comm_t comm;
-
+ mc_transition_t trans=NULL;
+
+ if (_surf_do_model_check) {
+ /* Let's intercept the communication and control it from the model-checker */
+ trans = MC_create_transition(mc_irecv, SIMIX_process_self(), rdv, NULL);
+ SIMIX_process_yield();
+ }
+
/* Look for communication request matching our needs.
If it is not found then create it and push it into the rendez-vous point */
comm = SIMIX_rdv_get_request(rdv, comm_send);
comm->dst_buff = dst_buff;
comm->dst_buff_size = dst_buff_size;
+ /* Associate the simix communication to the mc transition */
+ if (_surf_do_model_check)
+ MC_transition_set_comm(trans, comm);
+
SIMIX_communication_start(comm);
return comm;
}
/** @brief blocks until the communication terminates or the timeout occurs */
XBT_INLINE void SIMIX_network_wait(smx_comm_t comm, double timeout) {
+ if (_surf_do_model_check) {
+ /* Let's intercept the communication and control it from the model-checker */
+ MC_create_transition(mc_wait, SIMIX_process_self(), comm->rdv, comm);
+ SIMIX_process_yield();
+ }
/* Wait for communication completion */
SIMIX_communication_wait_for_completion(comm, timeout);
}
/** @Returns whether the (asynchronous) communication is done yet or not */
XBT_INLINE int SIMIX_network_test(smx_comm_t comm) {
+ if (_surf_do_model_check) {
+ /* Let's intercept the communication and control it from the model-checker */
+ MC_create_transition(mc_test, SIMIX_process_self(), comm->rdv, comm);
+ SIMIX_process_yield();
+ }
return comm->sem?SIMIX_sem_would_block(comm->sem):0;
}
unsigned int cursor, found_comm=-1;
smx_comm_t comm,comm_finished=NULL;
+ if (_surf_do_model_check) {
+ /* Let's intercept the communication and control it from the model-checker */
+ MC_create_transition(mc_waitany, SIMIX_process_self(), NULL, NULL);
+ SIMIX_process_yield();
+ }
+
xbt_dynar_foreach(comms,cursor,comm){
xbt_dynar_push(sems,&(comm->sem));
}