#define NB_BITS 6
#define NB_KEYS 64
+#define COMM_SIZE 10
+#define COMP_SIZE 0
/**
* Finger element.
}
}
else {
- // a task was received
+ // a transfer has occured
+ MSG_error_t status = MSG_comm_get_status(comm_receive);
MSG_comm_destroy(comm_receive);
comm_receive = NULL;
- const char* task_name = MSG_task_get_name(task);
- task_data_t task_data = (task_data_t) MSG_task_get_data(task);
- if (!strcmp(task_name, "Find Successor")) {
- INFO2("Receiving a 'Find Successor' Request from %s for id %d",
- task_data->issuer_host_name, task_data->request_id);
- // is my successor the successor?
- if (is_in_interval(task_data->request_id, node.id + 1, node.fingers[0].id)) {
- task_data->answer_id = node.fingers[0].id;
- MSG_task_set_name(task, "Find Successor Answer");
- INFO3("Sending back a 'Find Successor Answer' to %s: the successor of %d is %d",
- task_data->issuer_host_name, task_data->request_id, task_data->answer_id);
- comm_send = MSG_task_isend(task, task_data->answer_to);
- xbt_dynar_push(node.comms, &comm_send);
- }
- else {
- // otherwise, forward the request to the closest preceding finger in my table
- int closest = closest_preceding_node(&node, task_data->request_id);
- INFO2("Forwarding the 'Find Successor' request for id %d to my closest preceding finger %d",
- task_data->request_id, closest);
- mailbox = get_mailbox(closest);
- comm_send = MSG_task_isend(task, mailbox);
- xbt_dynar_push(node.comms, &comm_send);
- xbt_free(mailbox);
- }
+ if (status != MSG_OK) {
+ INFO0("Failed to receive a task. Nevermind.");
}
+ else {
+ // the task was successfully received
+ const char* task_name = MSG_task_get_name(task);
+ task_data_t task_data = (task_data_t) MSG_task_get_data(task);
- else if (!strcmp(task_name, "Get Predecessor")) {
- INFO1("Receiving a 'Get Predecessor' Request from %s", task_data->issuer_host_name);
- task_data->answer_id = node.pred_id;
- MSG_task_set_name(task, "Get Predecessor Answer");
- INFO2("Sending back a 'Get Predecessor Answer' to %s: my predecessor is %d",
- task_data->issuer_host_name, task_data->answer_id);
- comm_send = MSG_task_isend(task, task_data->answer_to);
- xbt_dynar_push(node.comms, &comm_send);
- }
- /*
+ if (!strcmp(task_name, "Find Successor")) {
+ INFO2("Receiving a 'Find Successor' request from %s for id %d",
+ task_data->issuer_host_name, task_data->request_id);
+ // is my successor the successor?
+ if (is_in_interval(task_data->request_id, node.id + 1, node.fingers[0].id)) {
+ task_data->answer_id = node.fingers[0].id;
+ MSG_task_set_name(task, "Find Successor Answer");
+ INFO3("Sending back a 'Find Successor Answer' to %s: the successor of %d is %d",
+ task_data->issuer_host_name, task_data->request_id, task_data->answer_id);
+ comm_send = MSG_task_isend(task, task_data->answer_to);
+ xbt_dynar_push(node.comms, &comm_send);
+ }
+ else {
+ // otherwise, forward the request to the closest preceding finger in my table
+ int closest = closest_preceding_node(&node, task_data->request_id);
+ INFO2("Forwarding the 'Find Successor' request for id %d to my closest preceding finger %d",
+ task_data->request_id, closest);
+ mailbox = get_mailbox(closest);
+ comm_send = MSG_task_isend(task, mailbox);
+ xbt_dynar_push(node.comms, &comm_send);
+ xbt_free(mailbox);
+ }
+ }
+
+ else if (!strcmp(task_name, "Get Predecessor")) {
+ INFO1("Receiving a 'Get Predecessor' request from %s", task_data->issuer_host_name);
+ task_data->answer_id = node.pred_id;
+ MSG_task_set_name(task, "Get Predecessor Answer");
+ INFO2("Sending back a 'Get Predecessor Answer' to %s: my predecessor is %d",
+ task_data->issuer_host_name, task_data->answer_id);
+ comm_send = MSG_task_isend(task, task_data->answer_to);
+ xbt_dynar_push(node.comms, &comm_send);
+ }
+ /*
else if (!strcmp(task_name, "Find Predecessor")) {
INFO2("Receiving a 'Find Predecessor' Request from %s for id %d", task_data->issuer_host_name, task_data->request_id);
// am I the predecessor?
xbt_free(mailbox);
}
}
- */
+ */
- /*
+ /*
else if (!strcmp(task_name, "Notify Node Joined")) {
// someone may be my new neighboor
INFO1("Receiving a 'Notify Node Joine' request from %s", task_data->issuer_host_name);
INFO1("Receiving an 'Update Finger' request from %s", task_data->issuer_host_name);
update_finger_table(&node, task_data->request_id, task_data->request_finger);
}
- */
- else if (!strcmp(task_name, "Notify")) {
- // someone is telling me that he may be my new predecessor
- INFO1("Receiving a 'Notify' request from %s", task_data->issuer_host_name);
- notify(&node, task_data->request_id);
- }
- else if (!strcmp(task_name, "Predecessor Leaving")) {
- // my predecessor is about to quit
- INFO1("Receiving a 'Predecessor Leaving' message from %s", task_data->issuer_host_name);
- // modify my predecessor
- set_predecessor(&node, task_data->pred_id);
- /*TODO :
+ */
+ else if (!strcmp(task_name, "Notify")) {
+ // someone is telling me that he may be my new predecessor
+ INFO1("Receiving a 'Notify' request from %s", task_data->issuer_host_name);
+ notify(&node, task_data->request_id);
+ }
+ else if (!strcmp(task_name, "Predecessor Leaving")) {
+ // my predecessor is about to quit
+ INFO1("Receiving a 'Predecessor Leaving' message from %s", task_data->issuer_host_name);
+ // modify my predecessor
+ set_predecessor(&node, task_data->pred_id);
+ /*TODO :
>> notify my new predecessor
>> send a notify_predecessors !!
- */
- }
- else if (!strcmp(task_name, "Successor Leaving")) {
- // my successor is about to quit
- INFO1("Receiving a 'Successor Leaving' message from %s", task_data->issuer_host_name);
- // modify my successor FIXME : this should be implicit ?
- set_finger(&node, 0, task_data->successor_id);
- /* TODO
+ */
+ }
+ else if (!strcmp(task_name, "Successor Leaving")) {
+ // my successor is about to quit
+ INFO1("Receiving a 'Successor Leaving' message from %s", task_data->issuer_host_name);
+ // modify my successor FIXME : this should be implicit ?
+ set_finger(&node, 0, task_data->successor_id);
+ /* TODO
>> notify my new successor
>> update my table & predecessors table */
+ }
}
}
}
int successor_id;
do {
successor_id = remote_find_successor(node, known_id, node->id);
- INFO0("My 'Find Successor' request has failed, let's try again");
+ if (successor_id == -1) {
+ INFO0("I really want to join the ring. Let's try again.");
+ }
} while (successor_id == -1);
set_finger(node, 0, successor_id);
// send a "Notify" request to notify_id
INFO2("Sending a 'Notify' request to %d because I have joined the network with id %d", notify_id, node->id);
- m_task_t task = MSG_task_create("Notify", 1000, 5000, req_data);
+ m_task_t task = MSG_task_create("Notify", COMP_SIZE, COMM_SIZE, req_data);
char* mailbox = get_mailbox(notify_id);
msg_comm_t comm = MSG_task_isend(task, mailbox);
xbt_dynar_push(node->comms, &comm);
task_name = "Predecessor Leaving";
}
- m_task_t task = MSG_task_create(task_name, 1000, 5000, req_data);
+ m_task_t task = MSG_task_create(task_name, COMP_SIZE, COMM_SIZE, req_data);
//char* mailbox = get_mailbox(to_mailbox);
msg_comm_t comm = MSG_task_isend(task, to_mailbox);
xbt_dynar_push(node->comms, &comm);
// send a "Update Finger" request to ask_to_id
INFO3("Sending an 'Update Finger' request to %d: his finger #%d may be %d now", ask_to_id, finger_index, candidate_id);
- m_task_t task = MSG_task_create("Update Finger", 1000, 5000, req_data);
+ m_task_t task = MSG_task_create("Update Finger", COMP_SIZE, COMM_SIZE, req_data);
char* mailbox = get_mailbox(ask_to_id);
msg_comm_t comm = MSG_task_isend(task, mailbox);
xbt_dynar_push(node->comms, &comm);
// send a "Find Successor" request to ask_to_id
INFO2("Sending a 'Find Successor' request to %d for key %d", ask_to, id);
- m_task_t task = MSG_task_create("Find Successor", 1000, 5000, &req_data);
- MSG_error_t res = MSG_task_send_with_timeout(task, get_mailbox(ask_to), 20);
+ m_task_t task = MSG_task_create("Find Successor", COMP_SIZE, COMM_SIZE, &req_data);
+ MSG_error_t res = MSG_task_send_with_timeout(task, get_mailbox(ask_to), 200);
if (res == MSG_OK) {
// receive the answer
task = NULL;
- res = MSG_task_receive_with_timeout(&task, req_data.answer_to, 20);
+ res = MSG_task_receive_with_timeout(&task, req_data.answer_to, 200);
if (res == MSG_OK) {
}
}
+ if (res != MSG_OK) {
+ INFO2("My 'Find Successor' request to node %d for key %d has failed", ask_to, id);
+ }
xbt_free(mailbox);
return successor;
}
// send a "Get Predecessor" request to ask_to_id
INFO1("Sending a 'Get Predecessor' request to %d", ask_to);
- m_task_t task = MSG_task_create("Get Predecessor", 1000, 5000, &req_data);
+ m_task_t task = MSG_task_create("Get Predecessor", COMP_SIZE, COMM_SIZE, &req_data);
MSG_error_t res = MSG_task_send_with_timeout(task, get_mailbox(ask_to), 20);
if (res == MSG_OK) {
}
}
+ if (res != MSG_OK) {
+ INFO1("My 'Get Predecessor' request to node %d has failed", ask_to);
+ }
+
xbt_free(mailbox);
return predecessor_id;
}
// send a "Find Predecessor" request to ask_to
INFO2("Sending a 'Find Predecessor' request to %d for key %d", ask_to, id);
- m_task_t task = MSG_task_create("Find Predecessor", 1000, 5000, &req_data);
+ m_task_t task = MSG_task_create("Find Predecessor", COMP_SIZE, COMM_SIZE, &req_data);
MSG_task_send(task, get_mailbox(ask_to));
// receive the answer
// send a "Notify" request to notify_id
INFO1("Sending a 'Notify' request to %d", notify_id);
- m_task_t task = MSG_task_create("Notify", 1000, 5000, req_data);
+ m_task_t task = MSG_task_create("Notify", COMP_SIZE, COMM_SIZE, req_data);
char* mailbox = get_mailbox(notify_id);
msg_comm_t comm = MSG_task_isend(task, mailbox);
xbt_dynar_push(node->comms, &comm);
<argument value="48"/> <!-- my id -->
<argument value="1"/> <!-- known id -->
<argument value="400"/> <!-- time to sleep before it starts-->
- <argument value ="500"/> <!-- deadline -->
+ <argument value ="5000"/> <!-- deadline -->
</process>
<process host="McGee" function="node">
<argument value="42"/> <!-- my id -->
<argument value="1"/> <!-- known id -->
<argument value="300"/> <!-- time to sleep before it starts-->
- <argument value ="500"/> <!-- deadline -->
+ <argument value ="5000"/> <!-- deadline -->
</process>
<process host="iRMX" function="node">
<argument value="38"/> <!-- my id -->
<argument value="1"/> <!-- known id -->
<argument value="200"/> <!-- time to sleep before it starts-->
- <argument value ="500"/> <!-- deadline -->
+ <argument value ="5000"/> <!-- deadline -->
</process>
<process host="Geoff" function="node">
<argument value="32"/> <!-- my id -->
<argument value="1"/> <!-- known id -->
<argument value="100"/> <!-- time to sleep before it starts-->
- <argument value ="500"/> <!-- deadline -->
+ <argument value ="5000"/> <!-- deadline -->
</process>
<process host="TeX" function="node">
<argument value="21"/> <!-- my id -->
<argument value="1"/> <!-- known id -->
<argument value="40"/> <!-- time to sleep before it starts-->
- <argument value ="500"/> <!-- deadline -->
+ <argument value ="5000"/> <!-- deadline -->
</process>
<process host="Jean_Yves" function="node">
<argument value="14"/> <!-- my id -->
<argument value="1"/> <!-- known id -->
<argument value="16"/> <!-- time to sleep before it starts-->
- <argument value ="500"/> <!-- deadline -->
+ <argument value ="5000"/> <!-- deadline -->
</process>
<process host="Boivin" function="node">
<argument value="8"/> <!-- my id -->
<argument value="1"/> <!-- known id -->
<argument value="1"/> <!-- time to sleep before it starts-->
- <argument value ="500"/> <!-- deadline -->
+ <argument value ="5000"/> <!-- deadline -->
</process>
<process host="Jacquelin" function="node">
<argument value="1"/> <!-- my id -->
- <argument value ="500"/> <!-- deadline -->
+ <argument value ="5000"/> <!-- deadline -->
</process>
</platform>
}
/** \ingroup msg_gos_functions
- * \brief Test the status of a communication.
- *
- * It takes one parameter.
- * \param comm the communication to test.
- * \return the status of the communication:
- * TRUE : the communication is completed
- * FALSE: the communication is incompleted
+ * \brief Returns whether a communication is finished.
+ * \param comm the communication to test
+ * \return TRUE if the communication is finished
+ * (but it may have failed, use MSG_comm_get_status() to know its status)
+ * or FALSE if the communication is not finished yet
* If the status is FALSE, don't forget to use MSG_process_sleep() after the test.
*/
int MSG_comm_test(msg_comm_t comm)
{
- return SIMIX_req_comm_test(comm);
+ xbt_ex_t e;
+ int finished = 0;
+ TRY {
+ finished = SIMIX_req_comm_test(comm);
+ }
+ CATCH(e) {
+ switch (e.category) {
+
+ case host_error:
+ case network_error:
+ case timeout_error:
+ finished = 1;
+ break;
+
+ default:
+ RETHROW;
+ }
+ xbt_ex_free(e);
+ }
+ return finished;
+}
+
+/** \ingroup msg_gos_functions
+ * \brief This function checks if a communication is finished
+ * \param comms a vector of communications
+ * \return the position of the finished communication if any
+ * (but it may have failed, use MSG_comm_get_status() to know its status),
+ * or -1 if none is finished
+ */
+int MSG_comm_testany(xbt_dynar_t comms)
+{
+ xbt_ex_t e;
+ int finished_index = -1;
+ TRY {
+ finished_index = SIMIX_req_comm_testany(comms);
+ }
+ CATCH(e) {
+ switch (e.category) {
+
+ case host_error:
+ case network_error:
+ case timeout_error:
+ finished_index = e.value;
+ break;
+
+ default:
+ RETHROW;
+ }
+ xbt_ex_free(e);
+ }
+ return finished_index;
}
/** \ingroup msg_gos_functions
- * \brief After received TRUE to MSG_comm_test(), the communication must be destroyed.
+ * \brief After received TRUE to MSG_comm_test(), the communication should be destroyed.
*
* It takes one parameter.
* \param comm the communication to destroy.
res = MSG_TIMEOUT;
break;
default:
- xbt_die(bprintf("Unhandled SIMIX network exception: %s", e.msg));
+ RETHROW;
}
xbt_ex_free(e);
}
*/
int MSG_comm_waitany(xbt_dynar_t comms)
{
- return SIMIX_req_comm_waitany(comms);
+ xbt_ex_t e;
+ int finished_index = -1;
+ TRY {
+ finished_index = SIMIX_req_comm_waitany(comms);
+ }
+ CATCH(e) {
+ switch (e.category) {
+
+ case host_error:
+ case network_error:
+ case timeout_error:
+ finished_index = e.value;
+ default:
+ RETHROW;
+ }
+ xbt_ex_free(e);
+ }
+ return finished_index;
}
-/** \ingroup msg_gos_functions
-* \brief This function wait for the first completed communication
-*
-* It takes on parameter.
-* \param comms a vector of communication
-* \return the position of the completed communication, if any, or -1 if none was completed
-*/
-int MSG_comm_testany(xbt_dynar_t comms)
-{
- return SIMIX_req_comm_testany(comms);
+/**
+ * \ingroup msg_gos_functions
+ * \brief Returns the error (if any) that occured during a finished communication.
+ * \param comm a finished communication
+ * \return the status of the communication, or MSG_OK if the communication
+ * was successfully completed
+ */
+MSG_error_t MSG_comm_get_status(msg_comm_t comm) {
+
+ MSG_error_t result;
+ e_smx_state_t smx_state = SIMIX_req_comm_get_state(comm);
+
+ switch (smx_state) {
+
+ case SIMIX_CANCELED:
+ result = MSG_TASK_CANCELLED;
+ break;
+
+ case SIMIX_FAILED:
+ case SIMIX_SRC_HOST_FAILURE:
+ case SIMIX_DST_HOST_FAILURE:
+ result = MSG_HOST_FAILURE;
+ break;
+
+ case SIMIX_LINK_FAILURE:
+ result = MSG_TRANSFER_FAILURE;
+ break;
+
+ case SIMIX_SRC_TIMEOUT:
+ case SIMIX_DST_TIMEOUT:
+ result = MSG_TIMEOUT;
+ break;
+
+ default:
+ result = MSG_OK;
+ break;
+ }
+ return result;
}
m_task_t MSG_comm_get_task(msg_comm_t comm)