Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Make this example clean for valgrind.
[simgrid.git] / examples / msg / chainsend / peer.c
1 #include "peer.h"
2
3 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_peer,
4                              "Messages specific for the peer");
5
6 /*******************************************************
7  *                     Peer                            *
8  *******************************************************/
9
10 void peer_init_chain(peer_t peer, message_t msg)
11 {
12   peer->prev = msg->prev_hostname;
13   peer->next = msg->next_hostname;
14   peer->total_pieces = msg->num_pieces;
15   peer->init = 1;
16 }
17
18 static void peer_forward_msg(peer_t peer, message_t msg)
19 {
20   msg_task_t task = task_message_data_new(peer->me, peer->next, NULL, msg->data_length);
21   msg_comm_t comm = NULL;
22   XBT_DEBUG("Sending (isend) from %s into mailbox %s", peer->me, peer->next);
23   comm = MSG_task_isend(task, peer->next);
24   queue_pending_connection(comm, peer->pending_sends);
25 }
26
27 int peer_execute_task(peer_t peer, msg_task_t task)
28 {
29   int done = 0;
30   message_t msg = MSG_task_get_data(task);
31   
32   XBT_DEBUG("Peer %s got message of type %d\n", peer->me, msg->type);
33   switch (msg->type) {
34     case MESSAGE_BUILD_CHAIN:
35       peer_init_chain(peer, msg);
36       break;
37     case MESSAGE_SEND_DATA:
38       xbt_assert(peer->init, "peer_execute_task() failed: got msg_type %d before initialization", msg->type);
39       if (peer->next != NULL)
40         peer_forward_msg(peer, msg);
41       peer->pieces++;
42       peer->bytes += msg->data_length;
43       if (peer->pieces >= peer->total_pieces) {
44         XBT_DEBUG("%d pieces receieved", peer->pieces);
45         done = 1;
46       }
47       break;
48   }
49
50   MSG_task_execute(task);
51
52   return done;
53 }
54
55 msg_error_t peer_wait_for_message(peer_t peer)
56 {
57   msg_error_t status;
58   msg_comm_t comm = NULL;
59   msg_task_t task = NULL;
60   int idx = -1;
61   int done = 0;
62
63   while (!done) {
64     comm = MSG_task_irecv(&task, peer->me);
65     queue_pending_connection(comm, peer->pending_recvs);
66
67     if ((idx = MSG_comm_waitany(peer->pending_recvs)) != -1) {
68       comm = xbt_dynar_get_as(peer->pending_recvs, idx, msg_comm_t);
69       status = MSG_comm_get_status(comm);
70       XBT_DEBUG("peer_wait_for_message: error code = %d", status);
71       xbt_assert(status == MSG_OK, "peer_wait_for_message() failed");
72
73       task = MSG_comm_get_task(comm);
74       MSG_comm_destroy(comm);
75       xbt_dynar_cursor_rm(peer->pending_recvs, (unsigned int*)&idx);
76       done = peer_execute_task(peer, task);
77
78       task_message_delete(task);
79       task = NULL;
80     }
81     process_pending_connections(peer->pending_sends);
82   }
83
84   return status;
85 }
86
87 void peer_init(peer_t p, int argc, char *argv[])
88 {
89   p->init = 0;
90   p->prev = NULL;
91   p->next = NULL;
92   p->pieces = 0;
93   p->bytes = 0;
94   p->pending_recvs = xbt_dynar_new(sizeof(msg_comm_t), NULL);
95   p->pending_sends = xbt_dynar_new(sizeof(msg_comm_t), NULL);
96   /* Set mailbox name: use host number from argv or hostname if no argument given */
97   if (argc > 1) {
98     p->me = bprintf("host%s", argv[1]);
99   } else {
100     p->me = xbt_strdup(MSG_host_get_name(MSG_host_self()));
101   }
102 }
103
104 void peer_shutdown(peer_t p)
105 {
106   unsigned int size = xbt_dynar_length(p->pending_sends);
107   unsigned int idx;
108   msg_comm_t *comms = xbt_new(msg_comm_t, size);
109
110   for (idx = 0; idx < size; idx++) {
111     comms[idx] = xbt_dynar_get_as(p->pending_sends, idx, msg_comm_t);
112   }
113
114   XBT_DEBUG("Waiting for sends to finish before shutdown...");
115   MSG_comm_waitall(comms, size, PEER_SHUTDOWN_DEADLINE);
116
117   for (idx = 0; idx < size; idx++) {
118     MSG_comm_destroy(comms[idx]);
119   }
120
121   xbt_free(comms);
122 }
123
124 void peer_delete(peer_t p)
125 {
126   xbt_dynar_free(&p->pending_recvs);
127   xbt_dynar_free(&p->pending_sends);
128   xbt_free(p->me);
129   xbt_free(p->prev);
130   xbt_free(p->next);
131
132   xbt_free(p);
133 }
134
135 void peer_print_stats(peer_t p, float elapsed_time)
136 {
137   XBT_INFO("### %f %llu bytes (Avg %f MB/s); copy finished (simulated).", elapsed_time, p->bytes, p->bytes / 1024.0 / 1024.0 / elapsed_time); 
138 }
139
140 /** Peer function  */
141 int peer(int argc, char *argv[])
142 {
143   float start_time, end_time;
144   peer_t p = xbt_new(s_peer_t, 1);
145   msg_error_t status;
146
147   XBT_DEBUG("peer");
148
149   peer_init(p, argc, argv);
150   start_time = MSG_get_clock();
151   status = peer_wait_for_message(p);
152   peer_shutdown(p);
153   end_time = MSG_get_clock();
154   peer_print_stats(p, end_time - start_time);
155   peer_delete(p);
156
157   return status;
158 }                               /* end_of_receiver */