Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Integrate properties into surf_resource_t
[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 = xbt_new0(s_surf_action_workstation_L07_t, 1);
459   DEBUG3("Creating a parallel task (%p) with %d cpus and %d links.",
460          action, workstation_nb, nb_link);
461   action->generic_action.refcount = 1;
462   action->generic_action.cost = amount;
463   action->generic_action.remains = amount;
464   action->generic_action.max_duration = NO_MAX_DURATION;
465   action->generic_action.start = surf_get_clock();
466   action->generic_action.finish = -1.0;
467   action->generic_action.model_type = surf_workstation_model;
468   action->suspended = 0;        /* Should be useless because of the
469                                    calloc but it seems to help valgrind... */
470   action->workstation_nb = workstation_nb;
471   action->workstation_list = (cpu_L07_t *) workstation_list;
472   action->computation_amount = computation_amount;
473   action->communication_amount = communication_amount;
474   action->latency = latency;
475   action->generic_action.state_set =
476     surf_workstation_model->states.running_action_set;
477
478   xbt_swag_insert(action, action->generic_action.state_set);
479   action->rate = rate;
480
481   action->variable =
482     lmm_variable_new(ptask_maxmin_system, action, 1.0,
483                      (action->rate > 0) ? action->rate : -1.0,
484                      workstation_nb + nb_link);
485
486   if (action->latency > 0)
487     lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
488
489   for (i = 0; i < workstation_nb; i++)
490     lmm_expand(ptask_maxmin_system,
491                ((cpu_L07_t) workstation_list[i])->constraint,
492                action->variable, computation_amount[i]);
493
494   for (i = 0; i < workstation_nb; i++) {
495     for (j = 0; j < workstation_nb; j++) {
496       cpu_L07_t card_src = workstation_list[i];
497       cpu_L07_t card_dst = workstation_list[j];
498       link_L07_t link;
499       xbt_dynar_t route = used_routing->get_route(card_src->id, card_dst->id);
500
501       if (communication_amount[i * workstation_nb + j] == 0.0)
502         continue;
503       xbt_dynar_foreach(route,cpt,link) {
504         lmm_expand_add(ptask_maxmin_system, link->constraint,
505                        action->variable,
506                        communication_amount[i * workstation_nb + j]);
507       }
508     }
509   }
510
511   if (nb_link + nb_host == 0) {
512     action->generic_action.cost = 1.0;
513     action->generic_action.remains = 0.0;
514   }
515
516   return (surf_action_t) action;
517 }
518
519 static surf_action_t execute(void *cpu, double size)
520 {
521   void **workstation_list = xbt_new0(void *, 1);
522   double *computation_amount = xbt_new0(double, 1);
523   double *communication_amount = xbt_new0(double, 1);
524
525   workstation_list[0] = cpu;
526   communication_amount[0] = 0.0;
527   computation_amount[0] = size;
528
529   return execute_parallel_task(1, workstation_list, computation_amount,
530                                communication_amount, 1, -1);
531 }
532
533 static surf_action_t communicate(void *src, void *dst, double size,
534                                  double rate)
535 {
536   void **workstation_list = xbt_new0(void *, 2);
537   double *computation_amount = xbt_new0(double, 2);
538   double *communication_amount = xbt_new0(double, 4);
539   surf_action_t res = NULL;
540
541   workstation_list[0] = src;
542   workstation_list[1] = dst;
543   communication_amount[1] = size;
544
545   res = execute_parallel_task(2, workstation_list,
546                               computation_amount, communication_amount,
547                               1, rate);
548
549   return res;
550 }
551
552 static surf_action_t action_sleep(void *cpu, double duration)
553 {
554   surf_action_workstation_L07_t action = NULL;
555
556   XBT_IN2("(%s,%g)", ((cpu_L07_t) cpu)->generic_resource.name, duration);
557
558   action = (surf_action_workstation_L07_t) execute(cpu, 1.0);
559   action->generic_action.max_duration = duration;
560   action->suspended = 2;
561   lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
562
563   XBT_OUT;
564   return (surf_action_t) action;
565 }
566
567 static xbt_dynar_t get_route(void *src, void *dst)
568 {
569   cpu_L07_t host_src = src;
570   cpu_L07_t host_dst = dst;
571
572   return used_routing->get_route(host_src->id, host_dst->id);
573 }
574
575 static double get_link_bandwidth(const void *link)
576 {
577   return ((link_L07_t) link)->bw_current;
578 }
579
580 static double get_link_latency(const void *link)
581 {
582   return ((link_L07_t) link)->lat_current;
583 }
584
585 static int link_shared(const void *link)
586 {
587   return lmm_constraint_is_shared(((link_L07_t) link)->constraint);
588 }
589
590 /**************************************/
591 /*** Resource Creation & Destruction **/
592 /**************************************/
593
594 static cpu_L07_t cpu_new(const char *name, double power_scale,
595                          double power_initial,
596                          tmgr_trace_t power_trace,
597                          e_surf_cpu_state_t state_initial,
598                          tmgr_trace_t state_trace, xbt_dict_t cpu_properties)
599 {
600   cpu_L07_t cpu = xbt_new0(s_cpu_L07_t, 1);
601   xbt_assert1(!surf_model_resource_by_name(surf_workstation_model, name),
602               "Host '%s' declared several times in the platform file.", name);
603
604   cpu->generic_resource.model = surf_workstation_model;
605   cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
606   cpu->generic_resource.name = xbt_strdup(name);
607   cpu->generic_resource.properties = current_property_set;
608   cpu->id = host_count++;
609
610   cpu->power_scale = power_scale;
611   xbt_assert0(cpu->power_scale > 0, "Power has to be >0");
612
613   cpu->power_current = power_initial;
614   if (power_trace)
615     cpu->power_event =
616       tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
617
618   cpu->state_current = state_initial;
619   if (state_trace)
620     cpu->state_event =
621       tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
622
623   cpu->constraint =
624     lmm_constraint_new(ptask_maxmin_system, cpu,
625                        cpu->power_current * cpu->power_scale);
626
627   xbt_dict_set(surf_model_resource_set(surf_workstation_model), name, cpu,
628                surf_resource_free);
629
630   return cpu;
631 }
632
633 static void parse_cpu_init(void)
634 {
635   double power_scale = 0.0;
636   double power_initial = 0.0;
637   tmgr_trace_t power_trace = NULL;
638   e_surf_cpu_state_t state_initial = SURF_CPU_OFF;
639   tmgr_trace_t state_trace = NULL;
640
641   power_scale = get_cpu_power(A_surfxml_host_power);
642   surf_parse_get_double(&power_initial, A_surfxml_host_availability);
643   surf_parse_get_trace(&power_trace, A_surfxml_host_availability_file);
644
645   xbt_assert0((A_surfxml_host_state == A_surfxml_host_state_ON) ||
646               (A_surfxml_host_state == A_surfxml_host_state_OFF),
647               "Invalid state");
648   if (A_surfxml_host_state == A_surfxml_host_state_ON)
649     state_initial = SURF_CPU_ON;
650   if (A_surfxml_host_state == A_surfxml_host_state_OFF)
651     state_initial = SURF_CPU_OFF;
652   surf_parse_get_trace(&state_trace, A_surfxml_host_state_file);
653
654   current_property_set = xbt_dict_new();
655   cpu_new(A_surfxml_host_id, power_scale, power_initial, power_trace,
656           state_initial, state_trace, current_property_set);
657 }
658
659 static link_L07_t link_new(char *name,
660                            double bw_initial,
661                            tmgr_trace_t bw_trace,
662                            double lat_initial,
663                            tmgr_trace_t lat_trace,
664                            e_surf_link_state_t
665                            state_initial,
666                            tmgr_trace_t state_trace,
667                            e_surf_link_sharing_policy_t
668                            policy, xbt_dict_t properties)
669 {
670   link_L07_t nw_link = xbt_new0(s_link_L07_t, 1);
671   xbt_assert1(!xbt_dict_get_or_null(surf_network_model->resource_set, name),
672               "Link '%s' declared several times in the platform file.", name);
673
674   nw_link->generic_resource.model = surf_workstation_model;
675   nw_link->generic_resource.properties = properties;
676   nw_link->generic_resource.name = name;
677   nw_link->type = SURF_WORKSTATION_RESOURCE_LINK;
678   nw_link->bw_current = bw_initial;
679   if (bw_trace)
680     nw_link->bw_event =
681       tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
682   nw_link->state_current = state_initial;
683   nw_link->lat_current = lat_initial;
684   if (lat_trace)
685     nw_link->lat_event =
686       tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
687   if (state_trace)
688     nw_link->state_event =
689       tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
690
691   nw_link->constraint =
692     lmm_constraint_new(ptask_maxmin_system, nw_link, nw_link->bw_current);
693
694   if (policy == SURF_LINK_FATPIPE)
695     lmm_constraint_shared(nw_link->constraint);
696
697
698   xbt_dict_set(surf_network_model->resource_set, name, nw_link, surf_resource_free);
699
700   return nw_link;
701 }
702
703 static void parse_link_init(void)
704 {
705   char *name_link;
706   double bw_initial;
707   tmgr_trace_t bw_trace;
708   double lat_initial;
709   tmgr_trace_t lat_trace;
710   e_surf_link_state_t state_initial_link = SURF_LINK_ON;
711   e_surf_link_sharing_policy_t policy_initial_link = SURF_LINK_SHARED;
712   tmgr_trace_t state_trace;
713
714   name_link = xbt_strdup(A_surfxml_link_id);
715   surf_parse_get_double(&bw_initial, A_surfxml_link_bandwidth);
716   surf_parse_get_trace(&bw_trace, A_surfxml_link_bandwidth_file);
717   surf_parse_get_double(&lat_initial, A_surfxml_link_latency);
718   surf_parse_get_trace(&lat_trace, A_surfxml_link_latency_file);
719
720   xbt_assert0((A_surfxml_link_state == A_surfxml_link_state_ON)
721               || (A_surfxml_link_state ==
722                   A_surfxml_link_state_OFF), "Invalid state");
723   if (A_surfxml_link_state == A_surfxml_link_state_ON)
724     state_initial_link = SURF_LINK_ON;
725   else if (A_surfxml_link_state == A_surfxml_link_state_OFF)
726     state_initial_link = SURF_LINK_OFF;
727
728   if (A_surfxml_link_sharing_policy == A_surfxml_link_sharing_policy_SHARED)
729     policy_initial_link = SURF_LINK_SHARED;
730   else if (A_surfxml_link_sharing_policy ==
731            A_surfxml_link_sharing_policy_FATPIPE)
732     policy_initial_link = SURF_LINK_FATPIPE;
733
734   surf_parse_get_trace(&state_trace, A_surfxml_link_state_file);
735
736   current_property_set = xbt_dict_new();
737   link_new(name_link, bw_initial, bw_trace, lat_initial, lat_trace,
738            state_initial_link, state_trace, policy_initial_link,
739            current_property_set);
740 }
741
742 static void add_traces(void)
743 {
744   xbt_dict_cursor_t cursor = NULL;
745   char *trace_name, *elm;
746
747   if (!trace_connect_list_host_avail)
748     return;
749
750   /* Connect traces relative to cpu */
751   xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
752     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
753     cpu_L07_t host = surf_model_resource_by_name(surf_workstation_model, elm);
754
755     xbt_assert1(host, "Host %s undefined", elm);
756     xbt_assert1(trace, "Trace %s undefined", trace_name);
757
758     host->state_event = tmgr_history_add_trace(history, trace, 0.0, 0, host);
759   }
760
761   xbt_dict_foreach(trace_connect_list_power, 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->power_event = tmgr_history_add_trace(history, trace, 0.0, 0, host);
769   }
770
771   /* Connect traces relative to network */
772   xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
773     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
774     link_L07_t link = xbt_dict_get_or_null(surf_network_model->resource_set, elm);
775
776     xbt_assert1(link, "Link %s undefined", elm);
777     xbt_assert1(trace, "Trace %s undefined", trace_name);
778
779     link->state_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
780   }
781
782   xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
783     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
784     link_L07_t link = xbt_dict_get_or_null(surf_network_model->resource_set, elm);
785
786     xbt_assert1(link, "Link %s undefined", elm);
787     xbt_assert1(trace, "Trace %s undefined", trace_name);
788
789     link->bw_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
790   }
791
792   xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
793     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
794     link_L07_t link = xbt_dict_get_or_null(surf_network_model->resource_set, elm);
795
796     xbt_assert1(link, "Link %s undefined", elm);
797     xbt_assert1(trace, "Trace %s undefined", trace_name);
798
799     link->lat_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
800   }
801 }
802
803 static void define_callbacks(const char *file)
804 {
805   /* Adding callback functions */
806   surf_parse_reset_parser();
807   surfxml_add_callback(STag_surfxml_host_cb_list, &parse_cpu_init);
808   surfxml_add_callback(STag_surfxml_link_cb_list, &parse_link_init);
809   surfxml_add_callback(ETag_surfxml_platform_cb_list, &add_traces);
810 }
811
812
813 /**************************************/
814 /********* Module  creation ***********/
815 /**************************************/
816
817 static void model_init_internal(void)
818 {
819   surf_workstation_model = surf_model_init();
820
821   surf_workstation_model->action_unref = action_unref;
822   surf_workstation_model->action_cancel = action_cancel;
823   surf_workstation_model->action_state_set = surf_action_state_set;
824   surf_workstation_model->suspend = action_suspend;
825   surf_workstation_model->resume = action_resume;
826   surf_workstation_model->is_suspended = action_is_suspended;
827   surf_workstation_model->set_max_duration = action_set_max_duration;
828   surf_workstation_model->set_priority = action_set_priority;
829   surf_workstation_model->name = "Workstation ptask_L07";
830
831   surf_workstation_model->model_private->resource_used = resource_used;
832   surf_workstation_model->model_private->share_resources = share_resources;
833   surf_workstation_model->model_private->update_actions_state =
834     update_actions_state;
835   surf_workstation_model->model_private->update_resource_state =
836     update_resource_state;
837   surf_workstation_model->model_private->finalize = finalize;
838
839   surf_workstation_model->extension.workstation.execute = execute;
840   surf_workstation_model->extension.workstation.sleep = action_sleep;
841   surf_workstation_model->extension.workstation.get_state =
842     resource_get_state;
843   surf_workstation_model->extension.workstation.get_speed = get_speed;
844   surf_workstation_model->extension.workstation.get_available_speed =
845     get_available_speed;
846   surf_workstation_model->extension.workstation.communicate = communicate;
847   surf_workstation_model->extension.workstation.get_route = get_route;
848   surf_workstation_model->extension.workstation.execute_parallel_task =
849     execute_parallel_task;
850   surf_workstation_model->extension.workstation.get_link_bandwidth =
851     get_link_bandwidth;
852   surf_workstation_model->extension.workstation.get_link_latency =
853     get_link_latency;
854   surf_workstation_model->extension.workstation.link_shared = link_shared;
855
856   if (!ptask_maxmin_system)
857     ptask_maxmin_system = lmm_system_new();
858
859   routing_model_full_create(sizeof(link_L07_t),
860         link_new(xbt_strdup("__MSG_loopback__"),
861             498000000, NULL, 0.000015, NULL,
862             SURF_LINK_ON, NULL, SURF_LINK_FATPIPE, NULL));
863
864 }
865
866 /**************************************/
867 /*************** Generic **************/
868 /**************************************/
869 void surf_workstation_model_init_ptask_L07(const char *filename)
870 {
871   xbt_assert0(!surf_cpu_model, "CPU model type already defined");
872   xbt_assert0(!surf_network_model, "network model type already defined");
873   surf_network_model = surf_model_init();
874   define_callbacks(filename);
875   model_init_internal();
876
877   update_model_description(surf_workstation_model_description,
878                            "ptask_L07", surf_workstation_model);
879   xbt_dynar_push(model_list, &surf_workstation_model);
880 }