Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix a few memory leaks.
[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 surf_action_t ptask_execute_parallel_task(int workstation_nb,
450                                                  void **workstation_list,
451                                                  double
452                                                  *computation_amount, double
453                                                  *communication_amount,
454                                                  double rate)
455 {
456   surf_action_workstation_L07_t action = NULL;
457   int i, j;
458   unsigned int cpt;
459   int nb_link = 0;
460   int nb_host = 0;
461   double latency = 0.0;
462
463   if (ptask_parallel_task_link_set == NULL)
464     ptask_parallel_task_link_set = xbt_dict_new_homogeneous(NULL);
465
466   xbt_dict_reset(ptask_parallel_task_link_set);
467
468   /* Compute the number of affected resources... */
469   for (i = 0; i < workstation_nb; i++) {
470     for (j = 0; j < workstation_nb; j++) {
471       xbt_dynar_t route=NULL;
472
473       if (communication_amount[i * workstation_nb + j] > 0) {
474         double lat=0.0;
475         unsigned int cpt;
476         link_L07_t link;
477
478         routing_get_route_and_latency(
479             ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[i]))->info,
480             ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[j]))->info,
481             &route,&lat);
482         latency = MAX(latency, lat);
483
484         xbt_dynar_foreach(route, cpt, link) {
485            xbt_dict_set(ptask_parallel_task_link_set,link->generic_resource.name,link,NULL);
486         }
487       }
488     }
489   }
490
491   nb_link = xbt_dict_length(ptask_parallel_task_link_set);
492   xbt_dict_reset(ptask_parallel_task_link_set);
493
494   for (i = 0; i < workstation_nb; i++)
495     if (computation_amount[i] > 0)
496       nb_host++;
497
498   action =
499       surf_action_new(sizeof(s_surf_action_workstation_L07_t), 1,
500                       surf_workstation_model, 0);
501   XBT_DEBUG("Creating a parallel task (%p) with %d cpus and %d links.",
502          action, workstation_nb, nb_link);
503   action->suspended = 0;        /* Should be useless because of the
504                                    calloc but it seems to help valgrind... */
505   action->workstation_nb = workstation_nb;
506   action->workstation_list = (cpu_L07_t *) workstation_list;
507   action->computation_amount = computation_amount;
508   action->communication_amount = communication_amount;
509   action->latency = latency;
510   action->rate = rate;
511
512   action->variable =
513       lmm_variable_new(ptask_maxmin_system, action, 1.0,
514                        (action->rate > 0) ? action->rate : -1.0,
515                        workstation_nb + nb_link);
516
517   if (action->latency > 0)
518     lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
519
520   for (i = 0; i < workstation_nb; i++)
521     lmm_expand(ptask_maxmin_system,
522                ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[i]))->constraint,
523                action->variable, computation_amount[i]);
524
525   for (i = 0; i < workstation_nb; i++) {
526     for (j = 0; j < workstation_nb; j++) {
527       link_L07_t link;
528       xbt_dynar_t route=NULL;
529       if (communication_amount[i * workstation_nb + j] == 0.0)
530         continue;
531
532       routing_get_route_and_latency(
533           ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[i]))->info,
534           ((cpu_L07_t)surf_workstation_resource_priv(workstation_list[j]))->info,
535           &route,NULL);
536
537       xbt_dynar_foreach(route, cpt, link) {
538         lmm_expand_add(ptask_maxmin_system, link->constraint,
539                        action->variable,
540                        communication_amount[i * workstation_nb + j]);
541       }
542     }
543   }
544
545   if (nb_link + nb_host == 0) {
546     action->generic_action.cost = 1.0;
547     action->generic_action.remains = 0.0;
548   }
549
550   return (surf_action_t) action;
551 }
552
553 static surf_action_t ptask_execute(void *cpu, double size)
554 {
555   void **workstation_list = xbt_new0(void *, 1);
556   double *computation_amount = xbt_new0(double, 1);
557   double *communication_amount = xbt_new0(double, 1);
558
559   workstation_list[0] = cpu;
560   communication_amount[0] = 0.0;
561   computation_amount[0] = size;
562
563   return ptask_execute_parallel_task(1, workstation_list,
564                                      computation_amount,
565                                      communication_amount, -1);
566 }
567
568 static surf_action_t ptask_communicate(void *src, void *dst, double size,
569                                        double rate)
570 {
571   void **workstation_list = xbt_new0(void *, 2);
572   double *computation_amount = xbt_new0(double, 2);
573   double *communication_amount = xbt_new0(double, 4);
574   surf_action_t res = NULL;
575
576   workstation_list[0] = src;
577   workstation_list[1] = dst;
578   communication_amount[1] = size;
579
580   res = ptask_execute_parallel_task(2, workstation_list,
581                                     computation_amount,
582                                     communication_amount, rate);
583
584   return res;
585 }
586
587 static surf_action_t ptask_action_sleep(void *cpu, double duration)
588 {
589   surf_action_workstation_L07_t action = NULL;
590
591   XBT_IN("(%s,%g)", surf_resource_name(cpu), duration);
592
593   action = (surf_action_workstation_L07_t) ptask_execute(cpu, 1.0);
594   action->generic_action.max_duration = duration;
595   action->suspended = 2;
596   lmm_update_variable_weight(ptask_maxmin_system, action->variable, 0.0);
597
598   XBT_OUT();
599   return (surf_action_t) action;
600 }
601
602 static xbt_dynar_t ptask_get_route(void *src, void *dst) // FIXME: kill that callback kind?
603 {
604   xbt_dynar_t route=NULL;
605   routing_get_route_and_latency(
606       ((cpu_L07_t)surf_workstation_resource_priv(src))->info, ((cpu_L07_t)surf_workstation_resource_priv(dst))->info,
607       &route,NULL);
608   return route;
609 }
610
611 static double ptask_get_link_bandwidth(const void *link)
612 {
613   return ((link_L07_t) link)->bw_current;
614 }
615
616 static double ptask_get_link_latency(const void *link)
617 {
618   return ((link_L07_t) link)->lat_current;
619 }
620
621 static int ptask_link_shared(const void *link)
622 {
623   return lmm_constraint_is_shared(((link_L07_t) link)->constraint);
624 }
625
626 /**************************************/
627 /*** Resource Creation & Destruction **/
628 /**************************************/
629
630 static void* ptask_cpu_create_resource(const char *name, double power_scale,
631                                double power_initial,
632                                tmgr_trace_t power_trace,
633                                e_surf_resource_state_t state_initial,
634                                tmgr_trace_t state_trace,
635                                xbt_dict_t cpu_properties)
636 {
637   cpu_L07_t cpu = NULL;
638   xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)),
639               "Host '%s' declared several times in the platform file.",
640               name);
641
642   cpu = (cpu_L07_t) surf_resource_new(sizeof(s_cpu_L07_t),
643           surf_workstation_model, name,cpu_properties);
644
645   cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
646   cpu->info = xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
647   if(!(cpu->info)) xbt_die("Don't find ROUTING_HOST_LEVEL for '%s'",name);
648
649   cpu->power_scale = power_scale;
650   xbt_assert(cpu->power_scale > 0, "Power has to be >0");
651
652   cpu->power_current = power_initial;
653   if (power_trace)
654     cpu->power_event =
655         tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
656
657   cpu->state_current = state_initial;
658   if (state_trace)
659     cpu->state_event =
660         tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
661
662   cpu->constraint =
663       lmm_constraint_new(ptask_maxmin_system, cpu,
664                          cpu->power_current * cpu->power_scale);
665
666   xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, cpu);
667
668   return xbt_lib_get_elm_or_null(host_lib, name);
669 }
670
671 static void ptask_parse_cpu_init(sg_platf_host_cbarg_t host)
672 {
673   ptask_cpu_create_resource(
674       host->id,
675       host->power_peak,
676       host->power_scale,
677       host->power_trace,
678       host->initial_state,
679       host->state_trace,
680       host->properties);
681 }
682
683 static void* ptask_link_create_resource(const char *name,
684                                  double bw_initial,
685                                  tmgr_trace_t bw_trace,
686                                  double lat_initial,
687                                  tmgr_trace_t lat_trace,
688                                  e_surf_resource_state_t
689                                  state_initial,
690                                  tmgr_trace_t state_trace,
691                                  e_surf_link_sharing_policy_t
692                                  policy, xbt_dict_t properties)
693 {
694   link_L07_t nw_link = xbt_new0(s_link_L07_t, 1);
695   xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL),
696               "Link '%s' declared several times in the platform file.",
697               name);
698
699   nw_link->generic_resource.model = surf_workstation_model;
700   nw_link->generic_resource.properties = properties;
701   nw_link->generic_resource.name = xbt_strdup(name);
702   nw_link->type = SURF_WORKSTATION_RESOURCE_LINK;
703   nw_link->bw_current = bw_initial;
704   if (bw_trace)
705     nw_link->bw_event =
706         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
707   nw_link->state_current = state_initial;
708   nw_link->lat_current = lat_initial;
709   if (lat_trace)
710     nw_link->lat_event =
711         tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
712   if (state_trace)
713     nw_link->state_event =
714         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
715
716   nw_link->constraint =
717       lmm_constraint_new(ptask_maxmin_system, nw_link,
718                          nw_link->bw_current);
719
720   if (policy == SURF_LINK_FATPIPE)
721     lmm_constraint_shared(nw_link->constraint);
722
723   xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, nw_link);
724   return nw_link;
725 }
726
727 static void ptask_parse_link_init(sg_platf_link_cbarg_t link)
728 {
729   if (link->policy == SURF_LINK_FULLDUPLEX) {
730     char *link_id;
731     link_id = bprintf("%s_UP", link->id);
732     ptask_link_create_resource(link_id,
733                                link->bandwidth,
734                                link->bandwidth_trace,
735                                link->latency,
736                                link->latency_trace,
737                                link->state,
738                                link->state_trace,
739                                link->policy,
740                                link->properties);
741     xbt_free(link_id);
742     link_id = bprintf("%s_DOWN", link->id);
743     ptask_link_create_resource(link_id,
744                                link->bandwidth,
745                                link->bandwidth_trace,
746                                link->latency,
747                                link->latency_trace,
748                                link->state,
749                                link->state_trace,
750                                link->policy,
751                                NULL); /* FIXME: We need to deep copy the
752                                        * properties or we won't be able to free
753                                        * it */
754     xbt_free(link_id);
755   } else {
756     ptask_link_create_resource(link->id,
757                                link->bandwidth,
758                                link->bandwidth_trace,
759                                link->latency,
760                                link->latency_trace,
761                                link->state,
762                                link->state_trace,
763                                link->policy,
764                                link->properties);
765   }
766
767   current_property_set = NULL;
768 }
769
770 static void ptask_add_traces(void)
771 {
772   xbt_dict_cursor_t cursor = NULL;
773   char *trace_name, *elm;
774
775   if (!trace_connect_list_host_avail)
776     return;
777
778   /* Connect traces relative to cpu */
779   xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
780     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
781     cpu_L07_t host = surf_workstation_resource_priv(surf_workstation_resource_by_name(elm));
782
783     xbt_assert(host, "Host %s undefined", elm);
784     xbt_assert(trace, "Trace %s undefined", trace_name);
785
786     host->state_event =
787         tmgr_history_add_trace(history, trace, 0.0, 0, host);
788   }
789
790   xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
791     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
792     cpu_L07_t host = surf_workstation_resource_priv(surf_workstation_resource_by_name(elm));
793
794     xbt_assert(host, "Host %s undefined", elm);
795     xbt_assert(trace, "Trace %s undefined", trace_name);
796
797     host->power_event =
798         tmgr_history_add_trace(history, trace, 0.0, 0, host);
799   }
800
801   /* Connect traces relative to network */
802   xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
803     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
804     link_L07_t link =
805         xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
806
807     xbt_assert(link, "Link %s undefined", elm);
808     xbt_assert(trace, "Trace %s undefined", trace_name);
809
810     link->state_event =
811         tmgr_history_add_trace(history, trace, 0.0, 0, link);
812   }
813
814   xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
815     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
816     link_L07_t link =
817         xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
818
819     xbt_assert(link, "Link %s undefined", elm);
820     xbt_assert(trace, "Trace %s undefined", trace_name);
821
822     link->bw_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
823   }
824
825   xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
826     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
827     link_L07_t link =
828         xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
829
830     xbt_assert(link, "Link %s undefined", elm);
831     xbt_assert(trace, "Trace %s undefined", trace_name);
832
833     link->lat_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
834   }
835 }
836
837 static void ptask_define_callbacks()
838 {
839   sg_platf_host_add_cb(ptask_parse_cpu_init);
840   sg_platf_link_add_cb(ptask_parse_link_init);
841   sg_platf_postparse_add_cb(ptask_add_traces);
842 }
843
844 /**************************************/
845 /********* Module  creation ***********/
846 /**************************************/
847
848 static void ptask_model_init_internal(void)
849 {
850   surf_workstation_model = surf_model_init();
851
852   surf_workstation_model->action_unref = ptask_action_unref;
853   surf_workstation_model->action_cancel = ptask_action_cancel;
854   surf_workstation_model->action_state_set = surf_action_state_set;
855   surf_workstation_model->suspend = ptask_action_suspend;
856   surf_workstation_model->resume = ptask_action_resume;
857   surf_workstation_model->is_suspended = ptask_action_is_suspended;
858   surf_workstation_model->set_max_duration = ptask_action_set_max_duration;
859   surf_workstation_model->set_priority = ptask_action_set_priority;
860   surf_workstation_model->get_remains = ptask_action_get_remains;
861   surf_workstation_model->name = "Workstation ptask_L07";
862
863   surf_workstation_model->model_private->resource_used =
864       ptask_resource_used;
865   surf_workstation_model->model_private->share_resources =
866       ptask_share_resources;
867   surf_workstation_model->model_private->update_actions_state =
868       ptask_update_actions_state;
869   surf_workstation_model->model_private->update_resource_state =
870       ptask_update_resource_state;
871   surf_workstation_model->model_private->finalize = ptask_finalize;
872
873
874   surf_workstation_model->extension.workstation.execute = ptask_execute;
875   surf_workstation_model->extension.workstation.sleep = ptask_action_sleep;
876   surf_workstation_model->extension.workstation.get_state =
877       ptask_resource_get_state;
878   surf_workstation_model->extension.workstation.get_speed =
879       ptask_get_speed;
880   surf_workstation_model->extension.workstation.get_available_speed =
881       ptask_get_available_speed;
882   surf_workstation_model->extension.workstation.communicate =
883       ptask_communicate;
884   surf_workstation_model->extension.workstation.get_route =
885       ptask_get_route;
886   surf_workstation_model->extension.workstation.execute_parallel_task =
887       ptask_execute_parallel_task;
888   surf_workstation_model->extension.workstation.get_link_bandwidth =
889       ptask_get_link_bandwidth;
890   surf_workstation_model->extension.workstation.get_link_latency =
891       ptask_get_link_latency;
892   surf_workstation_model->extension.workstation.link_shared =
893       ptask_link_shared;
894   surf_workstation_model->extension.workstation.get_properties =
895       surf_resource_properties;
896   surf_workstation_model->extension.workstation.add_traces =
897       ptask_add_traces;
898
899   if (!ptask_maxmin_system)
900     ptask_maxmin_system = lmm_system_new(1);
901
902   routing_model_create(ptask_link_create_resource("__loopback__",
903                                                   498000000, NULL,
904                                                   0.000015, NULL,
905                                                   SURF_RESOURCE_ON, NULL,
906                                                   SURF_LINK_FATPIPE, NULL));
907
908   surf_network_model = surf_model_init();
909
910   surf_network_model->extension.network.communicate = die_impossible_communicate;
911   surf_network_model->extension.network.get_route = die_impossible_get_route;
912   surf_network_model->extension.network.get_link_bandwidth = ptask_get_link_bandwidth;
913   surf_network_model->extension.network.get_link_latency = ptask_get_link_latency;
914   surf_network_model->extension.network.link_shared = ptask_link_shared;
915   surf_network_model->extension.network.add_traces = NULL;
916 }
917
918 /**************************************/
919 /*************** Generic **************/
920 /**************************************/
921 void surf_workstation_model_init_ptask_L07(void)
922 {
923   XBT_INFO("surf_workstation_model_init_ptask_L07");
924   xbt_assert(!surf_cpu_model, "CPU model type already defined");
925   xbt_assert(!surf_network_model, "network model type already defined");
926   ptask_define_callbacks();
927   ptask_model_init_internal();
928   xbt_dynar_push(model_list, &surf_workstation_model);
929 }