Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
ba86991b35960a1c6856cd326491f4dce1031e0f
[simgrid.git] / src / surf / workstation_ptask_L07.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2007 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 "xbt/ex.h"
9 #include "xbt/dict.h"
10 #include "surf_private.h"
11
12 typedef enum {
13   SURF_WORKSTATION_RESOURCE_CPU,
14   SURF_WORKSTATION_RESOURCE_LINK,
15 } e_surf_workstation_resource_type_t;
16
17 /**************************************/
18 /********* cpu object *****************/
19 /**************************************/
20 typedef struct cpu_L07 {
21   surf_resource_t resource;     /* Do not move this field */
22   e_surf_workstation_resource_type_t type;      /* Do not move this field */
23   char *name;                   /* Do not move this field */
24   lmm_constraint_t constraint;  /* Do not move this field */
25   double power_scale;
26   double power_current;
27   tmgr_trace_event_t power_event;
28   e_surf_cpu_state_t state_current;
29   tmgr_trace_event_t state_event;
30   int id;                       /* cpu and network card are a single object... */
31 } s_cpu_L07_t, *cpu_L07_t;
32
33 /**************************************/
34 /*********** network object ***********/
35 /**************************************/
36
37 typedef struct network_link_L07 {
38   surf_resource_t resource;     /* Do not move this field */
39   e_surf_workstation_resource_type_t type;      /* Do not move this field */
40   char *name;                   /* Do not move this field */
41   lmm_constraint_t constraint;  /* Do not move this field */
42   double bw_current;
43   tmgr_trace_event_t bw_event;
44   e_surf_network_link_state_t state_current;
45   tmgr_trace_event_t state_event;
46 } s_network_link_L07_t, *network_link_L07_t;
47
48
49 typedef struct s_route_L07 {
50   network_link_L07_t *links;
51   int size;
52 } s_route_L07_t, *route_L07_t;
53
54 /**************************************/
55 /*************** actions **************/
56 /**************************************/
57 typedef struct surf_action_workstation_L07 {
58   s_surf_action_t generic_action;
59   lmm_variable_t variable;
60   double rate;
61   int suspended;
62 } s_surf_action_workstation_L07_t, *surf_action_workstation_L07_t;
63
64
65 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_workstation);
66
67 static int nb_workstation = 0;
68 static s_route_L07_t *routing_table = NULL;
69 #define ROUTE(i,j) routing_table[(i)+(j)*nb_workstation]
70 static network_link_L07_t loopback = NULL;
71 static xbt_dict_t parallel_task_network_link_set = NULL;
72 lmm_system_t ptask_maxmin_system = NULL;
73
74 /**************************************/
75 /******* Resource Public     **********/
76 /**************************************/
77
78 static void *name_service(const char *name)
79 {
80   return xbt_dict_get_or_null(workstation_set, name);
81 }
82
83 static const char *get_resource_name(void *resource_id)
84 {
85   /* We can freely cast as a cpu_L07_t because it has the same
86      prefix as network_link_L07_t. However, only cpu_L07_t
87      will theoretically be given as an argument here. */
88   return ((cpu_L07_t) resource_id)->name;
89 }
90
91 /* action_get_state is inherited from the surf module */
92
93 static void action_use(surf_action_t action)
94 {
95   action->using++;
96   return;
97 }
98
99 static int action_free(surf_action_t action)
100 {
101   action->using--;
102
103   if (!action->using) {
104     xbt_swag_remove(action, action->state_set);
105     if (((surf_action_workstation_L07_t) action)->variable)
106       lmm_variable_free(ptask_maxmin_system,
107                         ((surf_action_workstation_L07_t) action)->
108                         variable);
109     free(action);
110     return 1;
111   }
112   return 0;
113 }
114
115 static void action_cancel(surf_action_t action)
116 {
117   surf_action_change_state(action, SURF_ACTION_FAILED);
118   return;
119 }
120
121 static void action_recycle(surf_action_t action)
122 {
123   DIE_IMPOSSIBLE;
124   return;
125 }
126
127 /* action_change_state is inherited from the surf module */
128 /* action_set_data is inherited from the surf module */
129
130 static void action_suspend(surf_action_t action)
131 {
132   XBT_IN1("(%p))", action);
133   if (((surf_action_workstation_L07_t) action)->suspended != 2) {
134     ((surf_action_workstation_L07_t) action)->suspended = 1;
135     lmm_update_variable_weight(ptask_maxmin_system,
136                                ((surf_action_workstation_L07_t)
137                                 action)->variable, 0.0);
138   }
139   XBT_OUT;
140 }
141
142 static void action_resume(surf_action_t action)
143 {
144   XBT_IN1("(%p)", action);
145   if (((surf_action_workstation_L07_t) action)->suspended != 2) {
146     lmm_update_variable_weight(ptask_maxmin_system,
147                                ((surf_action_workstation_L07_t)
148                                 action)->variable, 1.0);
149     ((surf_action_workstation_L07_t) action)->suspended = 0;
150   }
151   XBT_OUT;
152 }
153
154 static int action_is_suspended(surf_action_t action)
155 {
156   return (((surf_action_workstation_L07_t) action)->suspended == 1);
157 }
158
159 static void action_set_max_duration(surf_action_t action, double duration)
160 {                               /* FIXME: should inherit */
161   XBT_IN2("(%p,%g)", action, duration);
162   action->max_duration = duration;
163   XBT_OUT;
164 }
165
166
167 static void action_set_priority(surf_action_t action, double priority)
168 {                               /* FIXME: should inherit */
169   XBT_IN2("(%p,%g)", action, priority);
170   action->priority = priority;
171   XBT_OUT;
172 }
173
174 /**************************************/
175 /******* Resource Private    **********/
176 /**************************************/
177
178 static int resource_used(void *resource_id)
179 {
180   /* We can freely cast as a network_link_L07_t because it has
181      the same prefix as cpu_L07_t */
182   return lmm_constraint_used(ptask_maxmin_system,
183                              ((network_link_L07_t) resource_id)->
184                              constraint);
185
186 }
187
188 static double share_resources(double now)
189 {
190   s_surf_action_workstation_L07_t s_action;
191
192   xbt_swag_t running_actions =
193       surf_workstation_resource->common_public->states.running_action_set;
194   double min = generic_maxmin_share_resources2(running_actions,
195                                                xbt_swag_offset(s_action,
196                                                                variable),
197                                                ptask_maxmin_system,
198                                                bottleneck_solve);
199
200   DEBUG1("min value : %f", min);
201
202   return min;
203 }
204
205 static void update_actions_state(double now, double delta)
206 {
207   surf_action_workstation_L07_t action = NULL;
208   surf_action_workstation_L07_t next_action = NULL;
209   xbt_swag_t running_actions =
210       surf_workstation_resource->common_public->states.running_action_set;
211
212   xbt_swag_foreach_safe(action, next_action, running_actions) {
213     DEBUG3("Action (%p) : remains (%g) updated by %g.",
214            action, action->generic_action.remains,
215            lmm_variable_getvalue(action->variable) * delta);
216     double_update(&(action->generic_action.remains),
217                   lmm_variable_getvalue(action->variable) * delta);
218
219     if (action->generic_action.max_duration != NO_MAX_DURATION)
220       double_update(&(action->generic_action.max_duration), delta);
221
222     if ((action->generic_action.remains <= 0) &&
223         (lmm_get_variable_weight(action->variable) > 0)) {
224       action->generic_action.finish = surf_get_clock();
225       surf_action_change_state((surf_action_t) action, SURF_ACTION_DONE);
226     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
227                (action->generic_action.max_duration <= 0)) {
228       action->generic_action.finish = surf_get_clock();
229       surf_action_change_state((surf_action_t) action, SURF_ACTION_DONE);
230     } else {
231       /* Need to check that none of the resource has failed */
232       lmm_constraint_t cnst = NULL;
233       int i = 0;
234       void *constraint_id = NULL;
235
236       while ((cnst =
237               lmm_get_cnst_from_var(ptask_maxmin_system, action->variable,
238                                     i++))) {
239         constraint_id = lmm_constraint_id(cnst);
240
241 /*      if(((network_link_L07_t)constraint_id)->type== */
242 /*         SURF_WORKSTATION_RESOURCE_LINK) { */
243 /*        DEBUG2("Checking for link %s (%p)", */
244 /*               ((network_link_L07_t)constraint_id)->name, */
245 /*               ((network_link_L07_t)constraint_id)); */
246 /*      } */
247 /*      if(((cpu_L07_t)constraint_id)->type== */
248 /*         SURF_WORKSTATION_RESOURCE_CPU) { */
249 /*        DEBUG3("Checking for cpu %s (%p) : %s", */
250 /*               ((cpu_L07_t)constraint_id)->name, */
251 /*               ((cpu_L07_t)constraint_id), */
252 /*               ((cpu_L07_t)constraint_id)->state_current==SURF_CPU_OFF?"Off":"On"); */
253 /*      } */
254
255         if (((((network_link_L07_t) constraint_id)->type ==
256               SURF_WORKSTATION_RESOURCE_LINK) &&
257              (((network_link_L07_t) constraint_id)->state_current ==
258               SURF_NETWORK_LINK_OFF)) ||
259             ((((cpu_L07_t) constraint_id)->type ==
260               SURF_WORKSTATION_RESOURCE_CPU) &&
261              (((cpu_L07_t) constraint_id)->state_current ==
262               SURF_CPU_OFF))) {
263           DEBUG1("Action (%p) Failed!!", action);
264           action->generic_action.finish = surf_get_clock();
265           surf_action_change_state((surf_action_t) action,
266                                    SURF_ACTION_FAILED);
267           break;
268         }
269       }
270     }
271   }
272   return;
273 }
274
275 static void update_resource_state(void *id,
276                                   tmgr_trace_event_t event_type,
277                                   double value)
278 {
279   cpu_L07_t cpu = id;
280   network_link_L07_t nw_link = id;
281
282   if (nw_link->type == SURF_WORKSTATION_RESOURCE_LINK) {
283     DEBUG2("Updating link %s (%p)", nw_link->name, nw_link);
284     if (event_type == nw_link->bw_event) {
285       nw_link->bw_current = value;
286       lmm_update_constraint_bound(ptask_maxmin_system, nw_link->constraint,
287                                   nw_link->bw_current);
288     } else if (event_type == nw_link->state_event) {
289       if (value > 0)
290         nw_link->state_current = SURF_NETWORK_LINK_ON;
291       else
292         nw_link->state_current = SURF_NETWORK_LINK_OFF;
293     } else {
294       CRITICAL0("Unknown event ! \n");
295       xbt_abort();
296     }
297     return;
298   } else if (cpu->type == SURF_WORKSTATION_RESOURCE_CPU) {
299     DEBUG3("Updating cpu %s (%p) with value %g", cpu->name, cpu, value);
300     if (event_type == cpu->power_event) {
301       cpu->power_current = value;
302       lmm_update_constraint_bound(ptask_maxmin_system, cpu->constraint,
303                                   cpu->power_current);
304     } else if (event_type == cpu->state_event) {
305       if (value > 0)
306         cpu->state_current = SURF_CPU_ON;
307       else
308         cpu->state_current = SURF_CPU_OFF;
309     } else {
310       CRITICAL0("Unknown event ! \n");
311       xbt_abort();
312     }
313     return;
314   } else {
315     DIE_IMPOSSIBLE;
316   }
317   return;
318 }
319
320 static void finalize(void)
321 {
322   int i, j;
323
324   xbt_dict_free(&network_link_set);
325   xbt_dict_free(&workstation_set);
326   if (parallel_task_network_link_set != NULL) {
327     xbt_dict_free(&parallel_task_network_link_set);
328   }
329   xbt_swag_free(surf_workstation_resource->common_public->states.
330                 ready_action_set);
331   xbt_swag_free(surf_workstation_resource->common_public->states.
332                 running_action_set);
333   xbt_swag_free(surf_workstation_resource->common_public->states.
334                 failed_action_set);
335   xbt_swag_free(surf_workstation_resource->common_public->states.
336                 done_action_set);
337
338   free(surf_workstation_resource->common_public);
339   free(surf_workstation_resource->common_private);
340   free(surf_workstation_resource->extension_public);
341
342   free(surf_workstation_resource);
343   surf_workstation_resource = NULL;
344
345   for (i = 0; i < nb_workstation; i++)
346     for (j = 0; j < nb_workstation; j++)
347       free(ROUTE(i, j).links);
348   free(routing_table);
349   routing_table = NULL;
350   nb_workstation = 0;
351
352   if (ptask_maxmin_system) {
353     lmm_system_free(ptask_maxmin_system);
354     ptask_maxmin_system = NULL;
355   }
356 }
357
358 /**************************************/
359 /******* Resource Private    **********/
360 /**************************************/
361
362 static e_surf_cpu_state_t resource_get_state(void *cpu)
363 {
364   return ((cpu_L07_t) cpu)->state_current;
365 }
366
367 static double get_speed(void *cpu, double load)
368 {
369   return load * (((cpu_L07_t) cpu)->power_scale);
370 }
371
372 static double get_available_speed(void *cpu)
373 {
374   return ((cpu_L07_t) cpu)->power_current;
375 }
376
377 static surf_action_t execute_parallel_task(int workstation_nb,
378                                            void **workstation_list,
379                                            double *computation_amount,
380                                            double *communication_amount,
381                                            double amount, double rate)
382 {
383   surf_action_workstation_L07_t action = NULL;
384   int i, j, k;
385   int nb_link = 0;
386   int nb_host = 0;
387
388   if (parallel_task_network_link_set == NULL) {
389     parallel_task_network_link_set =
390         xbt_dict_new_ext(workstation_nb * workstation_nb * 10);
391   }
392
393   /* Compute the number of affected resources... */
394   for (i = 0; i < workstation_nb; i++) {
395     for (j = 0; j < workstation_nb; j++) {
396       cpu_L07_t card_src = workstation_list[i];
397       cpu_L07_t card_dst = workstation_list[j];
398       int route_size = ROUTE(card_src->id, card_dst->id).size;
399       network_link_L07_t *route = ROUTE(card_src->id, card_dst->id).links;
400
401       if (communication_amount[i * workstation_nb + j] > 0)
402         for (k = 0; k < route_size; k++) {
403           xbt_dict_set(parallel_task_network_link_set, route[k]->name,
404                        route[k], NULL);
405         }
406     }
407   }
408   nb_link = xbt_dict_length(parallel_task_network_link_set);
409   xbt_dict_reset(parallel_task_network_link_set);
410
411
412   for (i = 0; i < workstation_nb; i++)
413     if (computation_amount[i] > 0)
414       nb_host++;
415
416
417   if (nb_link + nb_host == 0)   /* was workstation_nb... */
418     return NULL;
419
420   action = xbt_new0(s_surf_action_workstation_L07_t, 1);
421   DEBUG3("Creating a parallel task (%p) with %d cpus and %d links.",
422          action, nb_host, nb_link);
423   action->generic_action.using = 1;
424   action->generic_action.cost = amount;
425   action->generic_action.remains = amount;
426   action->generic_action.max_duration = NO_MAX_DURATION;
427   action->generic_action.start = -1.0;
428   action->generic_action.finish = -1.0;
429   action->generic_action.resource_type =
430       (surf_resource_t) surf_workstation_resource;
431   action->suspended = 0;        /* Should be useless because of the
432                                    calloc but it seems to help valgrind... */
433   action->generic_action.state_set =
434       surf_workstation_resource->common_public->states.running_action_set;
435
436   xbt_swag_insert(action, action->generic_action.state_set);
437   action->rate = rate;
438
439   if (action->rate > 0)
440     action->variable =
441         lmm_variable_new(ptask_maxmin_system, action, 1.0, -1.0,
442                          nb_host + nb_link);
443   else
444     action->variable =
445         lmm_variable_new(ptask_maxmin_system, action, 1.0, action->rate,
446                          nb_host + nb_link);
447
448   for (i = 0; i < workstation_nb; i++)
449     if (computation_amount[i] > 0)
450       lmm_expand(ptask_maxmin_system,
451                  ((cpu_L07_t) workstation_list[i])->constraint,
452                  action->variable, computation_amount[i]);
453
454   for (i = 0; i < workstation_nb; i++) {
455     for (j = 0; j < workstation_nb; j++) {
456       cpu_L07_t card_src = workstation_list[i];
457       cpu_L07_t card_dst = workstation_list[j];
458       int route_size = ROUTE(card_src->id, card_dst->id).size;
459       network_link_L07_t *route = ROUTE(card_src->id, card_dst->id).links;
460
461       for (k = 0; k < route_size; k++) {
462         if (communication_amount[i * workstation_nb + j] > 0) {
463           lmm_expand_add(ptask_maxmin_system, route[k]->constraint,
464                          action->variable,
465                          communication_amount[i * workstation_nb + j]);
466         }
467       }
468     }
469   }
470
471   return (surf_action_t) action;
472 }
473
474 static surf_action_t execute(void *cpu, double size)
475 {
476   double val = 0.0;
477
478   return execute_parallel_task(1, &cpu, &size, &val, 1, -1);
479 }
480
481 static surf_action_t communicate(void *src, void *dst, double size,
482                                  double rate)
483 {
484   void **workstation_list = xbt_new0(void *, 2);
485   double *computation_amount = xbt_new0(double, 2);
486   double *communication_amount = xbt_new0(double, 4);
487   surf_action_t res = NULL;
488
489   workstation_list[0] = src;
490   workstation_list[1] = src;
491   communication_amount[1] = size;
492
493   res = execute_parallel_task(2, workstation_list,
494                               computation_amount, communication_amount,
495                               1, rate);
496
497   free(computation_amount);
498   free(communication_amount);
499   free(workstation_list);
500
501   return res;
502 }
503
504 static surf_action_t action_sleep(void *cpu, double duration)
505 {
506   surf_action_workstation_L07_t action = NULL;
507
508   XBT_IN2("(%s,%g)", ((cpu_L07_t) cpu)->name, duration);
509
510   action = (surf_action_workstation_L07_t) execute(cpu, 1.0);
511   action->generic_action.max_duration = duration;
512   action->suspended = 2;
513   lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
514
515   XBT_OUT;
516   return (surf_action_t) action;
517 }
518
519 /* returns an array of network_link_L07_t */
520 static const void **get_route(void *src, void *dst)
521 {
522   cpu_L07_t card_src = src;
523   cpu_L07_t card_dst = dst;
524   route_L07_t route = &(ROUTE(card_src->id, card_dst->id));
525
526   return (const void **) route->links;
527 }
528
529 static int get_route_size(void *src, void *dst)
530 {
531   cpu_L07_t card_src = src;
532   cpu_L07_t card_dst = dst;
533   route_L07_t route = &(ROUTE(card_src->id, card_dst->id));
534   return route->size;
535 }
536
537 static const char *get_link_name(const void *link)
538 {
539   return ((network_link_L07_t) link)->name;
540 }
541
542 static double get_link_bandwidth(const void *link)
543 {
544   return ((network_link_L07_t) link)->bw_current;
545 }
546
547 static double get_link_latency(const void *link)
548 {
549   xbt_assert0(0, "This model does not implement latencies");
550 }
551
552 /**************************************/
553 /*** Resource Creation & Destruction **/
554 /**************************************/
555
556 static void cpu_free(void *cpu)
557 {
558   free(((cpu_L07_t) cpu)->name);
559   free(cpu);
560 }
561
562 static cpu_L07_t cpu_new(const char *name, double power_scale,
563                          double power_initial,
564                          tmgr_trace_t power_trace,
565                          e_surf_cpu_state_t state_initial,
566                          tmgr_trace_t state_trace)
567 {
568   cpu_L07_t cpu = xbt_new0(s_cpu_L07_t, 1);
569
570   cpu->resource = (surf_resource_t) surf_workstation_resource;
571   cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
572   cpu->name = xbt_strdup(name);
573   cpu->id = nb_workstation++;
574
575   cpu->power_scale = power_scale;
576   xbt_assert0(cpu->power_scale > 0, "Power has to be >0");
577
578   cpu->power_current = power_initial;
579   if (power_trace)
580     cpu->power_event =
581         tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
582
583   cpu->state_current = state_initial;
584   if (state_trace)
585     cpu->state_event =
586         tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
587
588   cpu->constraint =
589       lmm_constraint_new(ptask_maxmin_system, cpu,
590                          cpu->power_current * cpu->power_scale);
591
592   xbt_dict_set(workstation_set, name, cpu, cpu_free);
593
594   return cpu;
595 }
596
597 static void parse_cpu(void)
598 {
599   double power_scale = 0.0;
600   double power_initial = 0.0;
601   tmgr_trace_t power_trace = NULL;
602   e_surf_cpu_state_t state_initial = SURF_CPU_OFF;
603   tmgr_trace_t state_trace = NULL;
604
605   surf_parse_get_double(&power_scale, A_surfxml_cpu_power);
606   surf_parse_get_double(&power_initial, A_surfxml_cpu_availability);
607   surf_parse_get_trace(&power_trace, A_surfxml_cpu_availability_file);
608
609   xbt_assert0((A_surfxml_cpu_state == A_surfxml_cpu_state_ON) ||
610               (A_surfxml_cpu_state == A_surfxml_cpu_state_OFF),
611               "Invalid state");
612   if (A_surfxml_cpu_state == A_surfxml_cpu_state_ON)
613     state_initial = SURF_CPU_ON;
614   if (A_surfxml_cpu_state == A_surfxml_cpu_state_OFF)
615     state_initial = SURF_CPU_OFF;
616   surf_parse_get_trace(&state_trace, A_surfxml_cpu_state_file);
617
618   cpu_new(A_surfxml_cpu_name, power_scale, power_initial, power_trace,
619           state_initial, state_trace);
620 }
621
622 static void create_routing_table(void)
623 {
624   routing_table = xbt_new0(s_route_L07_t, nb_workstation * nb_workstation);
625 }
626
627 static void network_link_free(void *nw_link)
628 {
629   free(((network_link_L07_t) nw_link)->name);
630   free(nw_link);
631 }
632
633 static network_link_L07_t network_link_new(char *name,
634                                            double bw_initial,
635                                            tmgr_trace_t bw_trace,
636                                            e_surf_network_link_state_t
637                                            state_initial,
638                                            tmgr_trace_t state_trace,
639                                            e_surf_network_link_sharing_policy_t
640                                            policy)
641 {
642   network_link_L07_t nw_link = xbt_new0(s_network_link_L07_t, 1);
643
644
645   nw_link->resource = (surf_resource_t) surf_workstation_resource;
646   nw_link->type = SURF_WORKSTATION_RESOURCE_LINK;
647   nw_link->name = name;
648   nw_link->bw_current = bw_initial;
649   if (bw_trace)
650     nw_link->bw_event =
651         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
652   nw_link->state_current = state_initial;
653   if (state_trace)
654     nw_link->state_event =
655         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
656
657   nw_link->constraint =
658       lmm_constraint_new(ptask_maxmin_system, nw_link,
659                          nw_link->bw_current);
660
661   if (policy == SURF_NETWORK_LINK_FATPIPE)
662     lmm_constraint_shared(nw_link->constraint);
663
664   xbt_dict_set(network_link_set, name, nw_link, network_link_free);
665
666   return nw_link;
667 }
668
669 static void parse_network_link(void)
670 {
671   char *name;
672   double bw_initial;
673   tmgr_trace_t bw_trace;
674   e_surf_network_link_state_t state_initial = SURF_NETWORK_LINK_ON;
675   e_surf_network_link_sharing_policy_t policy_initial =
676       SURF_NETWORK_LINK_SHARED;
677   tmgr_trace_t state_trace;
678
679   name = xbt_strdup(A_surfxml_network_link_name);
680   surf_parse_get_double(&bw_initial, A_surfxml_network_link_bandwidth);
681   surf_parse_get_trace(&bw_trace, A_surfxml_network_link_bandwidth_file);
682
683   xbt_assert0((A_surfxml_network_link_state ==
684                A_surfxml_network_link_state_ON)
685               || (A_surfxml_network_link_state ==
686                   A_surfxml_network_link_state_OFF), "Invalid state");
687   if (A_surfxml_network_link_state == A_surfxml_network_link_state_ON)
688     state_initial = SURF_NETWORK_LINK_ON;
689   else if (A_surfxml_network_link_state ==
690            A_surfxml_network_link_state_OFF)
691     state_initial = SURF_NETWORK_LINK_OFF;
692
693   if (A_surfxml_network_link_sharing_policy ==
694       A_surfxml_network_link_sharing_policy_SHARED)
695     policy_initial = SURF_NETWORK_LINK_SHARED;
696   else if (A_surfxml_network_link_sharing_policy ==
697            A_surfxml_network_link_sharing_policy_FATPIPE)
698     policy_initial = SURF_NETWORK_LINK_FATPIPE;
699
700   surf_parse_get_trace(&state_trace, A_surfxml_network_link_state_file);
701
702   network_link_new(name, bw_initial, bw_trace, state_initial, state_trace,
703                    policy_initial);
704 }
705
706 static void route_new(int src_id, int dst_id,
707                       network_link_L07_t * link_list, int nb_link)
708 {
709   route_L07_t route = &(ROUTE(src_id, dst_id));
710
711   route->size = nb_link;
712   route->links = link_list =
713       xbt_realloc(link_list, sizeof(network_link_L07_t) * nb_link);
714 }
715
716 static int nb_link;
717 static int link_list_capacity;
718 static network_link_L07_t *link_list = NULL;
719 static int src_id = -1;
720 static int dst_id = -1;
721
722 static void parse_route_set_endpoints(void)
723 {
724   cpu_L07_t cpu_tmp = NULL;
725
726   cpu_tmp = (cpu_L07_t) name_service(A_surfxml_route_src);
727   xbt_assert1(cpu_tmp, "Invalid cpu %s", A_surfxml_route_src);
728   if (cpu_tmp != NULL)
729     src_id = cpu_tmp->id;
730
731   cpu_tmp = (cpu_L07_t) name_service(A_surfxml_route_dst);
732   xbt_assert1(cpu_tmp, "Invalid cpu %s", A_surfxml_route_dst);
733   if (cpu_tmp != NULL)
734     dst_id = cpu_tmp->id;
735
736   nb_link = 0;
737   link_list_capacity = 1;
738   link_list = xbt_new(network_link_L07_t, link_list_capacity);
739 }
740
741 static void parse_route_elem(void)
742 {
743   xbt_ex_t e;
744   if (nb_link == link_list_capacity) {
745     link_list_capacity *= 2;
746     link_list =
747         xbt_realloc(link_list,
748                     (link_list_capacity) * sizeof(network_link_L07_t));
749   }
750   TRY {
751     link_list[nb_link++] =
752         xbt_dict_get(network_link_set, A_surfxml_route_element_name);
753   }
754   CATCH(e) {
755     RETHROW1("Link %s not found (dict raised this exception: %s)",
756              A_surfxml_route_element_name);
757   }
758 }
759
760 static void parse_route_set_route(void)
761 {
762   if (src_id != -1 && dst_id != -1)
763     route_new(src_id, dst_id, link_list, nb_link);
764 }
765
766 static void parse_file(const char *file)
767 {
768   int i;
769
770   /* Figuring out the cpus */
771   surf_parse_reset_parser();
772   ETag_surfxml_cpu_fun = parse_cpu;
773   surf_parse_open(file);
774   xbt_assert1((!surf_parse()), "Parse error in %s", file);
775   surf_parse_close();
776
777   create_routing_table();
778
779   /* Figuring out the network links */
780   surf_parse_reset_parser();
781   ETag_surfxml_network_link_fun = parse_network_link;
782   surf_parse_open(file);
783   xbt_assert1((!surf_parse()), "Parse error in %s", file);
784   surf_parse_close();
785
786   /* Building the routes */
787   surf_parse_reset_parser();
788   STag_surfxml_route_fun = parse_route_set_endpoints;
789   ETag_surfxml_route_element_fun = parse_route_elem;
790   ETag_surfxml_route_fun = parse_route_set_route;
791   surf_parse_open(file);
792   xbt_assert1((!surf_parse()), "Parse error in %s", file);
793   surf_parse_close();
794
795   /* Adding loopback if needed */
796   for (i = 0; i < nb_workstation; i++)
797     if (!ROUTE(i, i).size) {
798       if (!loopback)
799         loopback = network_link_new(xbt_strdup("__MSG_loopback__"),
800                                     498000000, NULL,
801                                     SURF_NETWORK_LINK_ON, NULL,
802                                     SURF_NETWORK_LINK_FATPIPE);
803
804       ROUTE(i, i).size = 1;
805       ROUTE(i, i).links = xbt_new0(network_link_L07_t, 1);
806       ROUTE(i, i).links[0] = loopback;
807     }
808 }
809
810 /**************************************/
811 /********* Module  creation ***********/
812 /**************************************/
813
814 static void resource_init_internal(void)
815 {
816   s_surf_action_t action;
817
818   surf_workstation_resource = xbt_new0(s_surf_workstation_resource_t, 1);
819
820   surf_workstation_resource->common_private =
821       xbt_new0(s_surf_resource_private_t, 1);
822   surf_workstation_resource->common_public =
823       xbt_new0(s_surf_resource_public_t, 1);
824   surf_workstation_resource->extension_public =
825       xbt_new0(s_surf_workstation_resource_extension_public_t, 1);
826
827   surf_workstation_resource->common_public->states.ready_action_set =
828       xbt_swag_new(xbt_swag_offset(action, state_hookup));
829   surf_workstation_resource->common_public->states.running_action_set =
830       xbt_swag_new(xbt_swag_offset(action, state_hookup));
831   surf_workstation_resource->common_public->states.failed_action_set =
832       xbt_swag_new(xbt_swag_offset(action, state_hookup));
833   surf_workstation_resource->common_public->states.done_action_set =
834       xbt_swag_new(xbt_swag_offset(action, state_hookup));
835
836   surf_workstation_resource->common_public->name_service = name_service;
837   surf_workstation_resource->common_public->get_resource_name =
838       get_resource_name;
839   surf_workstation_resource->common_public->action_get_state =
840       surf_action_get_state;
841   surf_workstation_resource->common_public->action_get_start_time =
842       surf_action_get_start_time;
843   surf_workstation_resource->common_public->action_get_finish_time =
844       surf_action_get_finish_time;
845   surf_workstation_resource->common_public->action_use = action_use;
846   surf_workstation_resource->common_public->action_free = action_free;
847   surf_workstation_resource->common_public->action_cancel = action_cancel;
848   surf_workstation_resource->common_public->action_recycle =
849       action_recycle;
850   surf_workstation_resource->common_public->action_change_state =
851       surf_action_change_state;
852   surf_workstation_resource->common_public->action_set_data =
853       surf_action_set_data;
854   surf_workstation_resource->common_public->suspend = action_suspend;
855   surf_workstation_resource->common_public->resume = action_resume;
856   surf_workstation_resource->common_public->is_suspended =
857       action_is_suspended;
858   surf_workstation_resource->common_public->set_max_duration =
859       action_set_max_duration;
860   surf_workstation_resource->common_public->set_priority =
861       action_set_priority;
862   surf_workstation_resource->common_public->name = "Workstation ptask_L07";
863
864   surf_workstation_resource->common_private->resource_used = resource_used;
865   surf_workstation_resource->common_private->share_resources =
866       share_resources;
867   surf_workstation_resource->common_private->update_actions_state =
868       update_actions_state;
869   surf_workstation_resource->common_private->update_resource_state =
870       update_resource_state;
871   surf_workstation_resource->common_private->finalize = finalize;
872
873   surf_workstation_resource->extension_public->execute = execute;
874   surf_workstation_resource->extension_public->sleep = action_sleep;
875   surf_workstation_resource->extension_public->get_state =
876       resource_get_state;
877   surf_workstation_resource->extension_public->get_speed = get_speed;
878   surf_workstation_resource->extension_public->get_available_speed =
879       get_available_speed;
880   surf_workstation_resource->extension_public->communicate = communicate;
881   surf_workstation_resource->extension_public->execute_parallel_task =
882       execute_parallel_task;
883   surf_workstation_resource->extension_public->get_route = get_route;
884   surf_workstation_resource->extension_public->get_route_size =
885       get_route_size;
886   surf_workstation_resource->extension_public->get_link_name =
887       get_link_name;
888   surf_workstation_resource->extension_public->get_link_bandwidth =
889       get_link_bandwidth;
890   surf_workstation_resource->extension_public->get_link_latency =
891       get_link_latency;
892
893   workstation_set = xbt_dict_new();
894   network_link_set = xbt_dict_new();
895
896   if (!ptask_maxmin_system)
897     ptask_maxmin_system = lmm_system_new();
898 }
899
900 /**************************************/
901 /*************** Generic **************/
902 /**************************************/
903 void surf_workstation_resource_init_ptask_L07(const char *filename)
904 {
905   xbt_assert0(!surf_cpu_resource, "CPU resource type already defined");
906   xbt_assert0(!surf_network_resource,
907               "network resource type already defined");
908   resource_init_internal();
909   parse_file(filename);
910
911   update_resource_description(surf_workstation_resource_description,
912                               surf_workstation_resource_description_size,
913                               "ptask_L07",
914                               (surf_resource_t) surf_workstation_resource);
915   xbt_dynar_push(resource_list, &surf_workstation_resource);
916 }