Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
handle modifications of the DTD in surf
[simgrid.git] / src / surf / workstation_ptask_L07.c
1 /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "xbt/ex.h"
8 #include "xbt/str.h"
9 #include "xbt/dict.h"
10 #include "surf_private.h"
11 #include "surf/surf_resource.h"
12 //#include "surf/surf_resource_lmm.h"
13
14 typedef enum {
15   SURF_WORKSTATION_RESOURCE_CPU,
16   SURF_WORKSTATION_RESOURCE_LINK
17 } e_surf_workstation_model_type_t;
18
19 /**************************************/
20 /********* cpu object *****************/
21 /**************************************/
22 typedef struct cpu_L07 {
23   s_surf_resource_t generic_resource;   /* Do not move this field: must match surf_resource_t */
24   e_surf_workstation_model_type_t type; /* Do not move this field: must match link_L07_t */
25   lmm_constraint_t constraint;  /* Do not move this field: must match link_L07_t */
26   double power_scale;
27   double power_current;
28   tmgr_trace_event_t power_event;
29   tmgr_trace_event_t state_event;
30   e_surf_resource_state_t state_current;
31   sg_routing_edge_t info;
32 } s_cpu_L07_t, *cpu_L07_t;
33
34 /**************************************/
35 /*********** network object ***********/
36 /**************************************/
37
38 typedef struct link_L07 {
39   s_surf_resource_t generic_resource;   /* Do not move this field: must match surf_resource_t */
40   e_surf_workstation_model_type_t type; /* Do not move this field: must match cpu_L07_t */
41   lmm_constraint_t constraint;  /* Do not move this field: must match cpu_L07_t */
42   double lat_current;
43   tmgr_trace_event_t lat_event;
44   double bw_current;
45   tmgr_trace_event_t bw_event;
46   e_surf_resource_state_t state_current;
47   tmgr_trace_event_t state_event;
48 } s_link_L07_t, *link_L07_t;
49
50 /**************************************/
51 /*************** actions **************/
52 /**************************************/
53 typedef struct surf_action_workstation_L07 {
54   s_surf_action_t generic_action;
55   lmm_variable_t variable;
56   int workstation_nb;
57   cpu_L07_t *workstation_list;
58   double *computation_amount;
59   double *communication_amount;
60   double latency;
61   double rate;
62   int suspended;
63 } s_surf_action_workstation_L07_t, *surf_action_workstation_L07_t;
64
65
66 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_workstation);
67
68 static int ptask_host_count = 0;
69 static xbt_dict_t ptask_parallel_task_link_set = NULL;
70 lmm_system_t ptask_maxmin_system = NULL;
71
72 static surf_action_t die_impossible_communicate (sg_routing_edge_t src,
73                                                  sg_routing_edge_t dst,
74                                                  double size, double rate)
75 {
76   DIE_IMPOSSIBLE;
77   return NULL;
78 }
79
80 static xbt_dynar_t die_impossible_get_route(void *src, void *dst)
81 {
82   DIE_IMPOSSIBLE;
83   return NULL;
84 }
85
86 static void ptask_update_action_bound(surf_action_workstation_L07_t action)
87 {
88   int workstation_nb = action->workstation_nb;
89   double lat_current = 0.0;
90   double lat_bound = -1.0;
91   int i, j;
92
93   for (i = 0; i < workstation_nb; i++) {
94     for (j = 0; j < workstation_nb; j++) {
95       xbt_dynar_t route=NULL;
96
97       if (action->communication_amount[i * workstation_nb + j] > 0) {
98         double lat = 0.0;
99         routing_get_route_and_latency(((cpu_L07_t)surf_workstation_resource_priv(action->workstation_list[i]))->info,
100             ((cpu_L07_t)surf_workstation_resource_priv(action->workstation_list[j]))->info,
101             &route, &lat);
102         lat_current =
103             MAX(lat_current,
104                 lat * action->communication_amount[i * workstation_nb + j]);
105       }
106     }
107   }
108   lat_bound = sg_tcp_gamma / (2.0 * lat_current);
109   XBT_DEBUG("action (%p) : lat_bound = %g", action, lat_bound);
110   if ((action->latency == 0.0) && (action->suspended == 0)) {
111     if (action->rate < 0)
112       lmm_update_variable_bound(ptask_maxmin_system, action->variable,
113                                 lat_bound);
114     else
115       lmm_update_variable_bound(ptask_maxmin_system, action->variable,
116                                 min(action->rate, lat_bound));
117   }
118 }
119
120 /**************************************/
121 /******* Resource Public     **********/
122 /**************************************/
123
124 static int ptask_action_unref(surf_action_t action)
125 {
126   action->refcount--;
127
128   if (!action->refcount) {
129     xbt_swag_remove(action, action->state_set);
130     if (((surf_action_workstation_L07_t) action)->variable)
131       lmm_variable_free(ptask_maxmin_system,
132                         ((surf_action_workstation_L07_t)
133                          action)->variable);
134     free(((surf_action_workstation_L07_t) action)->workstation_list);
135     free(((surf_action_workstation_L07_t) action)->communication_amount);
136     free(((surf_action_workstation_L07_t) action)->computation_amount);
137 #ifdef HAVE_TRACING
138     xbt_free(action->category);
139 #endif
140     surf_action_free(&action);
141     return 1;
142   }
143   return 0;
144 }
145
146 static void ptask_action_cancel(surf_action_t action)
147 {
148   surf_action_state_set(action, SURF_ACTION_FAILED);
149   return;
150 }
151
152 /* action_change_state is inherited from the surf module */
153 /* action_set_data is inherited from the surf module */
154
155 static void ptask_action_suspend(surf_action_t action)
156 {
157   XBT_IN("(%p))", action);
158   if (((surf_action_workstation_L07_t) action)->suspended != 2) {
159     ((surf_action_workstation_L07_t) action)->suspended = 1;
160     lmm_update_variable_weight(ptask_maxmin_system,
161                                ((surf_action_workstation_L07_t)
162                                 action)->variable, 0.0);
163   }
164   XBT_OUT();
165 }
166
167 static void ptask_action_resume(surf_action_t action)
168 {
169   surf_action_workstation_L07_t act =
170       (surf_action_workstation_L07_t) action;
171
172   XBT_IN("(%p)", act);
173   if (act->suspended != 2) {
174     lmm_update_variable_weight(ptask_maxmin_system, act->variable, 1.0);
175     act->suspended = 0;
176   }
177   XBT_OUT();
178 }
179
180 static int ptask_action_is_suspended(surf_action_t action)
181 {
182   return (((surf_action_workstation_L07_t) action)->suspended == 1);
183 }
184
185 static void ptask_action_set_max_duration(surf_action_t action,
186                                           double duration)
187 {                               /* FIXME: should inherit */
188   XBT_IN("(%p,%g)", action, duration);
189   action->max_duration = duration;
190   XBT_OUT();
191 }
192
193
194 static void ptask_action_set_priority(surf_action_t action,
195                                       double priority)
196 {                               /* FIXME: should inherit */
197   XBT_IN("(%p,%g)", action, priority);
198   action->priority = priority;
199   XBT_OUT();
200 }
201
202 static double ptask_action_get_remains(surf_action_t action)
203 {
204   XBT_IN("(%p)", action);
205   XBT_OUT();
206   return action->remains;
207 }
208
209 /**************************************/
210 /******* Resource Private    **********/
211 /**************************************/
212
213 static int ptask_resource_used(void *resource_id)
214 {
215   /* We can freely cast as a link_L07_t because it has
216      the same prefix as cpu_L07_t */
217   return lmm_constraint_used(ptask_maxmin_system,
218                              ((link_L07_t) resource_id)->constraint);
219
220 }
221
222 static double ptask_share_resources(double now)
223 {
224   s_surf_action_workstation_L07_t s_action;
225   surf_action_workstation_L07_t action = NULL;
226
227   xbt_swag_t running_actions =
228       surf_workstation_model->states.running_action_set;
229   double min = generic_maxmin_share_resources(running_actions,
230                                               xbt_swag_offset(s_action,
231                                                               variable),
232                                               ptask_maxmin_system,
233                                               bottleneck_solve);
234
235   xbt_swag_foreach(action, running_actions) {
236     if (action->latency > 0) {
237       if (min < 0) {
238         min = action->latency;
239         XBT_DEBUG("Updating min (value) with %p (start %f): %f", action,
240                action->generic_action.start, min);
241       } else if (action->latency < min) {
242         min = action->latency;
243         XBT_DEBUG("Updating min (latency) with %p (start %f): %f", action,
244                action->generic_action.start, min);
245       }
246     }
247   }
248
249   XBT_DEBUG("min value : %f", min);
250
251   return min;
252 }
253
254 static void ptask_update_actions_state(double now, double delta)
255 {
256   double deltap = 0.0;
257   surf_action_workstation_L07_t action = NULL;
258   surf_action_workstation_L07_t next_action = NULL;
259   xbt_swag_t running_actions =
260       surf_workstation_model->states.running_action_set;
261
262   xbt_swag_foreach_safe(action, next_action, running_actions) {
263     deltap = delta;
264     if (action->latency > 0) {
265       if (action->latency > deltap) {
266         double_update(&(action->latency), deltap);
267         deltap = 0.0;
268       } else {
269         double_update(&(deltap), action->latency);
270         action->latency = 0.0;
271       }
272       if ((action->latency == 0.0) && (action->suspended == 0)) {
273         ptask_update_action_bound(action);
274         lmm_update_variable_weight(ptask_maxmin_system, action->variable,
275                                    1.0);
276       }
277     }
278     XBT_DEBUG("Action (%p) : remains (%g) updated by %g.",
279            action, action->generic_action.remains,
280            lmm_variable_getvalue(action->variable) * delta);
281     double_update(&(action->generic_action.remains),
282                   lmm_variable_getvalue(action->variable) * delta);
283
284     if (action->generic_action.max_duration != NO_MAX_DURATION)
285       double_update(&(action->generic_action.max_duration), delta);
286
287     XBT_DEBUG("Action (%p) : remains (%g).",
288            action, action->generic_action.remains);
289     if ((action->generic_action.remains <= 0) &&
290         (lmm_get_variable_weight(action->variable) > 0)) {
291       action->generic_action.finish = surf_get_clock();
292       surf_action_state_set((surf_action_t) action, SURF_ACTION_DONE);
293     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
294                (action->generic_action.max_duration <= 0)) {
295       action->generic_action.finish = surf_get_clock();
296       surf_action_state_set((surf_action_t) action, SURF_ACTION_DONE);
297     } else {
298       /* Need to check that none of the model has failed */
299       lmm_constraint_t cnst = NULL;
300       int i = 0;
301       void *constraint_id = NULL;
302
303       while ((cnst =
304               lmm_get_cnst_from_var(ptask_maxmin_system, action->variable,
305                                     i++))) {
306         constraint_id = lmm_constraint_id(cnst);
307
308 /*   if(((link_L07_t)constraint_id)->type== */
309 /*      SURF_WORKSTATION_RESOURCE_LINK) { */
310 /*     XBT_DEBUG("Checking for link %s (%p)", */
311 /*      ((link_L07_t)constraint_id)->name, */
312 /*      ((link_L07_t)constraint_id)); */
313 /*   } */
314 /*   if(((cpu_L07_t)constraint_id)->type== */
315 /*      SURF_WORKSTATION_RESOURCE_CPU) { */
316 /*     XBT_DEBUG("Checking for cpu %s (%p) : %s", */
317 /*      ((cpu_L07_t)constraint_id)->name, */
318 /*      ((cpu_L07_t)constraint_id), */
319 /*      ((cpu_L07_t)constraint_id)->state_current==SURF_CPU_OFF?"Off":"On"); */
320 /*   } */
321
322         if (((((link_L07_t) constraint_id)->type ==
323               SURF_WORKSTATION_RESOURCE_LINK) &&
324              (((link_L07_t) constraint_id)->state_current ==
325               SURF_RESOURCE_OFF)) ||
326             ((((cpu_L07_t) constraint_id)->type ==
327               SURF_WORKSTATION_RESOURCE_CPU) &&
328              (((cpu_L07_t) constraint_id)->state_current ==
329               SURF_RESOURCE_OFF))) {
330           XBT_DEBUG("Action (%p) Failed!!", action);
331           action->generic_action.finish = surf_get_clock();
332           surf_action_state_set((surf_action_t) action,
333                                 SURF_ACTION_FAILED);
334           break;
335         }
336       }
337     }
338   }
339   return;
340 }
341
342 static void ptask_update_resource_state(void *id,
343                                         tmgr_trace_event_t event_type,
344                                         double value, double date)
345 {
346   cpu_L07_t cpu = id;
347   link_L07_t nw_link = id;
348
349   if (nw_link->type == SURF_WORKSTATION_RESOURCE_LINK) {
350     XBT_DEBUG("Updating link %s (%p) with value=%f for date=%g",
351       surf_resource_name(nw_link), nw_link, value, date);
352     if (event_type == nw_link->bw_event) {
353       nw_link->bw_current = value;
354       lmm_update_constraint_bound(ptask_maxmin_system, nw_link->constraint,
355                                   nw_link->bw_current);
356       if (tmgr_trace_event_free(event_type))
357         nw_link->bw_event = NULL;
358     } else if (event_type == nw_link->lat_event) {
359       lmm_variable_t var = NULL;
360       surf_action_workstation_L07_t action = NULL;
361       lmm_element_t elem = NULL;
362
363       nw_link->lat_current = value;
364       while ((var = lmm_get_var_from_cnst
365               (ptask_maxmin_system, nw_link->constraint, &elem))) {
366
367
368         action = lmm_variable_id(var);
369         ptask_update_action_bound(action);
370       }
371       if (tmgr_trace_event_free(event_type))
372         nw_link->lat_event = NULL;
373
374     } else if (event_type == nw_link->state_event) {
375       if (value > 0)
376         nw_link->state_current = SURF_RESOURCE_ON;
377       else
378         nw_link->state_current = SURF_RESOURCE_OFF;
379       if (tmgr_trace_event_free(event_type))
380         nw_link->state_event = NULL;
381     } else {
382       XBT_CRITICAL("Unknown event ! \n");
383       xbt_abort();
384     }
385     return;
386   } else if (cpu->type == SURF_WORKSTATION_RESOURCE_CPU) {
387     XBT_DEBUG("Updating cpu %s (%p) with value %g", surf_resource_name(cpu),
388            cpu, value);
389     if (event_type == cpu->power_event) {
390       cpu->power_current = value;
391       lmm_update_constraint_bound(ptask_maxmin_system, cpu->constraint,
392                                   cpu->power_current * cpu->power_scale);
393       if (tmgr_trace_event_free(event_type))
394         cpu->power_event = NULL;
395     } else if (event_type == cpu->state_event) {
396       if (value > 0)
397         cpu->state_current = SURF_RESOURCE_ON;
398       else
399         cpu->state_current = SURF_RESOURCE_OFF;
400       if (tmgr_trace_event_free(event_type))
401         cpu->state_event = NULL;
402     } else {
403       XBT_CRITICAL("Unknown event ! \n");
404       xbt_abort();
405     }
406     return;
407   } else {
408     DIE_IMPOSSIBLE;
409   }
410   return;
411 }
412
413 static void ptask_finalize(void)
414 {
415   xbt_dict_free(&ptask_parallel_task_link_set);
416
417   surf_model_exit(surf_workstation_model);
418   surf_workstation_model = NULL;
419   surf_model_exit(surf_network_model);
420   surf_network_model = NULL;
421
422   ptask_host_count = 0;
423
424   if (ptask_maxmin_system) {
425     lmm_system_free(ptask_maxmin_system);
426     ptask_maxmin_system = NULL;
427   }
428 }
429
430 /**************************************/
431 /******* Resource Private    **********/
432 /**************************************/
433
434 static e_surf_resource_state_t ptask_resource_get_state(void *cpu)
435 {
436   return ((cpu_L07_t)surf_workstation_resource_priv(cpu))->state_current;
437 }
438
439 static double ptask_get_speed(void *cpu, double load)
440 {
441   return load * ((cpu_L07_t)surf_workstation_resource_priv(cpu))->power_scale;
442 }
443
444 static double ptask_get_available_speed(void *cpu)
445 {
446   return ((cpu_L07_t)surf_workstation_resource_priv(cpu))->power_current;
447 }
448
449 static double ws_get_current_power_peak(void *cpu)
450 {
451   return ((cpu_L07_t)surf_workstation_resource_priv(cpu))->power_current;
452 }
453
454 static double ws_get_power_peak_at(void *cpu, int pstate_index)
455 {
456         XBT_DEBUG("[ws_get_power_peak_at] Not implemented for workstation_ptask_L07");
457         return 0.0;
458 }
459
460 static int ws_get_nb_pstates(void *workstation)
461 {
462         XBT_DEBUG("[ws_get_nb_pstates] Not implemented for workstation_ptask_L07");
463         return 0.0;
464 }
465
466 static void ws_set_power_peak_at(void *cpu, int pstate_index)
467 {
468         XBT_DEBUG("[ws_set_power_peak_at] Not implemented for workstation_ptask_L07");
469 }
470
471 static double ws_get_consumed_energy(void *cpu)
472 {
473         XBT_DEBUG("[ws_get_consumed_energy] Not implemented for workstation_ptask_L07");
474         return 0.0;
475 }
476
477 static surf_action_t ptask_execute_parallel_task(int workstation_nb,
478                                                  void **workstation_list,
479                                                  double
480                                                  *computation_amount, double
481                                                  *communication_amount,
482                                                  double rate)
483 {
484   surf_action_workstation_L07_t action = NULL;
485   int i, j;
486   unsigned int cpt;
487   int nb_link = 0;
488   int nb_host = 0;
489   double latency = 0.0;
490
491   if (ptask_parallel_task_link_set == NULL)
492     ptask_parallel_task_link_set = xbt_dict_new_homogeneous(NULL);
493
494   xbt_dict_reset(ptask_parallel_task_link_set);
495
496   /* Compute the number of affected resources... */
497   for (i = 0; i < workstation_nb; i++) {
498     for (j = 0; j < workstation_nb; j++) {
499       xbt_dynar_t route=NULL;
500
501       if (communication_amount[i * workstation_nb + j] > 0) {
502         double lat=0.0;
503         unsigned int cpt;
504         link_L07_t link;
505
506         routing_get_route_and_latency(
507             ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[i]))->info,
508             ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[j]))->info,
509             &route,&lat);
510         latency = MAX(latency, lat);
511
512         xbt_dynar_foreach(route, cpt, link) {
513            xbt_dict_set(ptask_parallel_task_link_set,link->generic_resource.name,link,NULL);
514         }
515       }
516     }
517   }
518
519   nb_link = xbt_dict_length(ptask_parallel_task_link_set);
520   xbt_dict_reset(ptask_parallel_task_link_set);
521
522   for (i = 0; i < workstation_nb; i++)
523     if (computation_amount[i] > 0)
524       nb_host++;
525
526   action =
527       surf_action_new(sizeof(s_surf_action_workstation_L07_t), 1,
528                       surf_workstation_model, 0);
529   XBT_DEBUG("Creating a parallel task (%p) with %d cpus and %d links.",
530          action, workstation_nb, nb_link);
531   action->suspended = 0;        /* Should be useless because of the
532                                    calloc but it seems to help valgrind... */
533   action->workstation_nb = workstation_nb;
534   action->workstation_list = (cpu_L07_t *) workstation_list;
535   action->computation_amount = computation_amount;
536   action->communication_amount = communication_amount;
537   action->latency = latency;
538   action->rate = rate;
539
540   action->variable =
541       lmm_variable_new(ptask_maxmin_system, action, 1.0,
542                        (action->rate > 0) ? action->rate : -1.0,
543                        workstation_nb + nb_link);
544
545   if (action->latency > 0)
546     lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
547
548   for (i = 0; i < workstation_nb; i++)
549     lmm_expand(ptask_maxmin_system,
550                ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[i]))->constraint,
551                action->variable, computation_amount[i]);
552
553   for (i = 0; i < workstation_nb; i++) {
554     for (j = 0; j < workstation_nb; j++) {
555       link_L07_t link;
556       xbt_dynar_t route=NULL;
557       if (communication_amount[i * workstation_nb + j] == 0.0)
558         continue;
559
560       routing_get_route_and_latency(
561           ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[i]))->info,
562           ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[j]))->info,
563           &route,NULL);
564
565       xbt_dynar_foreach(route, cpt, link) {
566         lmm_expand_add(ptask_maxmin_system, link->constraint,
567                        action->variable,
568                        communication_amount[i * workstation_nb + j]);
569       }
570     }
571   }
572
573   if (nb_link + nb_host == 0) {
574     action->generic_action.cost = 1.0;
575     action->generic_action.remains = 0.0;
576   }
577
578   return (surf_action_t) action;
579 }
580
581 static surf_action_t ptask_execute(void *cpu, double size)
582 {
583   void **workstation_list = xbt_new0(void *, 1);
584   double *computation_amount = xbt_new0(double, 1);
585   double *communication_amount = xbt_new0(double, 1);
586
587   workstation_list[0] = cpu;
588   communication_amount[0] = 0.0;
589   computation_amount[0] = size;
590
591   return ptask_execute_parallel_task(1, workstation_list,
592                                      computation_amount,
593                                      communication_amount, -1);
594 }
595
596 static surf_action_t ptask_communicate(void *src, void *dst, double size,
597                                        double rate)
598 {
599   void **workstation_list = xbt_new0(void *, 2);
600   double *computation_amount = xbt_new0(double, 2);
601   double *communication_amount = xbt_new0(double, 4);
602   surf_action_t res = NULL;
603
604   workstation_list[0] = src;
605   workstation_list[1] = dst;
606   communication_amount[1] = size;
607
608   res = ptask_execute_parallel_task(2, workstation_list,
609                                     computation_amount,
610                                     communication_amount, rate);
611
612   return res;
613 }
614
615 static surf_action_t ptask_action_sleep(void *cpu, double duration)
616 {
617   surf_action_workstation_L07_t action = NULL;
618
619   XBT_IN("(%s,%g)", surf_resource_name(cpu), duration);
620
621   action = (surf_action_workstation_L07_t) ptask_execute(cpu, 1.0);
622   action->generic_action.max_duration = duration;
623   action->suspended = 2;
624   lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
625
626   XBT_OUT();
627   return (surf_action_t) action;
628 }
629
630 static xbt_dynar_t ptask_get_route(void *src, void *dst) // FIXME: kill that callback kind?
631 {
632   xbt_dynar_t route=NULL;
633   routing_get_route_and_latency(
634       ((cpu_L07_t)surf_workstation_resource_priv(src))->info, ((cpu_L07_t)surf_workstation_resource_priv(dst))->info,
635       &route,NULL);
636   return route;
637 }
638
639 static double ptask_get_link_bandwidth(const void *link)
640 {
641   return ((link_L07_t) link)->bw_current;
642 }
643
644 static double ptask_get_link_latency(const void *link)
645 {
646   return ((link_L07_t) link)->lat_current;
647 }
648
649 static int ptask_link_shared(const void *link)
650 {
651   return lmm_constraint_is_shared(((link_L07_t) link)->constraint);
652 }
653
654 /**************************************/
655 /*** Resource Creation & Destruction **/
656 /**************************************/
657
658 static void* ptask_cpu_create_resource(const char *name, double power_scale,
659                                double power_initial,
660                                tmgr_trace_t power_trace,
661                                e_surf_resource_state_t state_initial,
662                                tmgr_trace_t state_trace,
663                                xbt_dict_t cpu_properties)
664 {
665   cpu_L07_t cpu = NULL;
666   xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)),
667               "Host '%s' declared several times in the platform file.",
668               name);
669
670   cpu = (cpu_L07_t) surf_resource_new(sizeof(s_cpu_L07_t),
671           surf_workstation_model, name,cpu_properties);
672
673   cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
674   cpu->info = xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
675   if(!(cpu->info)) xbt_die("Don't find ROUTING_HOST_LEVEL for '%s'",name);
676
677   cpu->power_scale = power_scale;
678   xbt_assert(cpu->power_scale > 0, "Power has to be >0");
679
680   cpu->power_current = power_initial;
681   if (power_trace)
682     cpu->power_event =
683         tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
684
685   cpu->state_current = state_initial;
686   if (state_trace)
687     cpu->state_event =
688         tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
689
690   cpu->constraint =
691       lmm_constraint_new(ptask_maxmin_system, cpu,
692                          cpu->power_current * cpu->power_scale);
693
694   xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, cpu);
695
696   return xbt_lib_get_elm_or_null(host_lib, name);
697 }
698
699 static void ptask_parse_cpu_init(sg_platf_host_cbarg_t host)
700 {
701   double power_peak = xbt_dynar_get_as(host->power_peak, host->pstate, double);
702  //cpu->power_peak = power_peak;
703
704   ptask_cpu_create_resource(
705       host->id,
706       power_peak,
707       host->power_scale,
708       host->power_trace,
709       host->initial_state,
710       host->state_trace,
711       host->properties);
712 }
713
714 static void* ptask_link_create_resource(const char *name,
715                                  double bw_initial,
716                                  tmgr_trace_t bw_trace,
717                                  double lat_initial,
718                                  tmgr_trace_t lat_trace,
719                                  e_surf_resource_state_t
720                                  state_initial,
721                                  tmgr_trace_t state_trace,
722                                  e_surf_link_sharing_policy_t
723                                  policy, xbt_dict_t properties)
724 {
725   link_L07_t nw_link = xbt_new0(s_link_L07_t, 1);
726   xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL),
727               "Link '%s' declared several times in the platform file.",
728               name);
729
730   nw_link->generic_resource.model = surf_workstation_model;
731   nw_link->generic_resource.properties = properties;
732   nw_link->generic_resource.name = xbt_strdup(name);
733   nw_link->type = SURF_WORKSTATION_RESOURCE_LINK;
734   nw_link->bw_current = bw_initial;
735   if (bw_trace)
736     nw_link->bw_event =
737         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
738   nw_link->state_current = state_initial;
739   nw_link->lat_current = lat_initial;
740   if (lat_trace)
741     nw_link->lat_event =
742         tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
743   if (state_trace)
744     nw_link->state_event =
745         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
746
747   nw_link->constraint =
748       lmm_constraint_new(ptask_maxmin_system, nw_link,
749                          nw_link->bw_current);
750
751   if (policy == SURF_LINK_FATPIPE)
752     lmm_constraint_shared(nw_link->constraint);
753
754   xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, nw_link);
755   return nw_link;
756 }
757
758 static void ptask_parse_link_init(sg_platf_link_cbarg_t link)
759 {
760   if (link->policy == SURF_LINK_FULLDUPLEX) {
761     char *link_id;
762     link_id = bprintf("%s_UP", link->id);
763     ptask_link_create_resource(link_id,
764                                link->bandwidth,
765                                link->bandwidth_trace,
766                                link->latency,
767                                link->latency_trace,
768                                link->state,
769                                link->state_trace,
770                                link->policy,
771                                link->properties);
772     xbt_free(link_id);
773     link_id = bprintf("%s_DOWN", link->id);
774     ptask_link_create_resource(link_id,
775                                link->bandwidth,
776                                link->bandwidth_trace,
777                                link->latency,
778                                link->latency_trace,
779                                link->state,
780                                link->state_trace,
781                                link->policy,
782                                NULL); /* FIXME: We need to deep copy the
783                                        * properties or we won't be able to free
784                                        * it */
785     xbt_free(link_id);
786   } else {
787     ptask_link_create_resource(link->id,
788                                link->bandwidth,
789                                link->bandwidth_trace,
790                                link->latency,
791                                link->latency_trace,
792                                link->state,
793                                link->state_trace,
794                                link->policy,
795                                link->properties);
796   }
797
798   current_property_set = NULL;
799 }
800
801 static void ptask_add_traces(void)
802 {
803   xbt_dict_cursor_t cursor = NULL;
804   char *trace_name, *elm;
805
806   if (!trace_connect_list_host_avail)
807     return;
808
809   /* Connect traces relative to cpu */
810   xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
811     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
812     cpu_L07_t host = surf_workstation_resource_priv(surf_workstation_resource_by_name(elm));
813
814     xbt_assert(host, "Host %s undefined", elm);
815     xbt_assert(trace, "Trace %s undefined", trace_name);
816
817     host->state_event =
818         tmgr_history_add_trace(history, trace, 0.0, 0, host);
819   }
820
821   xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
822     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
823     cpu_L07_t host = surf_workstation_resource_priv(surf_workstation_resource_by_name(elm));
824
825     xbt_assert(host, "Host %s undefined", elm);
826     xbt_assert(trace, "Trace %s undefined", trace_name);
827
828     host->power_event =
829         tmgr_history_add_trace(history, trace, 0.0, 0, host);
830   }
831
832   /* Connect traces relative to network */
833   xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
834     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
835     link_L07_t link =
836         xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
837
838     xbt_assert(link, "Link %s undefined", elm);
839     xbt_assert(trace, "Trace %s undefined", trace_name);
840
841     link->state_event =
842         tmgr_history_add_trace(history, trace, 0.0, 0, link);
843   }
844
845   xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
846     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
847     link_L07_t link =
848         xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
849
850     xbt_assert(link, "Link %s undefined", elm);
851     xbt_assert(trace, "Trace %s undefined", trace_name);
852
853     link->bw_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
854   }
855
856   xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
857     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
858     link_L07_t link =
859         xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
860
861     xbt_assert(link, "Link %s undefined", elm);
862     xbt_assert(trace, "Trace %s undefined", trace_name);
863
864     link->lat_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
865   }
866 }
867
868 static void ptask_define_callbacks()
869 {
870   sg_platf_host_add_cb(ptask_parse_cpu_init);
871   sg_platf_link_add_cb(ptask_parse_link_init);
872   sg_platf_postparse_add_cb(ptask_add_traces);
873 }
874
875 /**************************************/
876 /********* Module  creation ***********/
877 /**************************************/
878
879 static void ptask_model_init_internal(void)
880 {
881   surf_workstation_model = surf_model_init();
882
883   surf_workstation_model->action_unref = ptask_action_unref;
884   surf_workstation_model->action_cancel = ptask_action_cancel;
885   surf_workstation_model->action_state_set = surf_action_state_set;
886   surf_workstation_model->suspend = ptask_action_suspend;
887   surf_workstation_model->resume = ptask_action_resume;
888   surf_workstation_model->is_suspended = ptask_action_is_suspended;
889   surf_workstation_model->set_max_duration = ptask_action_set_max_duration;
890   surf_workstation_model->set_priority = ptask_action_set_priority;
891   surf_workstation_model->get_remains = ptask_action_get_remains;
892   surf_workstation_model->name = "Workstation ptask_L07";
893
894   surf_workstation_model->model_private->resource_used =
895       ptask_resource_used;
896   surf_workstation_model->model_private->share_resources =
897       ptask_share_resources;
898   surf_workstation_model->model_private->update_actions_state =
899       ptask_update_actions_state;
900   surf_workstation_model->model_private->update_resource_state =
901       ptask_update_resource_state;
902   surf_workstation_model->model_private->finalize = ptask_finalize;
903
904
905   surf_workstation_model->extension.workstation.execute = ptask_execute;
906   surf_workstation_model->extension.workstation.sleep = ptask_action_sleep;
907   surf_workstation_model->extension.workstation.get_state =
908       ptask_resource_get_state;
909   surf_workstation_model->extension.workstation.get_speed =
910       ptask_get_speed;
911   surf_workstation_model->extension.workstation.get_available_speed =
912       ptask_get_available_speed;
913   surf_workstation_model->extension.workstation.get_current_power_peak = ws_get_current_power_peak;
914   surf_workstation_model->extension.workstation.get_power_peak_at = ws_get_power_peak_at;
915   surf_workstation_model->extension.workstation.get_nb_pstates = ws_get_nb_pstates;
916   surf_workstation_model->extension.workstation.set_power_peak_at = ws_set_power_peak_at;
917   surf_workstation_model->extension.workstation.get_consumed_energy = ws_get_consumed_energy;
918
919   surf_workstation_model->extension.workstation.communicate =
920       ptask_communicate;
921   surf_workstation_model->extension.workstation.get_route =
922       ptask_get_route;
923   surf_workstation_model->extension.workstation.execute_parallel_task =
924       ptask_execute_parallel_task;
925   surf_workstation_model->extension.workstation.get_link_bandwidth =
926       ptask_get_link_bandwidth;
927   surf_workstation_model->extension.workstation.get_link_latency =
928       ptask_get_link_latency;
929   surf_workstation_model->extension.workstation.link_shared =
930       ptask_link_shared;
931   surf_workstation_model->extension.workstation.get_properties =
932       surf_resource_properties;
933   surf_workstation_model->extension.workstation.add_traces =
934       ptask_add_traces;
935
936   if (!ptask_maxmin_system)
937     ptask_maxmin_system = lmm_system_new(1);
938
939   routing_model_create(ptask_link_create_resource("__loopback__",
940                                                   498000000, NULL,
941                                                   0.000015, NULL,
942                                                   SURF_RESOURCE_ON, NULL,
943                                                   SURF_LINK_FATPIPE, NULL));
944
945   surf_network_model = surf_model_init();
946
947   surf_network_model->extension.network.communicate = die_impossible_communicate;
948   surf_network_model->extension.network.get_route = die_impossible_get_route;
949   surf_network_model->extension.network.get_link_bandwidth = ptask_get_link_bandwidth;
950   surf_network_model->extension.network.get_link_latency = ptask_get_link_latency;
951   surf_network_model->extension.network.link_shared = ptask_link_shared;
952   surf_network_model->extension.network.add_traces = NULL;
953 }
954
955 /**************************************/
956 /*************** Generic **************/
957 /**************************************/
958 void surf_workstation_model_init_ptask_L07(void)
959 {
960   XBT_INFO("surf_workstation_model_init_ptask_L07");
961   xbt_assert(!surf_cpu_model, "CPU model type already defined");
962   xbt_assert(!surf_network_model, "network model type already defined");
963   ptask_define_callbacks();
964   ptask_model_init_internal();
965   xbt_dynar_push(model_list, &surf_workstation_model);
966 }