Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add a command-line option to choose the routing schema to use
[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/str.h"
10 #include "xbt/dict.h"
11 #include "surf_private.h"
12
13 typedef enum {
14   SURF_WORKSTATION_RESOURCE_CPU,
15   SURF_WORKSTATION_RESOURCE_LINK,
16 } e_surf_workstation_model_type_t;
17
18 /**************************************/
19 /********* cpu object *****************/
20 /**************************************/
21 typedef struct cpu_L07 {
22   s_surf_resource_t generic_resource;  /* Do not move this field: must match surf_resource_t */
23   e_surf_workstation_model_type_t type; /* Do not move this field: must match link_L07_t */
24   lmm_constraint_t constraint;  /* Do not move this field: must match link_L07_t */
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 link_L07 {
38   s_surf_resource_t generic_resource;  /* Do not move this field: must match surf_resource_t */
39   e_surf_workstation_model_type_t type; /* Do not move this field: must match cpu_L07_t */
40   lmm_constraint_t constraint;  /* Do not move this field: must match cpu_L07_t */
41   double lat_current;
42   tmgr_trace_event_t lat_event;
43   double bw_current;
44   tmgr_trace_event_t bw_event;
45   e_surf_link_state_t state_current;
46   tmgr_trace_event_t state_event;
47 } s_link_L07_t, *link_L07_t;
48
49 /**************************************/
50 /*************** actions **************/
51 /**************************************/
52 typedef struct surf_action_workstation_L07 {
53   s_surf_action_t generic_action;
54   lmm_variable_t variable;
55   int workstation_nb;
56   cpu_L07_t *workstation_list;
57   double *computation_amount;
58   double *communication_amount;
59   double latency;
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 host_count = 0;
68 static xbt_dict_t parallel_task_link_set = NULL;
69 lmm_system_t ptask_maxmin_system = NULL;
70
71
72 static void update_action_bound(surf_action_workstation_L07_t action)
73 {
74   int workstation_nb = action->workstation_nb;
75   double lat_current = 0.0;
76   double lat_bound = -1.0;
77   int i, j;
78   unsigned int cpt;
79   link_L07_t link;
80
81   for (i = 0; i < workstation_nb; i++) {
82     for (j = 0; j < workstation_nb; j++) {
83       cpu_L07_t card_src = action->workstation_list[i];
84       cpu_L07_t card_dst = action->workstation_list[j];
85       xbt_dynar_t route = used_routing->get_route(card_src->id, card_dst->id);
86       double lat = 0.0;
87
88       if (action->communication_amount[i * workstation_nb + j] > 0) {
89         xbt_dynar_foreach(route,cpt,link) {
90           lat += link->lat_current;
91         }
92         lat_current =
93           MAX(lat_current,
94               lat * action->communication_amount[i * workstation_nb + j]);
95       }
96     }
97   }
98   lat_bound = sg_tcp_gamma / (2.0 * lat_current);
99   DEBUG2("action (%p) : lat_bound = %g", action, lat_bound);
100   if ((action->latency == 0.0) && (action->suspended == 0)) {
101     if (action->rate < 0)
102       lmm_update_variable_bound(ptask_maxmin_system, action->variable,
103                                 lat_bound);
104     else
105       lmm_update_variable_bound(ptask_maxmin_system, action->variable,
106                                 min(action->rate, lat_bound));
107   }
108 }
109
110 /**************************************/
111 /******* Resource Public     **********/
112 /**************************************/
113
114 static int action_unref(surf_action_t action)
115 {
116   action->refcount--;
117
118   if (!action->refcount) {
119     xbt_swag_remove(action, action->state_set);
120     if (((surf_action_workstation_L07_t) action)->variable)
121       lmm_variable_free(ptask_maxmin_system,
122                         ((surf_action_workstation_L07_t) action)->variable);
123     free(((surf_action_workstation_L07_t) action)->workstation_list);
124     free(((surf_action_workstation_L07_t) action)->communication_amount);
125     free(((surf_action_workstation_L07_t) action)->computation_amount);
126     free(action);
127     return 1;
128   }
129   return 0;
130 }
131
132 static void action_cancel(surf_action_t action)
133 {
134   surf_action_state_set(action, SURF_ACTION_FAILED);
135   return;
136 }
137
138 /* action_change_state is inherited from the surf module */
139 /* action_set_data is inherited from the surf module */
140
141 static void action_suspend(surf_action_t action)
142 {
143   XBT_IN1("(%p))", action);
144   if (((surf_action_workstation_L07_t) action)->suspended != 2) {
145     ((surf_action_workstation_L07_t) action)->suspended = 1;
146     lmm_update_variable_weight(ptask_maxmin_system,
147                                ((surf_action_workstation_L07_t)
148                                 action)->variable, 0.0);
149   }
150   XBT_OUT;
151 }
152
153 static void action_resume(surf_action_t action)
154 {
155   surf_action_workstation_L07_t act = (surf_action_workstation_L07_t) action;
156
157   XBT_IN1("(%p)", act);
158   if (act->suspended != 2) {
159     lmm_update_variable_weight(ptask_maxmin_system, act->variable, 1.0);
160     act->suspended = 0;
161   }
162   XBT_OUT;
163 }
164
165 static int action_is_suspended(surf_action_t action)
166 {
167   return (((surf_action_workstation_L07_t) action)->suspended == 1);
168 }
169
170 static void action_set_max_duration(surf_action_t action, double duration)
171 {                               /* FIXME: should inherit */
172   XBT_IN2("(%p,%g)", action, duration);
173   action->max_duration = duration;
174   XBT_OUT;
175 }
176
177
178 static void action_set_priority(surf_action_t action, double priority)
179 {                               /* FIXME: should inherit */
180   XBT_IN2("(%p,%g)", action, priority);
181   action->priority = priority;
182   XBT_OUT;
183 }
184
185 /**************************************/
186 /******* Resource Private    **********/
187 /**************************************/
188
189 static int resource_used(void *resource_id)
190 {
191   /* We can freely cast as a link_L07_t because it has
192      the same prefix as cpu_L07_t */
193   return lmm_constraint_used(ptask_maxmin_system,
194                              ((link_L07_t) resource_id)->constraint);
195
196 }
197
198 static double share_resources(double now)
199 {
200   s_surf_action_workstation_L07_t s_action;
201   surf_action_workstation_L07_t action = NULL;
202
203   xbt_swag_t running_actions =
204     surf_workstation_model->states.running_action_set;
205   double min = generic_maxmin_share_resources(running_actions,
206                                               xbt_swag_offset(s_action,
207                                                               variable),
208                                               ptask_maxmin_system,
209                                               bottleneck_solve);
210
211   xbt_swag_foreach(action, running_actions) {
212     if (action->latency > 0) {
213       if (min < 0) {
214         min = action->latency;
215         DEBUG3("Updating min (value) with %p (start %f): %f", action,
216                action->generic_action.start, min);
217       } else if (action->latency < min) {
218         min = action->latency;
219         DEBUG3("Updating min (latency) with %p (start %f): %f", action,
220                action->generic_action.start, min);
221       }
222     }
223   }
224
225   DEBUG1("min value : %f", min);
226
227   return min;
228 }
229
230 static void update_actions_state(double now, double delta)
231 {
232   double deltap = 0.0;
233   surf_action_workstation_L07_t action = NULL;
234   surf_action_workstation_L07_t next_action = NULL;
235   xbt_swag_t running_actions =
236     surf_workstation_model->states.running_action_set;
237
238   xbt_swag_foreach_safe(action, next_action, running_actions) {
239     deltap = delta;
240     if (action->latency > 0) {
241       if (action->latency > deltap) {
242         double_update(&(action->latency), deltap);
243         deltap = 0.0;
244       } else {
245         double_update(&(deltap), action->latency);
246         action->latency = 0.0;
247       }
248       if ((action->latency == 0.0) && (action->suspended == 0)) {
249         update_action_bound(action);
250         lmm_update_variable_weight(ptask_maxmin_system, action->variable,
251                                    1.0);
252       }
253     }
254     DEBUG3("Action (%p) : remains (%g) updated by %g.",
255            action, action->generic_action.remains,
256            lmm_variable_getvalue(action->variable) * delta);
257     double_update(&(action->generic_action.remains),
258                   lmm_variable_getvalue(action->variable) * delta);
259
260     if (action->generic_action.max_duration != NO_MAX_DURATION)
261       double_update(&(action->generic_action.max_duration), delta);
262
263     DEBUG2("Action (%p) : remains (%g).",
264            action, action->generic_action.remains);
265     if ((action->generic_action.remains <= 0) &&
266         (lmm_get_variable_weight(action->variable) > 0)) {
267       action->generic_action.finish = surf_get_clock();
268       surf_action_state_set((surf_action_t) action, SURF_ACTION_DONE);
269     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
270                (action->generic_action.max_duration <= 0)) {
271       action->generic_action.finish = surf_get_clock();
272       surf_action_state_set((surf_action_t) action, SURF_ACTION_DONE);
273     } else {
274       /* Need to check that none of the model has failed */
275       lmm_constraint_t cnst = NULL;
276       int i = 0;
277       void *constraint_id = NULL;
278
279       while ((cnst =
280               lmm_get_cnst_from_var(ptask_maxmin_system, action->variable,
281                                     i++))) {
282         constraint_id = lmm_constraint_id(cnst);
283
284 /*      if(((link_L07_t)constraint_id)->type== */
285 /*         SURF_WORKSTATION_RESOURCE_LINK) { */
286 /*        DEBUG2("Checking for link %s (%p)", */
287 /*               ((link_L07_t)constraint_id)->name, */
288 /*               ((link_L07_t)constraint_id)); */
289 /*      } */
290 /*      if(((cpu_L07_t)constraint_id)->type== */
291 /*         SURF_WORKSTATION_RESOURCE_CPU) { */
292 /*        DEBUG3("Checking for cpu %s (%p) : %s", */
293 /*               ((cpu_L07_t)constraint_id)->name, */
294 /*               ((cpu_L07_t)constraint_id), */
295 /*               ((cpu_L07_t)constraint_id)->state_current==SURF_CPU_OFF?"Off":"On"); */
296 /*      } */
297
298         if (((((link_L07_t) constraint_id)->type ==
299               SURF_WORKSTATION_RESOURCE_LINK) &&
300              (((link_L07_t) constraint_id)->state_current ==
301               SURF_LINK_OFF)) ||
302             ((((cpu_L07_t) constraint_id)->type ==
303               SURF_WORKSTATION_RESOURCE_CPU) &&
304              (((cpu_L07_t) constraint_id)->state_current == SURF_CPU_OFF))) {
305           DEBUG1("Action (%p) Failed!!", action);
306           action->generic_action.finish = surf_get_clock();
307           surf_action_state_set((surf_action_t) action,
308                                    SURF_ACTION_FAILED);
309           break;
310         }
311       }
312     }
313   }
314   return;
315 }
316
317 static void update_resource_state(void *id,
318                                   tmgr_trace_event_t event_type,
319                                   double value, double date)
320 {
321   cpu_L07_t cpu = id;
322   link_L07_t nw_link = id;
323
324   if (nw_link->type == SURF_WORKSTATION_RESOURCE_LINK) {
325     DEBUG2("Updating link %s (%p)", nw_link->generic_resource.name, nw_link);
326     if (event_type == nw_link->bw_event) {
327       nw_link->bw_current = value;
328       lmm_update_constraint_bound(ptask_maxmin_system, nw_link->constraint,
329                                   nw_link->bw_current);
330     } else if (event_type == nw_link->lat_event) {
331       lmm_variable_t var = NULL;
332       surf_action_workstation_L07_t action = NULL;
333       lmm_element_t elem = NULL;
334
335       nw_link->lat_current = value;
336       while ((var = lmm_get_var_from_cnst
337               (ptask_maxmin_system, nw_link->constraint, &elem))) {
338
339
340         action = lmm_variable_id(var);
341         update_action_bound(action);
342       }
343
344     } else if (event_type == nw_link->state_event) {
345       if (value > 0)
346         nw_link->state_current = SURF_LINK_ON;
347       else
348         nw_link->state_current = SURF_LINK_OFF;
349     } else {
350       CRITICAL0("Unknown event ! \n");
351       xbt_abort();
352     }
353     return;
354   } else if (cpu->type == SURF_WORKSTATION_RESOURCE_CPU) {
355     DEBUG3("Updating cpu %s (%p) with value %g", cpu->generic_resource.name, cpu, value);
356     if (event_type == cpu->power_event) {
357       cpu->power_current = value;
358       lmm_update_constraint_bound(ptask_maxmin_system, cpu->constraint,
359                                   cpu->power_current * cpu->power_scale);
360     } else if (event_type == cpu->state_event) {
361       if (value > 0)
362         cpu->state_current = SURF_CPU_ON;
363       else
364         cpu->state_current = SURF_CPU_OFF;
365     } else {
366       CRITICAL0("Unknown event ! \n");
367       xbt_abort();
368     }
369     return;
370   } else {
371     DIE_IMPOSSIBLE;
372   }
373   return;
374 }
375
376 static void finalize(void)
377 {
378   if (parallel_task_link_set != NULL)
379     xbt_dict_free(&parallel_task_link_set);
380
381   surf_model_exit(surf_workstation_model);
382   surf_workstation_model = NULL;
383   surf_model_exit(surf_network_model);
384   surf_network_model = NULL;
385   used_routing->finalize();
386
387   host_count = 0; // FIXME: KILLME?
388
389   if (ptask_maxmin_system) {
390     lmm_system_free(ptask_maxmin_system);
391     ptask_maxmin_system = NULL;
392   }
393 }
394
395 /**************************************/
396 /******* Resource Private    **********/
397 /**************************************/
398
399 static e_surf_cpu_state_t resource_get_state(void *cpu)
400 {
401   return ((cpu_L07_t) cpu)->state_current;
402 }
403
404 static double get_speed(void *cpu, double load)
405 {
406   return load * (((cpu_L07_t) cpu)->power_scale);
407 }
408
409 static double get_available_speed(void *cpu)
410 {
411   return ((cpu_L07_t) cpu)->power_current;
412 }
413
414 static surf_action_t execute_parallel_task(int workstation_nb,
415                                            void **workstation_list,
416                                            double *computation_amount,
417                                            double *communication_amount,
418                                            double amount, double rate)
419 {
420   surf_action_workstation_L07_t action = NULL;
421   int i, j;
422   unsigned int cpt;
423   int nb_link = 0;
424   int nb_host = 0;
425   double latency = 0.0;
426
427   if (parallel_task_link_set == NULL)
428     parallel_task_link_set = xbt_dict_new();
429
430   xbt_dict_reset(parallel_task_link_set);
431
432   /* Compute the number of affected resources... */
433   for (i = 0; i < workstation_nb; i++) {
434     for (j = 0; j < workstation_nb; j++) {
435       cpu_L07_t card_src = workstation_list[i];
436       cpu_L07_t card_dst = workstation_list[j];
437       link_L07_t link;
438       xbt_dynar_t route = used_routing->get_route(card_src->id, card_dst->id);
439       double lat = 0.0;
440
441       if (communication_amount[i * workstation_nb + j] > 0)
442         xbt_dynar_foreach(route,cpt,link) {
443           lat += link->lat_current;
444           xbt_dict_set(parallel_task_link_set, link->generic_resource.name,
445                        link, NULL);
446         }
447       latency = MAX(latency, lat);
448     }
449   }
450
451   nb_link = xbt_dict_length(parallel_task_link_set);
452   xbt_dict_reset(parallel_task_link_set);
453
454   for (i = 0; i < workstation_nb; i++)
455     if (computation_amount[i] > 0)
456       nb_host++;
457
458   action=surf_action_new(sizeof(s_surf_action_workstation_L07_t),amount,surf_workstation_model,0);
459   DEBUG3("Creating a parallel task (%p) with %d cpus and %d links.",
460          action, workstation_nb, nb_link);
461   action->suspended = 0;        /* Should be useless because of the
462                                    calloc but it seems to help valgrind... */
463   action->workstation_nb = workstation_nb;
464   action->workstation_list = (cpu_L07_t *) workstation_list;
465   action->computation_amount = computation_amount;
466   action->communication_amount = communication_amount;
467   action->latency = latency;
468   action->rate = rate;
469
470   action->variable =
471     lmm_variable_new(ptask_maxmin_system, action, 1.0,
472                      (action->rate > 0) ? action->rate : -1.0,
473                      workstation_nb + nb_link);
474
475   if (action->latency > 0)
476     lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
477
478   for (i = 0; i < workstation_nb; i++)
479     lmm_expand(ptask_maxmin_system,
480                ((cpu_L07_t) workstation_list[i])->constraint,
481                action->variable, computation_amount[i]);
482
483   for (i = 0; i < workstation_nb; i++) {
484     for (j = 0; j < workstation_nb; j++) {
485       cpu_L07_t card_src = workstation_list[i];
486       cpu_L07_t card_dst = workstation_list[j];
487       link_L07_t link;
488       xbt_dynar_t route = used_routing->get_route(card_src->id, card_dst->id);
489
490       if (communication_amount[i * workstation_nb + j] == 0.0)
491         continue;
492       xbt_dynar_foreach(route,cpt,link) {
493         lmm_expand_add(ptask_maxmin_system, link->constraint,
494                        action->variable,
495                        communication_amount[i * workstation_nb + j]);
496       }
497     }
498   }
499
500   if (nb_link + nb_host == 0) {
501     action->generic_action.cost = 1.0;
502     action->generic_action.remains = 0.0;
503   }
504
505   return (surf_action_t) action;
506 }
507
508 static surf_action_t execute(void *cpu, double size)
509 {
510   void **workstation_list = xbt_new0(void *, 1);
511   double *computation_amount = xbt_new0(double, 1);
512   double *communication_amount = xbt_new0(double, 1);
513
514   workstation_list[0] = cpu;
515   communication_amount[0] = 0.0;
516   computation_amount[0] = size;
517
518   return execute_parallel_task(1, workstation_list, computation_amount,
519                                communication_amount, 1, -1);
520 }
521
522 static surf_action_t communicate(void *src, void *dst, double size,
523                                  double rate)
524 {
525   void **workstation_list = xbt_new0(void *, 2);
526   double *computation_amount = xbt_new0(double, 2);
527   double *communication_amount = xbt_new0(double, 4);
528   surf_action_t res = NULL;
529
530   workstation_list[0] = src;
531   workstation_list[1] = dst;
532   communication_amount[1] = size;
533
534   res = execute_parallel_task(2, workstation_list,
535                               computation_amount, communication_amount,
536                               1, rate);
537
538   return res;
539 }
540
541 static surf_action_t action_sleep(void *cpu, double duration)
542 {
543   surf_action_workstation_L07_t action = NULL;
544
545   XBT_IN2("(%s,%g)", ((cpu_L07_t) cpu)->generic_resource.name, duration);
546
547   action = (surf_action_workstation_L07_t) execute(cpu, 1.0);
548   action->generic_action.max_duration = duration;
549   action->suspended = 2;
550   lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
551
552   XBT_OUT;
553   return (surf_action_t) action;
554 }
555
556 static xbt_dynar_t get_route(void *src, void *dst)
557 {
558   cpu_L07_t host_src = src;
559   cpu_L07_t host_dst = dst;
560
561   return used_routing->get_route(host_src->id, host_dst->id);
562 }
563
564 static double get_link_bandwidth(const void *link)
565 {
566   return ((link_L07_t) link)->bw_current;
567 }
568
569 static double get_link_latency(const void *link)
570 {
571   return ((link_L07_t) link)->lat_current;
572 }
573
574 static int link_shared(const void *link)
575 {
576   return lmm_constraint_is_shared(((link_L07_t) link)->constraint);
577 }
578
579 /**************************************/
580 /*** Resource Creation & Destruction **/
581 /**************************************/
582
583 static cpu_L07_t cpu_new(const char *name, double power_scale,
584                          double power_initial,
585                          tmgr_trace_t power_trace,
586                          e_surf_cpu_state_t state_initial,
587                          tmgr_trace_t state_trace, xbt_dict_t cpu_properties)
588 {
589   cpu_L07_t cpu = xbt_new0(s_cpu_L07_t, 1);
590   xbt_assert1(!surf_model_resource_by_name(surf_workstation_model, name),
591               "Host '%s' declared several times in the platform file.", name);
592
593   cpu->generic_resource.model = surf_workstation_model;
594   cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
595   cpu->generic_resource.name = xbt_strdup(name);
596   cpu->generic_resource.properties = current_property_set;
597   cpu->id = host_count++;
598
599   cpu->power_scale = power_scale;
600   xbt_assert0(cpu->power_scale > 0, "Power has to be >0");
601
602   cpu->power_current = power_initial;
603   if (power_trace)
604     cpu->power_event =
605       tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
606
607   cpu->state_current = state_initial;
608   if (state_trace)
609     cpu->state_event =
610       tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
611
612   cpu->constraint =
613     lmm_constraint_new(ptask_maxmin_system, cpu,
614                        cpu->power_current * cpu->power_scale);
615
616   xbt_dict_set(surf_model_resource_set(surf_workstation_model), name, cpu,
617                surf_resource_free);
618
619   return cpu;
620 }
621
622 static void parse_cpu_init(void)
623 {
624   double power_scale = 0.0;
625   double power_initial = 0.0;
626   tmgr_trace_t power_trace = NULL;
627   e_surf_cpu_state_t state_initial = SURF_CPU_OFF;
628   tmgr_trace_t state_trace = NULL;
629
630   power_scale = get_cpu_power(A_surfxml_host_power);
631   surf_parse_get_double(&power_initial, A_surfxml_host_availability);
632   surf_parse_get_trace(&power_trace, A_surfxml_host_availability_file);
633
634   xbt_assert0((A_surfxml_host_state == A_surfxml_host_state_ON) ||
635               (A_surfxml_host_state == A_surfxml_host_state_OFF),
636               "Invalid state");
637   if (A_surfxml_host_state == A_surfxml_host_state_ON)
638     state_initial = SURF_CPU_ON;
639   if (A_surfxml_host_state == A_surfxml_host_state_OFF)
640     state_initial = SURF_CPU_OFF;
641   surf_parse_get_trace(&state_trace, A_surfxml_host_state_file);
642
643   current_property_set = xbt_dict_new();
644   cpu_new(A_surfxml_host_id, power_scale, power_initial, power_trace,
645           state_initial, state_trace, current_property_set);
646 }
647
648 static link_L07_t link_new(char *name,
649                            double bw_initial,
650                            tmgr_trace_t bw_trace,
651                            double lat_initial,
652                            tmgr_trace_t lat_trace,
653                            e_surf_link_state_t
654                            state_initial,
655                            tmgr_trace_t state_trace,
656                            e_surf_link_sharing_policy_t
657                            policy, xbt_dict_t properties)
658 {
659   link_L07_t nw_link = xbt_new0(s_link_L07_t, 1);
660   xbt_assert1(!xbt_dict_get_or_null(surf_network_model->resource_set, name),
661               "Link '%s' declared several times in the platform file.", name);
662
663   nw_link->generic_resource.model = surf_workstation_model;
664   nw_link->generic_resource.properties = properties;
665   nw_link->generic_resource.name = name;
666   nw_link->type = SURF_WORKSTATION_RESOURCE_LINK;
667   nw_link->bw_current = bw_initial;
668   if (bw_trace)
669     nw_link->bw_event =
670       tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
671   nw_link->state_current = state_initial;
672   nw_link->lat_current = lat_initial;
673   if (lat_trace)
674     nw_link->lat_event =
675       tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
676   if (state_trace)
677     nw_link->state_event =
678       tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
679
680   nw_link->constraint =
681     lmm_constraint_new(ptask_maxmin_system, nw_link, nw_link->bw_current);
682
683   if (policy == SURF_LINK_FATPIPE)
684     lmm_constraint_shared(nw_link->constraint);
685
686
687   xbt_dict_set(surf_network_model->resource_set, name, nw_link, surf_resource_free);
688
689   return nw_link;
690 }
691
692 static void parse_link_init(void)
693 {
694   char *name_link;
695   double bw_initial;
696   tmgr_trace_t bw_trace;
697   double lat_initial;
698   tmgr_trace_t lat_trace;
699   e_surf_link_state_t state_initial_link = SURF_LINK_ON;
700   e_surf_link_sharing_policy_t policy_initial_link = SURF_LINK_SHARED;
701   tmgr_trace_t state_trace;
702
703   name_link = xbt_strdup(A_surfxml_link_id);
704   surf_parse_get_double(&bw_initial, A_surfxml_link_bandwidth);
705   surf_parse_get_trace(&bw_trace, A_surfxml_link_bandwidth_file);
706   surf_parse_get_double(&lat_initial, A_surfxml_link_latency);
707   surf_parse_get_trace(&lat_trace, A_surfxml_link_latency_file);
708
709   xbt_assert0((A_surfxml_link_state == A_surfxml_link_state_ON)
710               || (A_surfxml_link_state ==
711                   A_surfxml_link_state_OFF), "Invalid state");
712   if (A_surfxml_link_state == A_surfxml_link_state_ON)
713     state_initial_link = SURF_LINK_ON;
714   else if (A_surfxml_link_state == A_surfxml_link_state_OFF)
715     state_initial_link = SURF_LINK_OFF;
716
717   if (A_surfxml_link_sharing_policy == A_surfxml_link_sharing_policy_SHARED)
718     policy_initial_link = SURF_LINK_SHARED;
719   else if (A_surfxml_link_sharing_policy ==
720            A_surfxml_link_sharing_policy_FATPIPE)
721     policy_initial_link = SURF_LINK_FATPIPE;
722
723   surf_parse_get_trace(&state_trace, A_surfxml_link_state_file);
724
725   current_property_set = xbt_dict_new();
726   link_new(name_link, bw_initial, bw_trace, lat_initial, lat_trace,
727            state_initial_link, state_trace, policy_initial_link,
728            current_property_set);
729 }
730
731 static void add_traces(void)
732 {
733   xbt_dict_cursor_t cursor = NULL;
734   char *trace_name, *elm;
735
736   if (!trace_connect_list_host_avail)
737     return;
738
739   /* Connect traces relative to cpu */
740   xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
741     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
742     cpu_L07_t host = surf_model_resource_by_name(surf_workstation_model, elm);
743
744     xbt_assert1(host, "Host %s undefined", elm);
745     xbt_assert1(trace, "Trace %s undefined", trace_name);
746
747     host->state_event = tmgr_history_add_trace(history, trace, 0.0, 0, host);
748   }
749
750   xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
751     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
752     cpu_L07_t host = surf_model_resource_by_name(surf_workstation_model, elm);
753
754     xbt_assert1(host, "Host %s undefined", elm);
755     xbt_assert1(trace, "Trace %s undefined", trace_name);
756
757     host->power_event = tmgr_history_add_trace(history, trace, 0.0, 0, host);
758   }
759
760   /* Connect traces relative to network */
761   xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
762     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
763     link_L07_t link = xbt_dict_get_or_null(surf_network_model->resource_set, elm);
764
765     xbt_assert1(link, "Link %s undefined", elm);
766     xbt_assert1(trace, "Trace %s undefined", trace_name);
767
768     link->state_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
769   }
770
771   xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
772     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
773     link_L07_t link = xbt_dict_get_or_null(surf_network_model->resource_set, elm);
774
775     xbt_assert1(link, "Link %s undefined", elm);
776     xbt_assert1(trace, "Trace %s undefined", trace_name);
777
778     link->bw_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
779   }
780
781   xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
782     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
783     link_L07_t link = xbt_dict_get_or_null(surf_network_model->resource_set, elm);
784
785     xbt_assert1(link, "Link %s undefined", elm);
786     xbt_assert1(trace, "Trace %s undefined", trace_name);
787
788     link->lat_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
789   }
790 }
791
792 static void define_callbacks(const char *file)
793 {
794   /* Adding callback functions */
795   surf_parse_reset_parser();
796   surfxml_add_callback(STag_surfxml_host_cb_list, &parse_cpu_init);
797   surfxml_add_callback(STag_surfxml_link_cb_list, &parse_link_init);
798   surfxml_add_callback(ETag_surfxml_platform_cb_list, &add_traces);
799 }
800
801
802 /**************************************/
803 /********* Module  creation ***********/
804 /**************************************/
805
806 static void model_init_internal(void)
807 {
808   surf_workstation_model = surf_model_init();
809
810   surf_workstation_model->action_unref = action_unref;
811   surf_workstation_model->action_cancel = action_cancel;
812   surf_workstation_model->action_state_set = surf_action_state_set;
813   surf_workstation_model->suspend = action_suspend;
814   surf_workstation_model->resume = action_resume;
815   surf_workstation_model->is_suspended = action_is_suspended;
816   surf_workstation_model->set_max_duration = action_set_max_duration;
817   surf_workstation_model->set_priority = action_set_priority;
818   surf_workstation_model->name = "Workstation ptask_L07";
819
820   surf_workstation_model->model_private->resource_used = resource_used;
821   surf_workstation_model->model_private->share_resources = share_resources;
822   surf_workstation_model->model_private->update_actions_state =
823     update_actions_state;
824   surf_workstation_model->model_private->update_resource_state =
825     update_resource_state;
826   surf_workstation_model->model_private->finalize = finalize;
827
828   surf_workstation_model->extension.workstation.execute = execute;
829   surf_workstation_model->extension.workstation.sleep = action_sleep;
830   surf_workstation_model->extension.workstation.get_state =
831     resource_get_state;
832   surf_workstation_model->extension.workstation.get_speed = get_speed;
833   surf_workstation_model->extension.workstation.get_available_speed =
834     get_available_speed;
835   surf_workstation_model->extension.workstation.communicate = communicate;
836   surf_workstation_model->extension.workstation.get_route = get_route;
837   surf_workstation_model->extension.workstation.execute_parallel_task =
838     execute_parallel_task;
839   surf_workstation_model->extension.workstation.get_link_bandwidth =
840     get_link_bandwidth;
841   surf_workstation_model->extension.workstation.get_link_latency =
842     get_link_latency;
843   surf_workstation_model->extension.workstation.link_shared = link_shared;
844
845   if (!ptask_maxmin_system)
846     ptask_maxmin_system = lmm_system_new();
847
848   routing_model_create(sizeof(link_L07_t),
849         link_new(xbt_strdup("__loopback__"),
850             498000000, NULL, 0.000015, NULL,
851             SURF_LINK_ON, NULL, SURF_LINK_FATPIPE, NULL));
852
853 }
854
855 /**************************************/
856 /*************** Generic **************/
857 /**************************************/
858 void surf_workstation_model_init_ptask_L07(const char *filename)
859 {
860   xbt_assert0(!surf_cpu_model, "CPU model type already defined");
861   xbt_assert0(!surf_network_model, "network model type already defined");
862   surf_network_model = surf_model_init();
863   define_callbacks(filename);
864   model_init_internal();
865
866   update_model_description(surf_workstation_model_description,
867                            "ptask_L07", surf_workstation_model);
868   xbt_dynar_push(model_list, &surf_workstation_model);
869 }