Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
desperate attempt :
[simgrid.git] / examples / msg / chainsend / peer.c
1 /* Copyright (c) 2012-2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
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. */
6
7 #include "peer.h"
8
9 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_peer,
10                              "Messages specific for the peer");
11
12 /*******************************************************
13  *                     Peer                            *
14  *******************************************************/
15
16 void peer_init_chain(peer_t peer, message_t msg)
17 {
18   peer->prev = msg->prev_hostname;
19   peer->next = msg->next_hostname;
20   peer->total_pieces = msg->num_pieces;
21   peer->init = 1;
22 }
23
24 static void peer_forward_msg(peer_t peer, message_t msg)
25 {
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);
31 }
32
33 int peer_execute_task(peer_t peer, msg_task_t task)
34 {
35   int done = 0;
36   message_t msg = MSG_task_get_data(task);
37   
38   XBT_DEBUG("Peer %s got message of type %d\n", peer->me, msg->type);
39   switch (msg->type) {
40     case MESSAGE_BUILD_CHAIN:
41       peer_init_chain(peer, msg);
42       break;
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);
47       peer->pieces++;
48       peer->bytes += msg->data_length;
49       if (peer->pieces >= peer->total_pieces) {
50         XBT_DEBUG("%d pieces receieved", peer->pieces);
51         done = 1;
52       }
53       break;
54   }
55
56   MSG_task_execute(task);
57
58   return done;
59 }
60
61 msg_error_t peer_wait_for_message(peer_t peer)
62 {
63   msg_error_t status;
64   msg_comm_t comm = NULL;
65   msg_task_t task = NULL;
66   int idx = -1;
67   int done = 0;
68
69   while (!done) {
70     comm = MSG_task_irecv(&task, peer->me);
71     queue_pending_connection(comm, peer->pending_recvs);
72
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");
78
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);
83
84       task_message_delete(task);
85       task = NULL;
86     }
87     process_pending_connections(peer->pending_sends);
88   }
89
90   return status;
91 }
92
93 void peer_init(peer_t p, int argc, char *argv[])
94 {
95   p->init = 0;
96   p->prev = NULL;
97   p->next = NULL;
98   p->pieces = 0;
99   p->bytes = 0;
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 */
103   if (argc > 1) {
104     p->me = bprintf("host%s", argv[1]);
105   } else {
106     p->me = xbt_strdup(MSG_host_get_name(MSG_host_self()));
107   }
108 }
109
110 void peer_shutdown(peer_t p)
111 {
112   unsigned int size = xbt_dynar_length(p->pending_sends);
113   unsigned int idx;
114   msg_comm_t *comms = xbt_new(msg_comm_t, size);
115
116   for (idx = 0; idx < size; idx++) {
117     comms[idx] = xbt_dynar_get_as(p->pending_sends, idx, msg_comm_t);
118   }
119
120   XBT_DEBUG("Waiting for sends to finish before shutdown...");
121   MSG_comm_waitall(comms, size, PEER_SHUTDOWN_DEADLINE);
122
123   for (idx = 0; idx < size; idx++) {
124     MSG_comm_destroy(comms[idx]);
125   }
126
127   xbt_free(comms);
128 }
129
130 void peer_delete(peer_t p)
131 {
132   xbt_dynar_free(&p->pending_recvs);
133   xbt_dynar_free(&p->pending_sends);
134   xbt_free(p->me);
135   xbt_free(p->prev);
136   xbt_free(p->next);
137
138   xbt_free(p);
139 }
140
141 void peer_print_stats(peer_t p, float elapsed_time)
142 {
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); 
144 }
145
146 /** Peer function  */
147 int peer(int argc, char *argv[])
148 {
149   float start_time, end_time;
150   peer_t p = xbt_new(s_peer_t, 1);
151   msg_error_t status;
152
153   XBT_DEBUG("peer");
154
155   peer_init(p, argc, argv);
156   start_time = MSG_get_clock();
157   status = peer_wait_for_message(p);
158   peer_shutdown(p);
159   end_time = MSG_get_clock();
160   peer_print_stats(p, end_time - start_time);
161   peer_delete(p);
162
163   return status;
164 }                               /* end_of_receiver */