Logo AND Algorithmique Numérique Distribuée

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