Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
forgot to add this file thus breaking the smpi_replay test
[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->init = 1;
15 }
16
17 static void peer_forward_msg(peer_t peer, message_t msg)
18 {
19   msg_task_t task = task_message_data_new(peer->me, peer->next, NULL, 0);
20   msg_comm_t comm = NULL;
21   XBT_DEBUG("Sending (isend) from %s into mailbox %s", peer->me, peer->next);
22   comm = MSG_task_isend(task, peer->next);
23   queue_pending_connection(comm, peer->pending_sends);
24 }
25
26 int peer_execute_task(peer_t peer, msg_task_t task)
27 {
28   int done = 0;
29   message_t msg = MSG_task_get_data(task);
30   
31   XBT_DEBUG("Peer %s got message of type %d\n", peer->me, msg->type);
32   switch (msg->type) {
33     case MESSAGE_BUILD_CHAIN:
34       peer_init_chain(peer, msg);
35       break;
36     case MESSAGE_SEND_DATA:
37       xbt_assert(peer->init, "peer_execute_task() failed: got msg_type %d before initialization", msg->type);
38       if (peer->next != NULL)
39         peer_forward_msg(peer, msg);
40       peer->pieces++;
41       break;
42     case MESSAGE_END_DATA:
43       xbt_assert(peer->init, "peer_execute_task() failed: got msg_type %d before initialization", msg->type);
44       done = 1;
45       XBT_DEBUG("%d pieces receieved", peer->pieces);
46       break;
47   }
48
49   MSG_task_execute(task);
50
51   return done;
52 }
53
54 msg_error_t peer_wait_for_message(peer_t peer)
55 {
56   msg_error_t status;
57   msg_comm_t comm = NULL;
58   msg_task_t task = NULL;
59   int done = 0;
60
61   while (!done) {
62     if (comm == NULL) // FIXME I should have a recv queue
63       comm = MSG_task_irecv(&task, peer->me);
64
65     if (MSG_comm_test(comm)) {
66       status = MSG_comm_get_status(comm);
67       XBT_DEBUG("peer_wait_for_message: error code = %d", status);
68       xbt_assert(status == MSG_OK, "peer_wait_for_message() failed");
69       MSG_comm_destroy(comm);
70       comm = NULL;
71       done = peer_execute_task(peer, task);
72       task_message_delete(task);
73       task = NULL;
74     } else {
75       process_pending_connections(peer->pending_sends);
76       MSG_process_sleep(0.1);
77     }
78   }
79
80   return status;
81 }
82
83 void peer_init(peer_t p, int argc, char *argv[])
84 {
85   p->init = 0;
86   p->prev = NULL;
87   p->next = NULL;
88   p->pieces = 0;
89   p->close_asap = 0;
90   p->pending_sends = xbt_dynar_new(sizeof(msg_comm_t), NULL);
91   p->me = xbt_new(char, HOSTNAME_LENGTH);
92   /* Set mailbox name: use host number from argv or hostname if no argument given */
93   if (argc > 1) {
94     snprintf(p->me, HOSTNAME_LENGTH, "host%s", argv[1]);
95   } else {
96     strncpy(p->me, MSG_host_get_name(MSG_host_self()), HOSTNAME_LENGTH);
97   }
98 }
99
100 void peer_shutdown(peer_t p)
101 {
102   float start_time = MSG_get_clock();
103   float end_time = start_time + PEER_SHUTDOWN_DEADLINE;
104
105   XBT_INFO("Waiting for sends to finish before shutdown...");
106   while (xbt_dynar_length(p->pending_sends) && MSG_get_clock() < end_time) {
107     process_pending_connections(p->pending_sends);
108     MSG_process_sleep(0.1);
109   }
110
111   xbt_assert(xbt_dynar_length(p->pending_sends) == 0, "Shutdown failed, sends still pending after deadline");
112   xbt_dynar_free(&p->pending_sends);
113   xbt_free(p->me);
114
115   xbt_free(p);
116 }
117
118 /** Peer function  */
119 int peer(int argc, char *argv[])
120 {
121   peer_t p = xbt_new(s_peer_t, 1);
122   msg_error_t status;
123
124   XBT_INFO("peer");
125
126   peer_init(p, argc, argv);
127   status = peer_wait_for_message(p);
128   peer_shutdown(p);
129
130   return status;
131 }                               /* end_of_receiver */
132
133