1 /* Copyright (c) 2010. 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. */
10 #include "xbt/sysdep.h" /* calloc, printf */
12 /* Create a log channel to have nice outputs. */
14 #include "xbt/asserts.h"
15 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
16 "Messages specific for this msg example");
18 #define CHORD_NB_KEYS 64
25 const char *host_name;
34 const char *host_name; //my host name
35 const char* mailbox; //my mailbox
36 int fingers_nb; // size of finger list
37 finger_elem* fingers; // finger list [ fingers[0] >> Successor
38 int next; //next finger to fix
39 int pred_id; // predecessor id
40 const char* pred_host_name; // predecessor host name
41 const char* pred_mailbox; // predecessor mailbox
46 static int node(int argc, char *argv[]);
47 static int sender(int argc,char *argv[]);
48 static void find_successor_node(data_node *my_data, m_task_t join_task);
49 static int find_successor(data_node* my_data, int id);
50 static const char* find_closest_preceding(data_node* n_node, int id); //return a mailbox
51 static int get_successor_id(m_host_t);
53 static MSG_error_t test_all(const char *platform_file,
54 const char *application_file);
55 static void init_finger_table(data_node *data, int known_id);
57 static int is_in_interval(unsigned int id, unsigned int start, unsigned int end) {
59 id = id % CHORD_NB_KEYS;
60 start = start % CHORD_NB_KEYS;
61 end = end % CHORD_NB_KEYS;
63 /* make sure end >= start and id >= start */
79 /*<process host="host_name" function="node">
80 <argument value="id"/> <!-- my id -->
81 <argument value="mailbox"/> <!-- mailbox -->
83 <argument value="known_host_name" />
84 <argument value="knwon_host_mailbox" />
85 >argument value="time_to_sleep"/>
89 int node(int argc, char *argv[])
91 m_task_t recv_request = NULL;
95 if ( argc == 3) // if no known host are declared >>> first node >>> create chord ring
100 //int id = atoi(argv[1]);
101 //int mailbox = atoi(argv[2]);
103 data_node *data = xbt_new(data_node,1);
104 data->host_name = MSG_host_get_name(MSG_host_self());
105 data->id = atoi(argv[1]);
106 data->mailbox = argv[2];
107 data->fingers_nb = 1;
108 data->fingers = xbt_new(finger_elem,KEY_BITS);
109 data->fingers[0].host_name = data->host_name;
110 data->fingers[0].id = data->id;
111 data->fingers[0].mailbox = data->mailbox;
113 data->pred_host_name = NULL;
115 data->pred_mailbox = NULL;
118 * Ring Point Entry Node
120 if (create) // first ring
122 INFO0("Create new Chord Ring...");
126 data->fingers[0].host_name = data->host_name;
127 data->fingers[0].id = data->id;
128 data->fingers[0].mailbox = data->mailbox;
129 while(cpt < MSG_get_host_number()-1) //make condition!!!
132 res = MSG_task_receive(&(recv_request),data->mailbox);
133 xbt_assert0(res == MSG_OK, "MSG_receiev failed");
134 if (!strcmp(MSG_task_get_name(recv_request), "Join Call"))
136 if(MSG_task_get_data(recv_request)==NULL)
138 WARN0("Receiving an Empty Data");
140 data_node *recv_data = (data_node*)MSG_task_get_data(recv_request);
141 INFO1("Receiving a Join Call from %s",recv_data->host_name);
144 // predecessor(recv_data) >>>> data
145 recv_data->pred_host_name = data->host_name;
146 recv_data->pred_id = data->id;
147 recv_data->pred_mailbox = data->mailbox;
148 data->fingers_nb = 1;
149 // successor(recv_data) >>> data
150 recv_data->fingers[0].id = data->id;
151 recv_data->fingers[0].host_name = data->host_name;
152 recv_data->fingers[0].mailbox = data->mailbox;
153 //successor(data) >>>> recv_data
154 data->fingers[data->fingers_nb - 1].host_name = recv_data->host_name;
155 data->fingers[data->fingers_nb - 1].id = recv_data->id;
156 data->fingers[data->fingers_nb - 1].mailbox = recv_data->mailbox;
157 INFO1("Sending back a Join Request to %s",recv_data->host_name);
158 MSG_task_set_name(recv_request,"Join Response");
159 MSG_task_send(recv_request,recv_data->mailbox);
163 find_successor_node(data,recv_request);
174 //Sleep Before Starting
175 INFO1("Let's Sleep >>%i",atoi(argv[6]));
176 MSG_process_sleep(atoi(argv[5]));
177 INFO0("Hey! Let's Send a Join Request");
178 //send a join task to the known host via its(known host) mailbox
179 const char* known_host_name = argv[3];
180 const char* known_mailbox = argv[4];
181 int known_id = atoi(argv[5]);
182 m_task_t join_request = MSG_task_create("Join Call",10000,2000,data); // define comp size and comm size (#define ...)
183 INFO2("Sending a join request to %s via mailbox %s",known_host_name,known_mailbox);
184 MSG_task_send(join_request,known_mailbox);
185 //wait for answer on my mailbox
186 while(cpt < MSG_get_host_number()-1)
189 int res = MSG_task_receive(&(recv_request),data->mailbox);
190 //check if it's the response for my request
191 xbt_assert0(res == MSG_OK, "MSG_receiev failed");
193 data_node *recv_data = (data_node*)MSG_task_get_data(recv_request);
195 if(!strcmp(MSG_task_get_name(recv_request), "Join Call"))
198 INFO1("Receiving Join Call From %s",recv_data->host_name);
201 INFO1("Sorry %s... I'm not yet joined",recv_data->host_name);
203 MSG_task_set_name(recv_request,"Join Failed");
204 MSG_task_send(recv_request,recv_data->mailbox);
208 find_successor_node(data,recv_request);
213 else if(!strcmp(MSG_task_get_name(recv_request), "Join Response"))
215 INFO0("Receiving Join Response!!!");
216 INFO1("My successor is : %s",data->fingers[0].host_name);
217 INFO1("My Predecessor is : %s",data->pred_host_name);
220 INFO1("My finger table size : %i",data->fingers_nb);
221 INFO0("***********************************************************************");
224 MSG_task_set_name(recv_request,"Fix Fingers");
226 MSG_task_send(recv_request,data->pred_mailbox);
227 MSG_task_send(recv_request,data->fingers[0].mailbox);
229 init_finger_table(data, known_id);
233 // Join Failure Message
234 else if(!strcmp(MSG_task_get_name(recv_request), "Join Failed"))
236 INFO0("My Join call has failed... let's Try Again");
238 //MSG_task_send(join_request,known_mailbox);
239 // !!!!!!!!! YVes Jaques Always...???ยงยงยงยง**************************
242 else if(!strcmp(MSG_task_get_name(recv_request), "Fix Fingers"))
245 for(i = KEY_BITS -1 ; i>= 0;i--)
247 //data->fingers[i] = find_finger_elem(data,(data->id)+pow(2,i-1));
258 void init_finger_table(data_node *node, int known_id) {
260 // ask known_id who is my immediate successor
261 // data->fingers[0].id = remote_find_successor(known_id, data->id + 1);
267 void find_successor_node(data_node* n_data,m_task_t join_task) //use all data
270 data_node *recv_data = (data_node*)MSG_task_get_data(join_task);
271 INFO3("recv_data->id : %i , n_data->id :%i , successor->id :%i",recv_data->id,n_data->id,n_data->fingers[0].id);
272 //if ((recv_data->id >= n_data->id) && (recv_data->id <= n_data->fingers[0].id))
273 if (is_in_interval(recv_data->id,n_data->id,n_data->fingers[0].id))
275 INFO1("Successor Is %s",n_data->fingers[0].host_name);
276 //predecessor(recv_data) >>>> n_data
277 recv_data->pred_host_name = n_data->host_name;
278 recv_data->pred_id = n_data->id;
279 recv_data->pred_mailbox = n_data->pred_mailbox;
280 // successor(recv_data) >>>> n_data.finger[0]
281 recv_data->fingers_nb = 1;
282 recv_data->fingers[0].host_name = n_data->fingers[0].host_name;
283 recv_data->fingers[0].id = n_data->fingers[0].id;
284 recv_data->fingers[0].mailbox = n_data->fingers[0].mailbox;
285 // successor(n_data) >>>> recv_sucessor
286 n_data->fingers[0].id = recv_data->id;
287 n_data->fingers[0].host_name = recv_data->host_name;
288 n_data->fingers[0].mailbox = recv_data->mailbox;
290 INFO1("Sending back a Join Request to %s",recv_data->host_name);
291 MSG_task_set_name(join_task,"Join Response");
292 MSG_task_send(join_task,recv_data->mailbox);
297 const char* closest_preceding_mailbox = find_closest_preceding(n_data,recv_data->id);
298 INFO1("Forwarding Join Call to mailbox %s",closest_preceding_mailbox);
299 MSG_task_send(join_task,closest_preceding_mailbox);
303 const char* find_closest_preceding(data_node* n_node,int id)
306 for(i = n_node->fingers_nb-1; i >= 0 ; i--)
308 if (n_node->fingers[i].id <= id)
309 return n_node->fingers[i].mailbox;
312 return n_node->mailbox; // !!!!!!!!!!!!!!
315 * Fin successor id : used to fix finger list
317 static int find_successor(data_node* n_data, int id)
319 if (is_in_interval(id,n_data->id,n_data->fingers[0].id))
320 return n_data->fingers[0].id;
328 MSG_error_t test_all(const char *platform_file,
329 const char *application_file)
331 MSG_error_t res = MSG_OK;
333 /* MSG_config("workstation/model","KCCFLN05"); */
334 { /* Simulation setting */
335 MSG_set_channel_number(0);
336 MSG_create_environment(platform_file);
339 { /* Application deployment */
340 MSG_function_register("node",node);
341 MSG_launch_application(application_file);
344 INFO1("Simulation time %g", MSG_get_clock());
347 } /* end_of_test_all */
350 int main(int argc, char *argv[])
352 MSG_error_t res = MSG_OK;
354 MSG_global_init(&argc, argv);
356 printf("Usage: %s platform_file deployment_file\n", argv[0]);
357 printf("example: %s msg_platform.xml msg_deployment.xml\n", argv[0]);
360 res = test_all(argv[1], argv[2]);