Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
ce46e46d9595b05e09785d10acadcd00f596b6f6
[simgrid.git] / src / surf / network_constant.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2004 Arnaud Legrand. All rights reserved.                  */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "surf_private.h"
9 #include "network_common.h"
10 #include "xbt/dict.h"
11 #include "xbt/str.h"
12 #include "xbt/log.h"
13
14 #define CONSTANT_VALUE 1.0
15 typedef struct network_card_Constant {
16   char *name;
17   int id;
18 } s_network_card_Constant_t, *network_card_Constant_t;
19
20 typedef struct network_link_Constant {
21   surf_model_t model;   /* Any such object, added in a trace
22                                    should start by this field!!! */
23   xbt_dict_t properties;
24   /* Using this object with the public part of
25      model does not make sense */
26   char *name;
27   double bw_current;
28   tmgr_trace_event_t bw_event;
29   double lat_current;
30   tmgr_trace_event_t lat_event;
31   e_surf_link_state_t state_current;
32   tmgr_trace_event_t state_event;
33   lmm_constraint_t constraint;
34 } s_link_Constant_t, *link_Constant_t;
35
36 typedef struct surf_action_network_Constant {
37   s_surf_action_t generic_action;
38   double latency;
39   double lat_current;
40   lmm_variable_t variable;
41   double rate;
42   int suspended;
43   network_card_Constant_t src;
44   network_card_Constant_t dst;
45 } s_surf_action_network_Constant_t, *surf_action_network_Constant_t;
46
47 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
48
49 static lmm_system_t network_maxmin_system = NULL;
50 static void (*network_solve) (lmm_system_t) = NULL;
51
52 static int card_number = 0;
53 static int host_number = 0;
54
55 static void link_free(void *nw_link)
56 {
57   free(((link_Constant_t) nw_link)->name);
58   free(nw_link);
59 }
60
61 static link_Constant_t link_new(char *name,
62                             double bw_initial,
63                             tmgr_trace_t bw_trace,
64                             double lat_initial,
65                             tmgr_trace_t lat_trace,
66                             e_surf_link_state_t
67                             state_initial,
68                             tmgr_trace_t state_trace,
69                             e_surf_link_sharing_policy_t
70                             policy, xbt_dict_t properties)
71 {
72   link_Constant_t nw_link = xbt_new0(s_link_Constant_t, 1);
73   xbt_assert1(!xbt_dict_get_or_null(link_set, name), 
74               "Link '%s' declared several times in the platform file.", name);   
75
76   nw_link->model = (surf_model_t) surf_network_model;
77   nw_link->name = name;
78   nw_link->bw_current = bw_initial;
79   if (bw_trace)
80     nw_link->bw_event =
81         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
82   nw_link->lat_current = lat_initial;
83   if (lat_trace)
84     nw_link->lat_event =
85         tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
86   nw_link->state_current = state_initial;
87   if (state_trace)
88     nw_link->state_event =
89         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
90
91   nw_link->constraint =
92       lmm_constraint_new(network_maxmin_system, nw_link,
93                          nw_link->bw_current);
94
95   if (policy == SURF_LINK_FATPIPE)
96     lmm_constraint_shared(nw_link->constraint);
97
98   nw_link->properties = properties;
99
100   current_property_set = properties;
101
102   xbt_dict_set(link_set, name, nw_link, link_free);
103
104   return nw_link;
105 }
106
107 static void network_card_free(void *nw_card)
108 {
109   free(((network_card_Constant_t) nw_card)->name);
110   free(nw_card);
111 }
112
113 static int network_card_new(const char *card_name)
114 {
115   network_card_Constant_t card =
116       xbt_dict_get_or_null(network_card_set, card_name);
117
118   if (!card) {
119     card = xbt_new0(s_network_card_Constant_t, 1);
120     card->name = xbt_strdup(card_name);
121     card->id = card_number++;
122     xbt_dict_set(network_card_set, card_name, card, network_card_free);
123   }
124   return card->id;
125 }
126
127 static void parse_link_init(void)
128 {
129   char *name_link;
130   double bw_initial;
131   tmgr_trace_t bw_trace;
132   double lat_initial;
133   tmgr_trace_t lat_trace;
134   e_surf_link_state_t state_initial_link = SURF_LINK_ON;
135   e_surf_link_sharing_policy_t policy_initial_link = SURF_LINK_SHARED;
136   tmgr_trace_t state_trace;
137
138   name_link = xbt_strdup(A_surfxml_link_id);
139   surf_parse_get_double(&bw_initial, A_surfxml_link_bandwidth);
140   surf_parse_get_trace(&bw_trace, A_surfxml_link_bandwidth_file);
141   surf_parse_get_double(&lat_initial, A_surfxml_link_latency);
142   surf_parse_get_trace(&lat_trace, A_surfxml_link_latency_file);
143
144   xbt_assert0((A_surfxml_link_state ==
145                A_surfxml_link_state_ON)
146               || (A_surfxml_link_state ==
147                   A_surfxml_link_state_OFF), "Invalid state");
148   if (A_surfxml_link_state == A_surfxml_link_state_ON)
149     state_initial_link = SURF_LINK_ON;
150   else if (A_surfxml_link_state ==
151            A_surfxml_link_state_OFF)
152     state_initial_link = SURF_LINK_OFF;
153
154   if (A_surfxml_link_sharing_policy ==
155       A_surfxml_link_sharing_policy_SHARED)
156     policy_initial_link = SURF_LINK_SHARED;
157   else if (A_surfxml_link_sharing_policy ==
158            A_surfxml_link_sharing_policy_FATPIPE)
159     policy_initial_link = SURF_LINK_FATPIPE;
160
161   surf_parse_get_trace(&state_trace, A_surfxml_link_state_file);
162
163   link_new(name_link, bw_initial, bw_trace,
164                    lat_initial, lat_trace, state_initial_link, state_trace,
165                    policy_initial_link, xbt_dict_new());
166
167 }
168
169 static int src_id = -1;
170 static int dst_id = -1;
171
172 static void parse_route_set_endpoints(void)
173 {
174   src_id = network_card_new(A_surfxml_route_src);
175   dst_id = network_card_new(A_surfxml_route_dst);
176   route_action = A_surfxml_route_action;
177   route_link_list = xbt_dynar_new(sizeof(char *), &free_string);
178 }
179
180 static void parse_route_set_route(void)
181 {
182   char *name;
183   if (src_id != -1 && dst_id != -1) {
184     name = bprintf("%x#%x",src_id, dst_id);
185     manage_route(route_table, name, route_action, 0);
186     free(name);    
187   }
188 }
189
190 static void count_hosts(void)
191 {
192    host_number++;
193 }
194
195
196 static void add_traces(void) {
197    xbt_dict_cursor_t cursor=NULL;
198    char *trace_name,*elm;
199    
200    static int called = 0;
201    if (called) return;
202    called = 1;
203
204    /* connect all traces relative to network */
205    xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
206       tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
207       link_Constant_t link = xbt_dict_get_or_null(link_set, elm);
208       
209       xbt_assert1(link, "Link %s undefined", elm);
210       xbt_assert1(trace, "Trace %s undefined", trace_name);
211       
212       link->state_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
213    }
214
215    xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
216       tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
217       link_Constant_t link = xbt_dict_get_or_null(link_set, elm);
218       
219       xbt_assert1(link, "Link %s undefined", elm);
220       xbt_assert1(trace, "Trace %s undefined", trace_name);
221       
222       link->bw_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
223    }
224    
225    xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
226       tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
227       link_Constant_t link = xbt_dict_get_or_null(link_set, elm);
228       
229       xbt_assert1(link, "Link %s undefined", elm);
230       xbt_assert1(trace, "Trace %s undefined", trace_name);
231       
232       link->lat_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
233    }
234
235    xbt_dict_free(&trace_connect_list_host_avail);
236    xbt_dict_free(&trace_connect_list_power);
237    xbt_dict_free(&trace_connect_list_link_avail);
238    xbt_dict_free(&trace_connect_list_bandwidth);
239    xbt_dict_free(&trace_connect_list_latency);
240    
241    xbt_dict_free(&traces_set_list); 
242 }
243
244 static void define_callbacks(const char *file)
245 {
246   /* Figuring out the network links */
247   surfxml_add_callback(STag_surfxml_host_cb_list, &count_hosts);
248   surfxml_add_callback(STag_surfxml_link_cb_list, &parse_link_init);
249   surfxml_add_callback(STag_surfxml_prop_cb_list, &parse_properties);
250   surfxml_add_callback(STag_surfxml_route_cb_list, &parse_route_set_endpoints);
251   surfxml_add_callback(ETag_surfxml_link_c_ctn_cb_list, &parse_route_elem);
252   surfxml_add_callback(ETag_surfxml_route_cb_list, &parse_route_set_route);
253   surfxml_add_callback(STag_surfxml_platform_cb_list, &init_data);
254   surfxml_add_callback(ETag_surfxml_platform_cb_list, &add_traces);
255   surfxml_add_callback(STag_surfxml_set_cb_list, &parse_sets);
256   surfxml_add_callback(STag_surfxml_route_c_multi_cb_list, &parse_route_multi_set_endpoints);
257   surfxml_add_callback(ETag_surfxml_route_c_multi_cb_list, &parse_route_multi_set_route);
258   surfxml_add_callback(STag_surfxml_foreach_cb_list, &parse_foreach);
259   surfxml_add_callback(STag_surfxml_cluster_cb_list, &parse_cluster);
260   surfxml_add_callback(STag_surfxml_trace_cb_list, &parse_trace_init);
261   surfxml_add_callback(ETag_surfxml_trace_cb_list, &parse_trace_finalize);
262   surfxml_add_callback(STag_surfxml_trace_c_connect_cb_list, &parse_trace_c_connect);
263 }
264
265 static void *name_service(const char *name)
266 {
267   network_card_Constant_t card = xbt_dict_get_or_null(network_card_set, name);
268   return card;
269 }
270
271 static const char *get_resource_name(void *resource_id)
272 {
273   return ((network_card_Constant_t) resource_id)->name;
274 }
275
276 static int resource_used(void *resource_id)
277 {
278   return lmm_constraint_used(network_maxmin_system,
279                              ((link_Constant_t) resource_id)->
280                              constraint);
281 }
282
283 static int action_free(surf_action_t action)
284 {
285   action->using--;
286   if (!action->using) {
287     xbt_swag_remove(action, action->state_set);
288     if (((surf_action_network_Constant_t) action)->variable)
289       lmm_variable_free(network_maxmin_system,
290                         ((surf_action_network_Constant_t) action)->variable);
291     free(action);
292     return 1;
293   }
294   return 0;
295 }
296
297 static void action_use(surf_action_t action)
298 {
299   action->using++;
300 }
301
302 static void action_cancel(surf_action_t action)
303 {
304   return;
305 }
306
307 static void action_recycle(surf_action_t action)
308 {
309   return;
310 }
311
312 static void action_change_state(surf_action_t action,
313                                 e_surf_action_state_t state)
314 {
315 /*   if((state==SURF_ACTION_DONE) || (state==SURF_ACTION_FAILED)) */
316 /*     if(((surf_action_network_Constant_t)action)->variable) { */
317 /*       lmm_variable_disable(network_maxmin_system, ((surf_action_network_Constant_t)action)->variable); */
318 /*       ((surf_action_network_Constant_t)action)->variable = NULL; */
319 /*     } */
320
321   surf_action_change_state(action, state);
322   return;
323 }
324
325 static double share_resources(double now)
326 {
327   surf_action_network_Constant_t action = NULL;
328   xbt_swag_t running_actions =
329       surf_network_model->common_public->states.running_action_set;
330   double min = -1.0;
331
332   xbt_swag_foreach(action, running_actions) {
333     if (action->latency > 0) {
334       if (min < 0)
335         min = action->latency;
336       else if (action->latency < min)
337         min = action->latency;
338     }
339   }
340
341   return min;
342 }
343
344 static void update_actions_state(double now, double delta)
345 {
346   surf_action_network_Constant_t action = NULL;
347   surf_action_network_Constant_t next_action = NULL;
348   xbt_swag_t running_actions =
349       surf_network_model->common_public->states.running_action_set;
350
351   xbt_swag_foreach_safe(action, next_action, running_actions) {
352     if (action->latency > 0) {
353       if (action->latency > delta) {
354         double_update(&(action->latency), delta);
355       } else {
356         action->latency = 0.0;
357       }
358     }
359     double_update(&(action->generic_action.remains),
360                   action->generic_action.cost * delta/ CONSTANT_VALUE);
361     if (action->generic_action.max_duration != NO_MAX_DURATION)
362       double_update(&(action->generic_action.max_duration), delta);
363
364     if (action->generic_action.remains <= 0) {
365       action->generic_action.finish = surf_get_clock();
366       action_change_state((surf_action_t) action, SURF_ACTION_DONE);
367     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
368                (action->generic_action.max_duration <= 0)) {
369       action->generic_action.finish = surf_get_clock();
370       action_change_state((surf_action_t) action, SURF_ACTION_DONE);
371     } 
372   }
373
374   return;
375 }
376
377 static void update_resource_state(void *id,
378                                   tmgr_trace_event_t event_type,
379                                   double value)
380 {
381   link_Constant_t nw_link = id;
382   /*   printf("[" "%lg" "] Asking to update network card \"%s\" with value " */
383   /*     "%lg" " for event %p\n", surf_get_clock(), nw_link->name, */
384   /*     value, event_type); */
385
386   if (event_type == nw_link->bw_event) {
387     nw_link->bw_current = value;
388     lmm_update_constraint_bound(network_maxmin_system, nw_link->constraint,
389                                 nw_link->bw_current);
390   } else if (event_type == nw_link->lat_event) {
391     double delta = value - nw_link->lat_current;
392     lmm_variable_t var = NULL;
393     surf_action_network_Constant_t action = NULL;
394
395     nw_link->lat_current = value;
396     while (lmm_get_var_from_cnst
397            (network_maxmin_system, nw_link->constraint, &var)) {
398       action = lmm_variable_id(var);
399       action->lat_current += delta;
400       if (action->rate < 0)
401         lmm_update_variable_bound(network_maxmin_system, action->variable,
402                                   SG_TCP_CTE_GAMMA / (2.0 *
403                                                       action->
404                                                       lat_current));
405       else
406         lmm_update_variable_bound(network_maxmin_system, action->variable,
407                                   min(action->rate,
408                                       SG_TCP_CTE_GAMMA / (2.0 *
409                                                           action->
410                                                           lat_current)));
411       if (!(action->suspended))
412         lmm_update_variable_weight(network_maxmin_system, action->variable,
413                                    action->lat_current);
414       lmm_update_variable_latency(network_maxmin_system, action->variable,
415                                   delta);
416     }
417   } else if (event_type == nw_link->state_event) {
418     if (value > 0)
419       nw_link->state_current = SURF_LINK_ON;
420     else
421       nw_link->state_current = SURF_LINK_OFF;
422   } else {
423     CRITICAL0("Unknown event ! \n");
424     xbt_abort();
425   }
426
427   return;
428 }
429
430 static surf_action_t communicate(void *src, void *dst, double size,
431                                  double rate)
432 {
433   surf_action_network_Constant_t action = NULL;
434   network_card_Constant_t card_src = src;
435   network_card_Constant_t card_dst = dst;
436
437   XBT_IN4("(%s,%s,%g,%g)", card_src->name, card_dst->name, size, rate);
438
439   action = xbt_new0(s_surf_action_network_Constant_t, 1);
440
441   action->generic_action.using = 1;
442   action->generic_action.cost = size;
443   action->generic_action.remains = size;
444   action->generic_action.max_duration = NO_MAX_DURATION;
445   action->generic_action.start = surf_get_clock();
446   action->generic_action.finish = -1.0;
447   action->generic_action.model_type =
448       (surf_model_t) surf_network_model;
449   action->suspended = 0;
450   action->generic_action.state_set =
451       surf_network_model->common_public->states.running_action_set;
452
453   xbt_swag_insert(action, action->generic_action.state_set);
454   action->rate = rate;
455
456   action->latency = CONSTANT_VALUE;
457   action->lat_current = action->latency;
458
459   XBT_OUT;
460
461   return (surf_action_t) action;
462 }
463
464 /* returns an array of link_Constant_t */
465 static const void **get_route(void *src, void *dst)
466 {
467   xbt_assert0(0, "Calling this function does not make any sense");
468   return (const void **) NULL;
469 }
470
471 static int get_route_size(void *src, void *dst)
472 {
473   xbt_assert0(0, "Calling this function does not make any sense");
474   return 0;
475 }
476
477 static const char *get_link_name(const void *link)
478 {
479   return ((link_Constant_t) link)->name;
480 }
481
482 static double get_link_bandwidth(const void *link)
483 {
484   return ((link_Constant_t) link)->bw_current;
485 }
486
487 static double get_link_latency(const void *link)
488 {
489   return ((link_Constant_t) link)->lat_current;
490 }
491
492 static xbt_dict_t get_properties(void *link)
493 {
494  return ((link_Constant_t) link)->properties;
495 }
496
497 static void action_suspend(surf_action_t action)
498 {
499   ((surf_action_network_Constant_t) action)->suspended = 1;
500   lmm_update_variable_weight(network_maxmin_system,
501                              ((surf_action_network_Constant_t) action)->
502                              variable, 0.0);
503 }
504
505 static void action_resume(surf_action_t action)
506 {
507   if (((surf_action_network_Constant_t) action)->suspended) {
508     lmm_update_variable_weight(network_maxmin_system,
509                                ((surf_action_network_Constant_t) action)->
510                                variable,
511                                ((surf_action_network_Constant_t) action)->
512                                lat_current);
513     ((surf_action_network_Constant_t) action)->suspended = 0;
514   }
515 }
516
517 static int action_is_suspended(surf_action_t action)
518 {
519   return ((surf_action_network_Constant_t) action)->suspended;
520 }
521
522 static void action_set_max_duration(surf_action_t action, double duration)
523 {
524   action->max_duration = duration;
525 }
526
527 static void finalize(void)
528 {
529   xbt_dict_free(&network_card_set);
530   xbt_dict_free(&link_set);
531   xbt_swag_free(surf_network_model->common_public->states.
532                 ready_action_set);
533   xbt_swag_free(surf_network_model->common_public->states.
534                 running_action_set);
535   xbt_swag_free(surf_network_model->common_public->states.
536                 failed_action_set);
537   xbt_swag_free(surf_network_model->common_public->states.
538                 done_action_set);
539   free(surf_network_model->common_public);
540   free(surf_network_model->common_private);
541   free(surf_network_model->extension_public);
542
543   free(surf_network_model);
544   surf_network_model = NULL;
545
546   card_number = 0;
547 }
548
549 static void surf_network_model_init_internal(void)
550 {
551   s_surf_action_t action;
552
553   surf_network_model = xbt_new0(s_surf_network_model_t, 1);
554
555   surf_network_model->common_private =
556       xbt_new0(s_surf_model_private_t, 1);
557   surf_network_model->common_public =
558       xbt_new0(s_surf_model_public_t, 1);
559   surf_network_model->extension_public =
560       xbt_new0(s_surf_network_model_extension_public_t, 1);
561
562   surf_network_model->common_public->states.ready_action_set =
563       xbt_swag_new(xbt_swag_offset(action, state_hookup));
564   surf_network_model->common_public->states.running_action_set =
565       xbt_swag_new(xbt_swag_offset(action, state_hookup));
566   surf_network_model->common_public->states.failed_action_set =
567       xbt_swag_new(xbt_swag_offset(action, state_hookup));
568   surf_network_model->common_public->states.done_action_set =
569       xbt_swag_new(xbt_swag_offset(action, state_hookup));
570
571   surf_network_model->common_public->name_service = name_service;
572   surf_network_model->common_public->get_resource_name =
573       get_resource_name;
574   surf_network_model->common_public->action_get_state =
575       surf_action_get_state;
576   surf_network_model->common_public->action_get_start_time =
577       surf_action_get_start_time;
578   surf_network_model->common_public->action_get_finish_time =
579       surf_action_get_finish_time;
580   surf_network_model->common_public->action_free = action_free;
581   surf_network_model->common_public->action_use = action_use;
582   surf_network_model->common_public->action_cancel = action_cancel;
583   surf_network_model->common_public->action_recycle = action_recycle;
584   surf_network_model->common_public->action_change_state =
585       action_change_state;
586   surf_network_model->common_public->action_set_data =
587       surf_action_set_data;
588   surf_network_model->common_public->name = "network";
589
590   surf_network_model->common_private->resource_used = resource_used;
591   surf_network_model->common_private->share_resources = share_resources;
592   surf_network_model->common_private->update_actions_state =
593       update_actions_state;
594   surf_network_model->common_private->update_resource_state =
595       update_resource_state;
596   surf_network_model->common_private->finalize = finalize;
597
598   surf_network_model->common_public->suspend = action_suspend;
599   surf_network_model->common_public->resume = action_resume;
600   surf_network_model->common_public->is_suspended = action_is_suspended;
601   surf_cpu_model->common_public->set_max_duration =
602       action_set_max_duration;
603
604   surf_network_model->extension_public->communicate = communicate;
605   surf_network_model->extension_public->get_route = get_route;
606   surf_network_model->extension_public->get_route_size = get_route_size;
607   surf_network_model->extension_public->get_link_name = get_link_name;
608   surf_network_model->extension_public->get_link_bandwidth =
609       get_link_bandwidth;
610   surf_network_model->extension_public->get_link_latency =
611       get_link_latency;
612
613   surf_network_model->common_public->get_properties =  get_properties;
614
615   link_set = xbt_dict_new();
616   network_card_set = xbt_dict_new();
617
618   if (!network_maxmin_system)
619     network_maxmin_system = lmm_system_new();
620 }
621
622 void surf_network_model_init_Constant(const char *filename)
623 {
624
625   if (surf_network_model)
626     return;
627   surf_network_model_init_internal();
628   define_callbacks(filename);
629   xbt_dynar_push(model_list, &surf_network_model);
630   network_solve = lmm_solve;
631
632   update_model_description(surf_network_model_description,
633                               surf_network_model_description_size,
634                               "Constant",
635                               (surf_model_t) surf_network_model);
636 }