Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
077cde270e2be40c6fe96e79dbd01f681d350e1f
[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     DEBUG2("Action (%p) : remains (%g).",
223            action, action->generic_action.remains);
224     if ((action->generic_action.remains <= 0) &&
225         (lmm_get_variable_weight(action->variable) > 0)) {
226       action->generic_action.finish = surf_get_clock();
227       surf_action_change_state((surf_action_t) action, SURF_ACTION_DONE);
228     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
229                (action->generic_action.max_duration <= 0)) {
230       action->generic_action.finish = surf_get_clock();
231       surf_action_change_state((surf_action_t) action, SURF_ACTION_DONE);
232     } else {
233       /* Need to check that none of the resource has failed */
234       lmm_constraint_t cnst = NULL;
235       int i = 0;
236       void *constraint_id = NULL;
237
238       while ((cnst =
239               lmm_get_cnst_from_var(ptask_maxmin_system, action->variable,
240                                     i++))) {
241         constraint_id = lmm_constraint_id(cnst);
242
243 /*      if(((network_link_L07_t)constraint_id)->type== */
244 /*         SURF_WORKSTATION_RESOURCE_LINK) { */
245 /*        DEBUG2("Checking for link %s (%p)", */
246 /*               ((network_link_L07_t)constraint_id)->name, */
247 /*               ((network_link_L07_t)constraint_id)); */
248 /*      } */
249 /*      if(((cpu_L07_t)constraint_id)->type== */
250 /*         SURF_WORKSTATION_RESOURCE_CPU) { */
251 /*        DEBUG3("Checking for cpu %s (%p) : %s", */
252 /*               ((cpu_L07_t)constraint_id)->name, */
253 /*               ((cpu_L07_t)constraint_id), */
254 /*               ((cpu_L07_t)constraint_id)->state_current==SURF_CPU_OFF?"Off":"On"); */
255 /*      } */
256
257         if (((((network_link_L07_t) constraint_id)->type ==
258               SURF_WORKSTATION_RESOURCE_LINK) &&
259              (((network_link_L07_t) constraint_id)->state_current ==
260               SURF_NETWORK_LINK_OFF)) ||
261             ((((cpu_L07_t) constraint_id)->type ==
262               SURF_WORKSTATION_RESOURCE_CPU) &&
263              (((cpu_L07_t) constraint_id)->state_current ==
264               SURF_CPU_OFF))) {
265           DEBUG1("Action (%p) Failed!!", action);
266           action->generic_action.finish = surf_get_clock();
267           surf_action_change_state((surf_action_t) action,
268                                    SURF_ACTION_FAILED);
269           break;
270         }
271       }
272     }
273   }
274   return;
275 }
276
277 static void update_resource_state(void *id,
278                                   tmgr_trace_event_t event_type,
279                                   double value)
280 {
281   cpu_L07_t cpu = id;
282   network_link_L07_t nw_link = id;
283
284   if (nw_link->type == SURF_WORKSTATION_RESOURCE_LINK) {
285     DEBUG2("Updating link %s (%p)", nw_link->name, nw_link);
286     if (event_type == nw_link->bw_event) {
287       nw_link->bw_current = value;
288       lmm_update_constraint_bound(ptask_maxmin_system, nw_link->constraint,
289                                   nw_link->bw_current);
290     } else if (event_type == nw_link->state_event) {
291       if (value > 0)
292         nw_link->state_current = SURF_NETWORK_LINK_ON;
293       else
294         nw_link->state_current = SURF_NETWORK_LINK_OFF;
295     } else {
296       CRITICAL0("Unknown event ! \n");
297       xbt_abort();
298     }
299     return;
300   } else if (cpu->type == SURF_WORKSTATION_RESOURCE_CPU) {
301     DEBUG3("Updating cpu %s (%p) with value %g", cpu->name, cpu, value);
302     if (event_type == cpu->power_event) {
303       cpu->power_current = value;
304       lmm_update_constraint_bound(ptask_maxmin_system, cpu->constraint,
305                                   cpu->power_current);
306     } else if (event_type == cpu->state_event) {
307       if (value > 0)
308         cpu->state_current = SURF_CPU_ON;
309       else
310         cpu->state_current = SURF_CPU_OFF;
311     } else {
312       CRITICAL0("Unknown event ! \n");
313       xbt_abort();
314     }
315     return;
316   } else {
317     DIE_IMPOSSIBLE;
318   }
319   return;
320 }
321
322 static void finalize(void)
323 {
324   int i, j;
325
326   xbt_dict_free(&network_link_set);
327   xbt_dict_free(&workstation_set);
328   if (parallel_task_network_link_set != NULL) {
329     xbt_dict_free(&parallel_task_network_link_set);
330   }
331   xbt_swag_free(surf_workstation_resource->common_public->states.
332                 ready_action_set);
333   xbt_swag_free(surf_workstation_resource->common_public->states.
334                 running_action_set);
335   xbt_swag_free(surf_workstation_resource->common_public->states.
336                 failed_action_set);
337   xbt_swag_free(surf_workstation_resource->common_public->states.
338                 done_action_set);
339
340   free(surf_workstation_resource->common_public);
341   free(surf_workstation_resource->common_private);
342   free(surf_workstation_resource->extension_public);
343
344   free(surf_workstation_resource);
345   surf_workstation_resource = NULL;
346
347   for (i = 0; i < nb_workstation; i++)
348     for (j = 0; j < nb_workstation; j++)
349       free(ROUTE(i, j).links);
350   free(routing_table);
351   routing_table = NULL;
352   nb_workstation = 0;
353
354   if (ptask_maxmin_system) {
355     lmm_system_free(ptask_maxmin_system);
356     ptask_maxmin_system = NULL;
357   }
358 }
359
360 /**************************************/
361 /******* Resource Private    **********/
362 /**************************************/
363
364 static e_surf_cpu_state_t resource_get_state(void *cpu)
365 {
366   return ((cpu_L07_t) cpu)->state_current;
367 }
368
369 static double get_speed(void *cpu, double load)
370 {
371   return load * (((cpu_L07_t) cpu)->power_scale);
372 }
373
374 static double get_available_speed(void *cpu)
375 {
376   return ((cpu_L07_t) cpu)->power_current;
377 }
378
379 static surf_action_t execute_parallel_task(int workstation_nb,
380                                            void **workstation_list,
381                                            double *computation_amount,
382                                            double *communication_amount,
383                                            double amount, double rate)
384 {
385   surf_action_workstation_L07_t action = NULL;
386   int i, j, k;
387   int nb_link = 0;
388   int nb_host = 0;
389
390   if (parallel_task_network_link_set == NULL) {
391     parallel_task_network_link_set =
392         xbt_dict_new_ext(workstation_nb * workstation_nb * 10);
393   }
394
395   /* Compute the number of affected resources... */
396   for (i = 0; i < workstation_nb; i++) {
397     for (j = 0; j < workstation_nb; j++) {
398       cpu_L07_t card_src = workstation_list[i];
399       cpu_L07_t card_dst = workstation_list[j];
400       int route_size = ROUTE(card_src->id, card_dst->id).size;
401       network_link_L07_t *route = ROUTE(card_src->id, card_dst->id).links;
402
403       if (communication_amount[i * workstation_nb + j] > 0)
404         for (k = 0; k < route_size; k++) {
405           xbt_dict_set(parallel_task_network_link_set, route[k]->name,
406                        route[k], NULL);
407         }
408     }
409   }
410   nb_link = xbt_dict_length(parallel_task_network_link_set);
411   xbt_dict_reset(parallel_task_network_link_set);
412
413   for (i = 0; i < workstation_nb; i++)
414     if (computation_amount[i] > 0)
415       nb_host++;
416
417   action = xbt_new0(s_surf_action_workstation_L07_t, 1);
418   DEBUG3("Creating a parallel task (%p) with %d cpus and %d links.",
419          action, workstation_nb, nb_link);
420   action->generic_action.using = 1;
421   action->generic_action.cost = amount;
422   action->generic_action.remains = amount;
423   action->generic_action.max_duration = NO_MAX_DURATION;
424   action->generic_action.start = -1.0;
425   action->generic_action.finish = -1.0;
426   action->generic_action.resource_type =
427       (surf_resource_t) surf_workstation_resource;
428   action->suspended = 0;        /* Should be useless because of the
429                                    calloc but it seems to help valgrind... */
430   action->generic_action.state_set =
431       surf_workstation_resource->common_public->states.running_action_set;
432
433   xbt_swag_insert(action, action->generic_action.state_set);
434   action->rate = rate;
435
436   if (action->rate > 0)
437     action->variable =
438         lmm_variable_new(ptask_maxmin_system, action, 1.0, -1.0,
439                          workstation_nb + nb_link);
440   else
441     action->variable =
442         lmm_variable_new(ptask_maxmin_system, action, 1.0, action->rate,
443                          workstation_nb + nb_link);
444
445   for (i = 0; i < workstation_nb; i++)
446     lmm_expand(ptask_maxmin_system,
447                ((cpu_L07_t) workstation_list[i])->constraint,
448                action->variable, computation_amount[i]);
449   
450   for (i = 0; i < workstation_nb; i++) {
451     for (j = 0; j < workstation_nb; j++) {
452       cpu_L07_t card_src = workstation_list[i];
453       cpu_L07_t card_dst = workstation_list[j];
454       int route_size = ROUTE(card_src->id, card_dst->id).size;
455       network_link_L07_t *route = ROUTE(card_src->id, card_dst->id).links;
456       
457       if (communication_amount[i * workstation_nb + j] == 0.0) 
458         continue;
459       for (k = 0; k < route_size; k++) {
460           lmm_expand_add(ptask_maxmin_system, route[k]->constraint,
461                          action->variable,
462                          communication_amount[i * workstation_nb + j]);
463       }
464     }
465   }
466
467   if (nb_link + nb_host == 0) {
468     action->generic_action.cost = 1.0;
469     action->generic_action.remains = 0.0;
470   }
471
472   return (surf_action_t) action;
473 }
474
475 static surf_action_t execute(void *cpu, double size)
476 {
477   double val = 0.0;
478
479   return execute_parallel_task(1, &cpu, &size, &val, 1, -1);
480 }
481
482 static surf_action_t communicate(void *src, void *dst, double size,
483                                  double rate)
484 {
485   void **workstation_list = xbt_new0(void *, 2);
486   double *computation_amount = xbt_new0(double, 2);
487   double *communication_amount = xbt_new0(double, 4);
488   surf_action_t res = NULL;
489
490   workstation_list[0] = src;
491   workstation_list[1] = dst;
492   communication_amount[1] = size;
493
494   res = execute_parallel_task(2, workstation_list,
495                               computation_amount, communication_amount,
496                               1, rate);
497
498   free(computation_amount);
499   free(communication_amount);
500   free(workstation_list);
501
502   return res;
503 }
504
505 static surf_action_t action_sleep(void *cpu, double duration)
506 {
507   surf_action_workstation_L07_t action = NULL;
508
509   XBT_IN2("(%s,%g)", ((cpu_L07_t) cpu)->name, duration);
510
511   action = (surf_action_workstation_L07_t) execute(cpu, 1.0);
512   action->generic_action.max_duration = duration;
513   action->suspended = 2;
514   lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
515
516   XBT_OUT;
517   return (surf_action_t) action;
518 }
519
520 /* returns an array of network_link_L07_t */
521 static const void **get_route(void *src, void *dst)
522 {
523   cpu_L07_t card_src = src;
524   cpu_L07_t card_dst = dst;
525   route_L07_t route = &(ROUTE(card_src->id, card_dst->id));
526
527   return (const void **) route->links;
528 }
529
530 static int get_route_size(void *src, void *dst)
531 {
532   cpu_L07_t card_src = src;
533   cpu_L07_t card_dst = dst;
534   route_L07_t route = &(ROUTE(card_src->id, card_dst->id));
535   return route->size;
536 }
537
538 static const char *get_link_name(const void *link)
539 {
540   return ((network_link_L07_t) link)->name;
541 }
542
543 static double get_link_bandwidth(const void *link)
544 {
545   return ((network_link_L07_t) link)->bw_current;
546 }
547
548 static double get_link_latency(const void *link)
549 {
550   xbt_assert0(0, "This model does not implement latencies");
551 }
552
553 /**************************************/
554 /*** Resource Creation & Destruction **/
555 /**************************************/
556
557 static void cpu_free(void *cpu)
558 {
559   free(((cpu_L07_t) cpu)->name);
560   free(cpu);
561 }
562
563 static cpu_L07_t cpu_new(const char *name, double power_scale,
564                          double power_initial,
565                          tmgr_trace_t power_trace,
566                          e_surf_cpu_state_t state_initial,
567                          tmgr_trace_t state_trace)
568 {
569   cpu_L07_t cpu = xbt_new0(s_cpu_L07_t, 1);
570
571   cpu->resource = (surf_resource_t) surf_workstation_resource;
572   cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
573   cpu->name = xbt_strdup(name);
574   cpu->id = nb_workstation++;
575
576   cpu->power_scale = power_scale;
577   xbt_assert0(cpu->power_scale > 0, "Power has to be >0");
578
579   cpu->power_current = power_initial;
580   if (power_trace)
581     cpu->power_event =
582         tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
583
584   cpu->state_current = state_initial;
585   if (state_trace)
586     cpu->state_event =
587         tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
588
589   cpu->constraint =
590       lmm_constraint_new(ptask_maxmin_system, cpu,
591                          cpu->power_current * cpu->power_scale);
592
593   xbt_dict_set(workstation_set, name, cpu, cpu_free);
594
595   return cpu;
596 }
597
598 static void parse_cpu(void)
599 {
600   double power_scale = 0.0;
601   double power_initial = 0.0;
602   tmgr_trace_t power_trace = NULL;
603   e_surf_cpu_state_t state_initial = SURF_CPU_OFF;
604   tmgr_trace_t state_trace = NULL;
605
606   surf_parse_get_double(&power_scale, A_surfxml_cpu_power);
607   surf_parse_get_double(&power_initial, A_surfxml_cpu_availability);
608   surf_parse_get_trace(&power_trace, A_surfxml_cpu_availability_file);
609
610   xbt_assert0((A_surfxml_cpu_state == A_surfxml_cpu_state_ON) ||
611               (A_surfxml_cpu_state == A_surfxml_cpu_state_OFF),
612               "Invalid state");
613   if (A_surfxml_cpu_state == A_surfxml_cpu_state_ON)
614     state_initial = SURF_CPU_ON;
615   if (A_surfxml_cpu_state == A_surfxml_cpu_state_OFF)
616     state_initial = SURF_CPU_OFF;
617   surf_parse_get_trace(&state_trace, A_surfxml_cpu_state_file);
618
619   cpu_new(A_surfxml_cpu_name, power_scale, power_initial, power_trace,
620           state_initial, state_trace);
621 }
622
623 static void create_routing_table(void)
624 {
625   routing_table = xbt_new0(s_route_L07_t, nb_workstation * nb_workstation);
626 }
627
628 static void network_link_free(void *nw_link)
629 {
630   free(((network_link_L07_t) nw_link)->name);
631   free(nw_link);
632 }
633
634 static network_link_L07_t network_link_new(char *name,
635                                            double bw_initial,
636                                            tmgr_trace_t bw_trace,
637                                            e_surf_network_link_state_t
638                                            state_initial,
639                                            tmgr_trace_t state_trace,
640                                            e_surf_network_link_sharing_policy_t
641                                            policy)
642 {
643   network_link_L07_t nw_link = xbt_new0(s_network_link_L07_t, 1);
644
645
646   nw_link->resource = (surf_resource_t) surf_workstation_resource;
647   nw_link->type = SURF_WORKSTATION_RESOURCE_LINK;
648   nw_link->name = name;
649   nw_link->bw_current = bw_initial;
650   if (bw_trace)
651     nw_link->bw_event =
652         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
653   nw_link->state_current = state_initial;
654   if (state_trace)
655     nw_link->state_event =
656         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
657
658   nw_link->constraint =
659       lmm_constraint_new(ptask_maxmin_system, nw_link,
660                          nw_link->bw_current);
661
662   if (policy == SURF_NETWORK_LINK_FATPIPE)
663     lmm_constraint_shared(nw_link->constraint);
664
665   xbt_dict_set(network_link_set, name, nw_link, network_link_free);
666
667   return nw_link;
668 }
669
670 static void parse_network_link(void)
671 {
672   char *name;
673   double bw_initial;
674   tmgr_trace_t bw_trace;
675   e_surf_network_link_state_t state_initial = SURF_NETWORK_LINK_ON;
676   e_surf_network_link_sharing_policy_t policy_initial =
677       SURF_NETWORK_LINK_SHARED;
678   tmgr_trace_t state_trace;
679
680   name = xbt_strdup(A_surfxml_network_link_name);
681   surf_parse_get_double(&bw_initial, A_surfxml_network_link_bandwidth);
682   surf_parse_get_trace(&bw_trace, A_surfxml_network_link_bandwidth_file);
683
684   xbt_assert0((A_surfxml_network_link_state ==
685                A_surfxml_network_link_state_ON)
686               || (A_surfxml_network_link_state ==
687                   A_surfxml_network_link_state_OFF), "Invalid state");
688   if (A_surfxml_network_link_state == A_surfxml_network_link_state_ON)
689     state_initial = SURF_NETWORK_LINK_ON;
690   else if (A_surfxml_network_link_state ==
691            A_surfxml_network_link_state_OFF)
692     state_initial = SURF_NETWORK_LINK_OFF;
693
694   if (A_surfxml_network_link_sharing_policy ==
695       A_surfxml_network_link_sharing_policy_SHARED)
696     policy_initial = SURF_NETWORK_LINK_SHARED;
697   else if (A_surfxml_network_link_sharing_policy ==
698            A_surfxml_network_link_sharing_policy_FATPIPE)
699     policy_initial = SURF_NETWORK_LINK_FATPIPE;
700
701   surf_parse_get_trace(&state_trace, A_surfxml_network_link_state_file);
702
703   network_link_new(name, bw_initial, bw_trace, state_initial, state_trace,
704                    policy_initial);
705 }
706
707 static void route_new(int src_id, int dst_id,
708                       network_link_L07_t * link_list, int nb_link)
709 {
710   route_L07_t route = &(ROUTE(src_id, dst_id));
711
712   route->size = nb_link;
713   route->links = link_list =
714       xbt_realloc(link_list, sizeof(network_link_L07_t) * nb_link);
715 }
716
717 static int nb_link;
718 static int link_list_capacity;
719 static network_link_L07_t *link_list = NULL;
720 static int src_id = -1;
721 static int dst_id = -1;
722
723 static void parse_route_set_endpoints(void)
724 {
725   cpu_L07_t cpu_tmp = NULL;
726
727   cpu_tmp = (cpu_L07_t) name_service(A_surfxml_route_src);
728   xbt_assert1(cpu_tmp, "Invalid cpu %s", A_surfxml_route_src);
729   if (cpu_tmp != NULL)
730     src_id = cpu_tmp->id;
731
732   cpu_tmp = (cpu_L07_t) name_service(A_surfxml_route_dst);
733   xbt_assert1(cpu_tmp, "Invalid cpu %s", A_surfxml_route_dst);
734   if (cpu_tmp != NULL)
735     dst_id = cpu_tmp->id;
736
737   nb_link = 0;
738   link_list_capacity = 1;
739   link_list = xbt_new(network_link_L07_t, link_list_capacity);
740 }
741
742 static void parse_route_elem(void)
743 {
744   xbt_ex_t e;
745   if (nb_link == link_list_capacity) {
746     link_list_capacity *= 2;
747     link_list =
748         xbt_realloc(link_list,
749                     (link_list_capacity) * sizeof(network_link_L07_t));
750   }
751   TRY {
752     link_list[nb_link++] =
753         xbt_dict_get(network_link_set, A_surfxml_route_element_name);
754   }
755   CATCH(e) {
756     RETHROW1("Link %s not found (dict raised this exception: %s)",
757              A_surfxml_route_element_name);
758   }
759 }
760
761 static void parse_route_set_route(void)
762 {
763   if (src_id != -1 && dst_id != -1)
764     route_new(src_id, dst_id, link_list, nb_link);
765 }
766
767 static void parse_file(const char *file)
768 {
769   int i;
770
771   /* Figuring out the cpus */
772   surf_parse_reset_parser();
773   ETag_surfxml_cpu_fun = parse_cpu;
774   surf_parse_open(file);
775   xbt_assert1((!surf_parse()), "Parse error in %s", file);
776   surf_parse_close();
777
778   create_routing_table();
779
780   /* Figuring out the network links */
781   surf_parse_reset_parser();
782   ETag_surfxml_network_link_fun = parse_network_link;
783   surf_parse_open(file);
784   xbt_assert1((!surf_parse()), "Parse error in %s", file);
785   surf_parse_close();
786
787   /* Building the routes */
788   surf_parse_reset_parser();
789   STag_surfxml_route_fun = parse_route_set_endpoints;
790   ETag_surfxml_route_element_fun = parse_route_elem;
791   ETag_surfxml_route_fun = parse_route_set_route;
792   surf_parse_open(file);
793   xbt_assert1((!surf_parse()), "Parse error in %s", file);
794   surf_parse_close();
795
796   /* Adding loopback if needed */
797   for (i = 0; i < nb_workstation; i++)
798     if (!ROUTE(i, i).size) {
799       if (!loopback)
800         loopback = network_link_new(xbt_strdup("__MSG_loopback__"),
801                                     498000000, NULL,
802                                     SURF_NETWORK_LINK_ON, NULL,
803                                     SURF_NETWORK_LINK_FATPIPE);
804
805       ROUTE(i, i).size = 1;
806       ROUTE(i, i).links = xbt_new0(network_link_L07_t, 1);
807       ROUTE(i, i).links[0] = loopback;
808     }
809 }
810
811 /**************************************/
812 /********* Module  creation ***********/
813 /**************************************/
814
815 static void resource_init_internal(void)
816 {
817   s_surf_action_t action;
818
819   surf_workstation_resource = xbt_new0(s_surf_workstation_resource_t, 1);
820
821   surf_workstation_resource->common_private =
822       xbt_new0(s_surf_resource_private_t, 1);
823   surf_workstation_resource->common_public =
824       xbt_new0(s_surf_resource_public_t, 1);
825   surf_workstation_resource->extension_public =
826       xbt_new0(s_surf_workstation_resource_extension_public_t, 1);
827
828   surf_workstation_resource->common_public->states.ready_action_set =
829       xbt_swag_new(xbt_swag_offset(action, state_hookup));
830   surf_workstation_resource->common_public->states.running_action_set =
831       xbt_swag_new(xbt_swag_offset(action, state_hookup));
832   surf_workstation_resource->common_public->states.failed_action_set =
833       xbt_swag_new(xbt_swag_offset(action, state_hookup));
834   surf_workstation_resource->common_public->states.done_action_set =
835       xbt_swag_new(xbt_swag_offset(action, state_hookup));
836
837   surf_workstation_resource->common_public->name_service = name_service;
838   surf_workstation_resource->common_public->get_resource_name =
839       get_resource_name;
840   surf_workstation_resource->common_public->action_get_state =
841       surf_action_get_state;
842   surf_workstation_resource->common_public->action_get_start_time =
843       surf_action_get_start_time;
844   surf_workstation_resource->common_public->action_get_finish_time =
845       surf_action_get_finish_time;
846   surf_workstation_resource->common_public->action_use = action_use;
847   surf_workstation_resource->common_public->action_free = action_free;
848   surf_workstation_resource->common_public->action_cancel = action_cancel;
849   surf_workstation_resource->common_public->action_recycle =
850       action_recycle;
851   surf_workstation_resource->common_public->action_change_state =
852       surf_action_change_state;
853   surf_workstation_resource->common_public->action_set_data =
854       surf_action_set_data;
855   surf_workstation_resource->common_public->suspend = action_suspend;
856   surf_workstation_resource->common_public->resume = action_resume;
857   surf_workstation_resource->common_public->is_suspended =
858       action_is_suspended;
859   surf_workstation_resource->common_public->set_max_duration =
860       action_set_max_duration;
861   surf_workstation_resource->common_public->set_priority =
862       action_set_priority;
863   surf_workstation_resource->common_public->name = "Workstation ptask_L07";
864
865   surf_workstation_resource->common_private->resource_used = resource_used;
866   surf_workstation_resource->common_private->share_resources =
867       share_resources;
868   surf_workstation_resource->common_private->update_actions_state =
869       update_actions_state;
870   surf_workstation_resource->common_private->update_resource_state =
871       update_resource_state;
872   surf_workstation_resource->common_private->finalize = finalize;
873
874   surf_workstation_resource->extension_public->execute = execute;
875   surf_workstation_resource->extension_public->sleep = action_sleep;
876   surf_workstation_resource->extension_public->get_state =
877       resource_get_state;
878   surf_workstation_resource->extension_public->get_speed = get_speed;
879   surf_workstation_resource->extension_public->get_available_speed =
880       get_available_speed;
881   surf_workstation_resource->extension_public->communicate = communicate;
882   surf_workstation_resource->extension_public->execute_parallel_task =
883       execute_parallel_task;
884   surf_workstation_resource->extension_public->get_route = get_route;
885   surf_workstation_resource->extension_public->get_route_size =
886       get_route_size;
887   surf_workstation_resource->extension_public->get_link_name =
888       get_link_name;
889   surf_workstation_resource->extension_public->get_link_bandwidth =
890       get_link_bandwidth;
891   surf_workstation_resource->extension_public->get_link_latency =
892       get_link_latency;
893
894   workstation_set = xbt_dict_new();
895   network_link_set = xbt_dict_new();
896
897   if (!ptask_maxmin_system)
898     ptask_maxmin_system = lmm_system_new();
899 }
900
901 /**************************************/
902 /*************** Generic **************/
903 /**************************************/
904 void surf_workstation_resource_init_ptask_L07(const char *filename)
905 {
906   xbt_assert0(!surf_cpu_resource, "CPU resource type already defined");
907   xbt_assert0(!surf_network_resource,
908               "network resource type already defined");
909   resource_init_internal();
910   parse_file(filename);
911
912   update_resource_description(surf_workstation_resource_description,
913                               surf_workstation_resource_description_size,
914                               "ptask_L07",
915                               (surf_resource_t) surf_workstation_resource);
916   xbt_dynar_push(resource_list, &surf_workstation_resource);
917 }