1 /* Copyright (c) 2012-2014. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
9 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_peer,
10 "Messages specific for the peer");
12 /*******************************************************
14 *******************************************************/
16 void peer_init_chain(peer_t peer, message_t msg)
18 peer->prev = msg->prev_hostname;
19 peer->next = msg->next_hostname;
20 peer->total_pieces = msg->num_pieces;
24 static void peer_forward_msg(peer_t peer, message_t msg)
26 msg_task_t task = task_message_data_new(NULL, msg->data_length);
27 msg_comm_t comm = NULL;
28 XBT_DEBUG("Sending (isend) from %s into mailbox %s", peer->me, peer->next);
29 comm = MSG_task_isend(task, peer->next);
30 queue_pending_connection(comm, peer->pending_sends);
33 int peer_execute_task(peer_t peer, msg_task_t task)
36 message_t msg = MSG_task_get_data(task);
38 XBT_DEBUG("Peer %s got message of type %d\n", peer->me, msg->type);
40 case MESSAGE_BUILD_CHAIN:
41 peer_init_chain(peer, msg);
43 case MESSAGE_SEND_DATA:
44 xbt_assert(peer->init, "peer_execute_task() failed: got msg_type %d before initialization", msg->type);
45 if (peer->next != NULL)
46 peer_forward_msg(peer, msg);
48 peer->bytes += msg->data_length;
49 if (peer->pieces >= peer->total_pieces) {
50 XBT_DEBUG("%d pieces receieved", peer->pieces);
56 MSG_task_execute(task);
61 msg_error_t peer_wait_for_message(peer_t peer)
64 msg_comm_t comm = NULL;
65 msg_task_t task = NULL;
70 comm = MSG_task_irecv(&task, peer->me);
71 queue_pending_connection(comm, peer->pending_recvs);
73 if ((idx = MSG_comm_waitany(peer->pending_recvs)) != -1) {
74 comm = xbt_dynar_get_as(peer->pending_recvs, idx, msg_comm_t);
75 status = MSG_comm_get_status(comm);
76 XBT_DEBUG("peer_wait_for_message: error code = %d", status);
77 xbt_assert(status == MSG_OK, "peer_wait_for_message() failed");
79 task = MSG_comm_get_task(comm);
80 MSG_comm_destroy(comm);
81 xbt_dynar_cursor_rm(peer->pending_recvs, (unsigned int*)&idx);
82 done = peer_execute_task(peer, task);
84 task_message_delete(task);
87 process_pending_connections(peer->pending_sends);
93 void peer_init(peer_t p, int argc, char *argv[])
100 p->pending_recvs = xbt_dynar_new(sizeof(msg_comm_t), NULL);
101 p->pending_sends = xbt_dynar_new(sizeof(msg_comm_t), NULL);
102 /* Set mailbox name: use host number from argv or hostname if no argument given */
104 p->me = bprintf("host%s", argv[1]);
106 p->me = xbt_strdup(MSG_host_get_name(MSG_host_self()));
110 void peer_shutdown(peer_t p)
112 unsigned int size = xbt_dynar_length(p->pending_sends);
114 msg_comm_t *comms = xbt_new(msg_comm_t, size);
116 for (idx = 0; idx < size; idx++) {
117 comms[idx] = xbt_dynar_get_as(p->pending_sends, idx, msg_comm_t);
120 XBT_DEBUG("Waiting for sends to finish before shutdown...");
121 MSG_comm_waitall(comms, size, PEER_SHUTDOWN_DEADLINE);
123 for (idx = 0; idx < size; idx++) {
124 MSG_comm_destroy(comms[idx]);
130 void peer_delete(peer_t p)
132 xbt_dynar_free(&p->pending_recvs);
133 xbt_dynar_free(&p->pending_sends);
141 void peer_print_stats(peer_t p, float elapsed_time)
143 XBT_INFO("### %f %llu bytes (Avg %f MB/s); copy finished (simulated).", elapsed_time, p->bytes, p->bytes / 1024.0 / 1024.0 / elapsed_time);
147 int peer(int argc, char *argv[])
149 float start_time, end_time;
150 peer_t p = xbt_new(s_peer_t, 1);
155 peer_init(p, argc, argv);
156 start_time = MSG_get_clock();
157 status = peer_wait_for_message(p);
159 end_time = MSG_get_clock();
160 peer_print_stats(p, end_time - start_time);
164 } /* end_of_receiver */