Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
getting rid of workstation_KCCFLN05_private.h
[simgrid.git] / src / surf / workstation_KCCFLN05.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2005 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/dict.h"
10 #include "surf_private.h"
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf,
13                                 "Logging specific to the SURF workstation module (KCCFLN05)");
14
15 typedef enum {
16   SURF_WORKSTATION_RESOURCE_CPU,
17   SURF_WORKSTATION_RESOURCE_LINK,
18 } e_surf_workstation_model_type_t;
19
20
21 /**************************************/
22 /********* router object **************/
23 /**************************************/
24 typedef struct router_KCCFLN05 {
25   char *name;           
26   unsigned int id;
27 } s_router_KCCFLN05_t, *router_KCCFLN05_t;
28
29
30 /**************************************/
31 /********* cpu object *****************/
32 /**************************************/
33 typedef struct cpu_KCCFLN05 {
34   surf_model_t model;
35   e_surf_workstation_model_type_t type; /* Do not move this field */
36   char *name;                                   /* Do not move this field */
37   lmm_constraint_t constraint;
38   lmm_constraint_t bus;
39   double power_scale;
40   double power_current;
41   double interference_send;
42   double interference_recv;
43   double interference_send_recv;
44   tmgr_trace_event_t power_event;
45   e_surf_cpu_state_t state_current;
46   tmgr_trace_event_t state_event;
47   int id;                       /* cpu and network card are a single object... */
48   xbt_dynar_t incomming_communications;
49   xbt_dynar_t outgoing_communications;
50 } s_cpu_KCCFLN05_t, *cpu_KCCFLN05_t;
51
52 /**************************************/
53 /*********** network object ***********/
54 /**************************************/
55
56 typedef struct network_link_KCCFLN05 {
57   surf_model_t model;
58   e_surf_workstation_model_type_t type; /* Do not move this field */
59   char *name;                                   /* Do not move this field */
60   lmm_constraint_t constraint;
61   double lat_current;
62   tmgr_trace_event_t lat_event;
63   double bw_current;
64   tmgr_trace_event_t bw_event;
65   e_surf_network_link_state_t state_current;
66   tmgr_trace_event_t state_event;
67 } s_network_link_KCCFLN05_t, *network_link_KCCFLN05_t;
68
69
70 typedef struct s_route_KCCFLN05 {
71   double impact_on_src;
72   double impact_on_dst;
73   double impact_on_src_with_other_recv;
74   double impact_on_dst_with_other_send;
75   network_link_KCCFLN05_t *links;
76   int size;
77 } s_route_KCCFLN05_t, *route_KCCFLN05_t;
78
79 /**************************************/
80 /*************** actions **************/
81 /**************************************/
82 typedef struct surf_action_workstation_KCCFLN05 {
83   s_surf_action_t generic_action;
84   double latency;
85   double lat_current;
86   lmm_variable_t variable;
87   double rate;
88   int suspended;
89   cpu_KCCFLN05_t src;           /* could be avoided */
90   cpu_KCCFLN05_t dst;           /* could be avoided */
91 } s_surf_action_workstation_KCCFLN05_t,
92   *surf_action_workstation_KCCFLN05_t;
93
94
95
96 static int nb_workstation = 0;
97 static s_route_KCCFLN05_t *routing_table = NULL;
98 #define ROUTE(i,j) routing_table[(i)+(j)*nb_workstation]
99 static network_link_KCCFLN05_t loopback = NULL;
100 static xbt_dict_t parallel_task_network_link_set = NULL;
101 //added to work with GTNETS
102 static xbt_dict_t router_set = NULL;
103
104 /*xbt_dict_t network_link_set = NULL;*/
105
106
107 /* convenient function */
108 static void __update_cpu_usage(cpu_KCCFLN05_t cpu)
109 {
110   int cpt;
111   surf_action_workstation_KCCFLN05_t action = NULL;
112   if ((!xbt_dynar_length(cpu->incomming_communications)) &&
113       (!xbt_dynar_length(cpu->outgoing_communications))) {
114     /* No communications */
115     lmm_update_constraint_bound(maxmin_system, cpu->constraint,
116                                 cpu->power_current * cpu->power_scale);
117   } else if ((!xbt_dynar_length(cpu->incomming_communications))
118              && (xbt_dynar_length(cpu->outgoing_communications))) {
119     /* Emission */
120     lmm_update_constraint_bound(maxmin_system, cpu->constraint,
121                                 cpu->power_current * cpu->power_scale *
122                                 cpu->interference_send);
123     xbt_dynar_foreach(cpu->outgoing_communications, cpt, action)
124         lmm_elem_set_value(maxmin_system, cpu->constraint,
125                            action->variable,
126                            cpu->power_current * cpu->power_scale *
127                            ROUTE(action->src->id,
128                                  action->dst->id).impact_on_src);
129   } else if ((xbt_dynar_length(cpu->incomming_communications))
130              && (!xbt_dynar_length(cpu->outgoing_communications))) {
131     /* Reception */
132     lmm_update_constraint_bound(maxmin_system, cpu->constraint,
133                                 cpu->power_current * cpu->power_scale *
134                                 cpu->interference_recv);
135     xbt_dynar_foreach(cpu->incomming_communications, cpt, action)
136         lmm_elem_set_value(maxmin_system, cpu->constraint,
137                            action->variable,
138                            cpu->power_current * cpu->power_scale *
139                            ROUTE(action->src->id,
140                                  action->dst->id).impact_on_dst);
141   } else {
142     /* Emission & Reception */
143     lmm_update_constraint_bound(maxmin_system, cpu->constraint,
144                                 cpu->power_current * cpu->power_scale *
145                                 cpu->interference_send_recv);
146     xbt_dynar_foreach(cpu->outgoing_communications, cpt, action)
147         lmm_elem_set_value(maxmin_system, cpu->constraint,
148                            action->variable,
149                            cpu->power_current * cpu->power_scale *
150                            ROUTE(action->src->id,
151                                  action->dst->id).
152                            impact_on_src_with_other_recv);
153     xbt_dynar_foreach(cpu->incomming_communications, cpt, action)
154         lmm_elem_set_value(maxmin_system, cpu->constraint,
155                            action->variable,
156                            cpu->power_current * cpu->power_scale *
157                            ROUTE(action->src->id,
158                                  action->dst->id).
159                            impact_on_dst_with_other_send);
160   }
161 }
162
163 /**************************************/
164 /******* Resource Public     **********/
165 /**************************************/
166
167 static void *name_service(const char *name)
168 {
169   xbt_ex_t e;
170   void *res = NULL;
171
172   TRY {
173     res = xbt_dict_get(workstation_set, name);
174   } CATCH(e) {
175     if (e.category != not_found_error)
176       RETHROW;
177     WARN1("Host '%s' not found, verifing if it is a router", name);
178     res = NULL;
179     xbt_ex_free(e);
180   }
181
182   return res;
183 }
184
185 static const char *get_model_name(void *model_id)
186 {
187   /* We can freely cast as a cpu_KCCFLN05_t because it has the same
188      prefix as network_link_KCCFLN05_t. However, only cpu_KCCFLN05_t
189      will theoretically be given as an argument here. */
190   return ((cpu_KCCFLN05_t) model_id)->name;
191 }
192
193 /* action_get_state is inherited from the surf module */
194
195 static void action_use(surf_action_t action)
196 {
197   action->using++;
198   return;
199 }
200
201 static int action_free(surf_action_t action)
202 {
203   int cpt;
204   surf_action_t act = NULL;
205   cpu_KCCFLN05_t src = ((surf_action_workstation_KCCFLN05_t) action)->src;
206   cpu_KCCFLN05_t dst = ((surf_action_workstation_KCCFLN05_t) action)->dst;
207
208   action->using--;
209   if (!action->using) {
210     xbt_swag_remove(action, action->state_set);
211     if (((surf_action_workstation_KCCFLN05_t) action)->variable)
212       lmm_variable_free(maxmin_system,
213                         ((surf_action_workstation_KCCFLN05_t) action)->
214                         variable);
215     if (src)
216       xbt_dynar_foreach(src->outgoing_communications, cpt, act)
217           if (act == action) {
218         xbt_dynar_remove_at(src->outgoing_communications, cpt, &act);
219         break;
220       }
221
222     if (dst)
223       xbt_dynar_foreach(dst->incomming_communications, cpt, act)
224           if (act == action) {
225         xbt_dynar_remove_at(dst->incomming_communications, cpt, &act);
226         break;
227       }
228
229     if (src && (!xbt_dynar_length(src->outgoing_communications)))
230       __update_cpu_usage(src);
231     if (dst && (!xbt_dynar_length(dst->incomming_communications)))
232       __update_cpu_usage(dst);
233
234     free(action);
235     return 1;
236   }
237   return 0;
238 }
239
240 static void action_cancel(surf_action_t action)
241 {
242   surf_action_change_state(action, SURF_ACTION_FAILED);
243   return;
244 }
245
246 static void action_recycle(surf_action_t action)
247 {
248   DIE_IMPOSSIBLE;
249   return;
250 }
251
252 /* action_change_state is inherited from the surf module */
253 /* action_set_data is inherited from the surf module */
254
255 static void action_suspend(surf_action_t action)
256 {
257   XBT_IN1("(%p))", action);
258   if (((surf_action_workstation_KCCFLN05_t) action)->suspended != 2) {
259     ((surf_action_workstation_KCCFLN05_t) action)->suspended = 1;
260     lmm_update_variable_weight(maxmin_system,
261                                ((surf_action_workstation_KCCFLN05_t)
262                                 action)->variable, 0.0);
263   }
264   XBT_OUT;
265 }
266
267 static void action_resume(surf_action_t action)
268 {
269   XBT_IN1("(%p)", action);
270   if (((surf_action_workstation_KCCFLN05_t) action)->suspended != 2) {
271     if (((surf_action_workstation_KCCFLN05_t) action)->lat_current == 0.0)
272       lmm_update_variable_weight(maxmin_system,
273                                  ((surf_action_workstation_KCCFLN05_t)
274                                   action)->variable, action->priority);
275     else
276       lmm_update_variable_weight(maxmin_system,
277                                  ((surf_action_workstation_KCCFLN05_t)
278                                   action)->variable,
279                                  ((surf_action_workstation_KCCFLN05_t)
280                                   action)->lat_current);
281
282     ((surf_action_workstation_KCCFLN05_t) action)->suspended = 0;
283   }
284   XBT_OUT;
285 }
286
287 static int action_is_suspended(surf_action_t action)
288 {
289   return (((surf_action_workstation_KCCFLN05_t) action)->suspended == 1);
290 }
291
292 static void action_set_max_duration(surf_action_t action, double duration)
293 {                               /* FIXME: should inherit */
294   XBT_IN2("(%p,%g)", action, duration);
295   action->max_duration = duration;
296   XBT_OUT;
297 }
298
299
300 static void action_set_priority(surf_action_t action, double priority)
301 {
302   XBT_IN2("(%p,%g)", action, priority);
303   action->priority = priority;
304   lmm_update_variable_weight(maxmin_system, ((surf_action_workstation_KCCFLN05_t) action)->variable, priority);
305
306   XBT_OUT;
307 }
308
309 /**************************************/
310 /******* Resource Private    **********/
311 /**************************************/
312
313 static int model_used(void *model_id)
314 {
315   /* We can freely cast as a network_link_KCCFLN05_t because it has
316      the same prefix as cpu_KCCFLN05_t */
317   if (((cpu_KCCFLN05_t) model_id)->type ==
318       SURF_WORKSTATION_RESOURCE_CPU)
319     return (lmm_constraint_used
320             (maxmin_system, ((cpu_KCCFLN05_t) model_id)->constraint)
321             || ((((cpu_KCCFLN05_t) model_id)->bus) ?
322                 lmm_constraint_used(maxmin_system,
323                                     ((cpu_KCCFLN05_t) model_id)->
324                                     bus) : 0));
325   else
326     return lmm_constraint_used(maxmin_system,
327                                ((network_link_KCCFLN05_t) model_id)->
328                                constraint);
329
330 }
331
332 static double share_models(double now)
333 {
334   s_surf_action_workstation_KCCFLN05_t s_action;
335   surf_action_workstation_KCCFLN05_t action = NULL;
336
337   xbt_swag_t running_actions =
338       surf_workstation_model->common_public->states.running_action_set;
339   double min = generic_maxmin_share_models(running_actions,
340                                               xbt_swag_offset(s_action,
341                                                               variable));
342
343   xbt_swag_foreach(action, running_actions) {
344     if (action->latency > 0) {
345       if (min < 0) {
346         min = action->latency;
347         DEBUG3("Updating min (value) with %p (start %f): %f", action,
348                action->generic_action.start, min);
349       } else if (action->latency < min) {
350         min = action->latency;
351         DEBUG3("Updating min (latency) with %p (start %f): %f", action,
352                action->generic_action.start, min);
353       }
354     }
355   }
356
357   DEBUG1("min value : %f", min);
358
359   return min;
360 }
361
362 static void update_actions_state(double now, double delta)
363 {
364   double deltap = 0.0;
365   surf_action_workstation_KCCFLN05_t action = NULL;
366   surf_action_workstation_KCCFLN05_t next_action = NULL;
367   xbt_swag_t running_actions =
368       surf_workstation_model->common_public->states.running_action_set;
369
370   xbt_swag_foreach_safe(action, next_action, running_actions) {
371     deltap = delta;
372     if (action->latency > 0) {
373       if (action->latency > deltap) {
374         double_update(&(action->latency), deltap);
375         deltap = 0.0;
376       } else {
377         double_update(&(deltap), action->latency);
378         action->latency = 0.0;
379       }
380       if ((action->latency == 0.0) && (action->suspended == 0)) {
381         if ((action)->lat_current == 0.0)
382           lmm_update_variable_weight(maxmin_system, action->variable, 1.0);
383         else
384           lmm_update_variable_weight(maxmin_system, action->variable,
385                                      action->lat_current);
386       }
387     }
388     DEBUG3("Action (%p) : remains (%g) updated by %g.",
389            action, action->generic_action.remains,
390            lmm_variable_getvalue(action->variable) * deltap);
391     double_update(&(action->generic_action.remains),
392                   lmm_variable_getvalue(action->variable) * deltap);
393
394     if (action->generic_action.max_duration != NO_MAX_DURATION)
395       double_update(&(action->generic_action.max_duration), delta);
396
397     if ((action->generic_action.remains <= 0) &&
398         (lmm_get_variable_weight(action->variable) > 0)) {
399       action->generic_action.finish = surf_get_clock();
400       surf_action_change_state((surf_action_t) action, SURF_ACTION_DONE);
401     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
402                (action->generic_action.max_duration <= 0)) {
403       action->generic_action.finish = surf_get_clock();
404       surf_action_change_state((surf_action_t) action, SURF_ACTION_DONE);
405     } else {
406       /* Need to check that none of the model has failed */
407       lmm_constraint_t cnst = NULL;
408       int i = 0;
409       void *constraint_id = NULL;
410
411       while ((cnst =
412               lmm_get_cnst_from_var(maxmin_system, action->variable,
413                                     i++))) {
414         constraint_id = lmm_constraint_id(cnst);
415
416 /*      if(((network_link_KCCFLN05_t)constraint_id)->type== */
417 /*         SURF_WORKSTATION_RESOURCE_LINK) { */
418 /*        DEBUG2("Checking for link %s (%p)", */
419 /*               ((network_link_KCCFLN05_t)constraint_id)->name, */
420 /*               ((network_link_KCCFLN05_t)constraint_id)); */
421 /*      } */
422 /*      if(((cpu_KCCFLN05_t)constraint_id)->type== */
423 /*         SURF_WORKSTATION_RESOURCE_CPU) { */
424 /*        DEBUG3("Checking for cpu %s (%p) : %s", */
425 /*               ((cpu_KCCFLN05_t)constraint_id)->name, */
426 /*               ((cpu_KCCFLN05_t)constraint_id), */
427 /*               ((cpu_KCCFLN05_t)constraint_id)->state_current==SURF_CPU_OFF?"Off":"On"); */
428 /*      } */
429
430         if (((((network_link_KCCFLN05_t) constraint_id)->type ==
431               SURF_WORKSTATION_RESOURCE_LINK) &&
432              (((network_link_KCCFLN05_t) constraint_id)->state_current ==
433               SURF_NETWORK_LINK_OFF)) ||
434             ((((cpu_KCCFLN05_t) constraint_id)->type ==
435               SURF_WORKSTATION_RESOURCE_CPU) &&
436              (((cpu_KCCFLN05_t) constraint_id)->state_current ==
437               SURF_CPU_OFF))) {
438           DEBUG1("Action (%p) Failed!!", action);
439           action->generic_action.finish = surf_get_clock();
440           surf_action_change_state((surf_action_t) action,
441                                    SURF_ACTION_FAILED);
442           break;
443         }
444       }
445     }
446   }
447   return;
448 }
449
450 static void update_model_state(void *id,
451                                   tmgr_trace_event_t event_type,
452                                   double value)
453 {
454   cpu_KCCFLN05_t cpu = id;
455   network_link_KCCFLN05_t nw_link = id;
456
457   if (nw_link->type == SURF_WORKSTATION_RESOURCE_LINK) {
458     DEBUG2("Updating link %s (%p)", nw_link->name, nw_link);
459     if (event_type == nw_link->bw_event) {
460       nw_link->bw_current = value;
461       lmm_update_constraint_bound(maxmin_system, nw_link->constraint,
462                                   nw_link->bw_current);
463     } else if (event_type == nw_link->lat_event) {
464       double delta = value - nw_link->lat_current;
465       lmm_variable_t var = NULL;
466       surf_action_workstation_KCCFLN05_t action = NULL;
467
468       nw_link->lat_current = value;
469       while (lmm_get_var_from_cnst
470              (maxmin_system, nw_link->constraint, &var)) {
471         action = lmm_variable_id(var);
472         action->lat_current += delta;
473         if (action->rate < 0)
474           lmm_update_variable_bound(maxmin_system, action->variable,
475                                     SG_TCP_CTE_GAMMA / (2.0 *
476                                                         action->
477                                                         lat_current));
478         else
479           lmm_update_variable_bound(maxmin_system, action->variable,
480                                     min(action->rate,
481                                         SG_TCP_CTE_GAMMA / (2.0 *
482                                                             action->
483                                                             lat_current)));
484         if (action->suspended == 0)
485           lmm_update_variable_weight(maxmin_system, action->variable,
486                                      action->lat_current);
487         lmm_update_variable_latency(maxmin_system, action->variable,
488                                     delta);
489
490
491       }
492     } else if (event_type == nw_link->state_event) {
493       if (value > 0)
494         nw_link->state_current = SURF_NETWORK_LINK_ON;
495       else
496         nw_link->state_current = SURF_NETWORK_LINK_OFF;
497     } else {
498       CRITICAL0("Unknown event ! \n");
499       xbt_abort();
500     }
501     return;
502   } else if (cpu->type == SURF_WORKSTATION_RESOURCE_CPU) {
503     DEBUG3("Updating cpu %s (%p) with value %g", cpu->name, cpu, value);
504     if (event_type == cpu->power_event) {
505       cpu->power_current = value;
506       __update_cpu_usage(cpu);
507     } else if (event_type == cpu->state_event) {
508       if (value > 0)
509         cpu->state_current = SURF_CPU_ON;
510       else
511         cpu->state_current = SURF_CPU_OFF;
512     } else {
513       CRITICAL0("Unknown event ! \n");
514       xbt_abort();
515     }
516     return;
517   } else {
518     DIE_IMPOSSIBLE;
519   }
520   return;
521 }
522
523 static void finalize(void)
524 {
525   int i, j;
526
527   xbt_dict_free(&network_link_set);
528   xbt_dict_free(&workstation_set);
529   xbt_dict_free(&router_set);
530   if (parallel_task_network_link_set != NULL) {
531     xbt_dict_free(&parallel_task_network_link_set);
532   }
533   xbt_swag_free(surf_workstation_model->common_public->states.
534                 ready_action_set);
535   xbt_swag_free(surf_workstation_model->common_public->states.
536                 running_action_set);
537   xbt_swag_free(surf_workstation_model->common_public->states.
538                 failed_action_set);
539   xbt_swag_free(surf_workstation_model->common_public->states.
540                 done_action_set);
541
542   free(surf_workstation_model->common_public);
543   free(surf_workstation_model->common_private);
544   free(surf_workstation_model->extension_public);
545
546   free(surf_workstation_model);
547   surf_workstation_model = NULL;
548
549   for (i = 0; i < nb_workstation; i++)
550     for (j = 0; j < nb_workstation; j++)
551       free(ROUTE(i, j).links);
552   free(routing_table);
553   routing_table = NULL;
554   nb_workstation = 0;
555
556   if (maxmin_system) {
557     lmm_system_free(maxmin_system);
558     maxmin_system = NULL;
559   }
560 }
561
562 /**************************************/
563 /******* Resource Private    **********/
564 /**************************************/
565
566 static surf_action_t execute(void *cpu, double size)
567 {
568   surf_action_workstation_KCCFLN05_t action = NULL;
569   cpu_KCCFLN05_t CPU = cpu;
570
571   XBT_IN2("(%s,%g)", CPU->name, size);
572   action = xbt_new0(s_surf_action_workstation_KCCFLN05_t, 1);
573
574   action->generic_action.using = 1;
575   action->generic_action.cost = size;
576   action->generic_action.remains = size;
577   action->generic_action.priority = 1.0;
578   action->generic_action.max_duration = NO_MAX_DURATION;
579   action->generic_action.start = surf_get_clock();
580   action->generic_action.finish = -1.0;
581   action->generic_action.model_type =
582       (surf_model_t) surf_workstation_model;
583   action->suspended = 0;
584
585   if (CPU->state_current == SURF_CPU_ON)
586     action->generic_action.state_set =
587         surf_workstation_model->common_public->states.
588         running_action_set;
589   else
590     action->generic_action.state_set =
591         surf_workstation_model->common_public->states.failed_action_set;
592   xbt_swag_insert(action, action->generic_action.state_set);
593
594   action->variable = lmm_variable_new(maxmin_system, action,
595                                       action->generic_action.priority,
596                                       -1.0, 1);
597   lmm_expand(maxmin_system, CPU->constraint, action->variable, 1.0);
598   XBT_OUT;
599   return (surf_action_t) action;
600 }
601
602 static surf_action_t action_sleep(void *cpu, double duration)
603 {
604   surf_action_workstation_KCCFLN05_t action = NULL;
605
606   XBT_IN2("(%s,%g)", ((cpu_KCCFLN05_t) cpu)->name, duration);
607
608   action = (surf_action_workstation_KCCFLN05_t) execute(cpu, 1.0);
609   action->generic_action.max_duration = duration;
610   action->suspended = 2;
611   lmm_update_variable_weight(maxmin_system, action->variable, 0.0);
612
613   XBT_OUT;
614   return (surf_action_t) action;
615 }
616
617 static e_surf_cpu_state_t model_get_state(void *cpu)
618 {
619   return ((cpu_KCCFLN05_t) cpu)->state_current;
620 }
621
622 static double get_speed(void *cpu, double load)
623 {
624   return load * (((cpu_KCCFLN05_t) cpu)->power_scale);
625 }
626
627 static double get_available_speed(void *cpu)
628 {
629   return ((cpu_KCCFLN05_t) cpu)->power_current;
630 }
631
632
633 static surf_action_t communicate(void *src, void *dst, double size,
634                                  double rate)
635 {
636   surf_action_workstation_KCCFLN05_t action = NULL;
637   cpu_KCCFLN05_t card_src = src;
638   cpu_KCCFLN05_t card_dst = dst;
639   route_KCCFLN05_t route = &(ROUTE(card_src->id, card_dst->id));
640   int route_size = route->size;
641   int i;
642
643   XBT_IN4("(%s,%s,%g,%g)", card_src->name, card_dst->name, size, rate);
644   xbt_assert2(route_size,
645               "You're trying to send data from %s to %s but there is no connexion between these two cards.",
646               card_src->name, card_dst->name);
647
648   action = xbt_new0(s_surf_action_workstation_KCCFLN05_t, 1);
649
650   action->generic_action.using = 1;
651   action->generic_action.cost = size;
652   action->generic_action.remains = size;
653   action->generic_action.max_duration = NO_MAX_DURATION;
654   action->generic_action.start = surf_get_clock();
655   action->generic_action.finish = -1.0;
656   action->src = src;
657   action->dst = dst;
658   action->generic_action.model_type =
659       (surf_model_t) surf_workstation_model;
660   action->suspended = 0;        /* Should be useless because of the 
661                                    calloc but it seems to help valgrind... */
662   action->generic_action.state_set =
663       surf_workstation_model->common_public->states.running_action_set;
664
665   xbt_dynar_push(card_src->outgoing_communications, &action);
666   xbt_dynar_push(card_dst->incomming_communications, &action);
667
668   xbt_swag_insert(action, action->generic_action.state_set);
669   action->rate = rate;
670
671   action->latency = 0.0;
672   for (i = 0; i < route_size; i++)
673     action->latency += route->links[i]->lat_current;
674   action->lat_current = action->latency;
675
676   if (action->latency > 0)
677     action->variable = lmm_variable_new(maxmin_system, action, 0.0, -1.0, route_size + 4);      /* +1 for the src bus
678                                                                                                    +1 for the dst bus
679                                                                                                    +1 for the src cpu
680                                                                                                    +1 for the dst cpu */
681   else
682     action->variable = lmm_variable_new(maxmin_system, action, 1.0, -1.0,
683                                         route_size + 4);
684
685   if (action->rate < 0) {
686     if (action->lat_current > 0)
687       lmm_update_variable_bound(maxmin_system, action->variable,
688                                 SG_TCP_CTE_GAMMA / (2.0 *
689                                                     action->lat_current));
690     else
691       lmm_update_variable_bound(maxmin_system, action->variable, -1.0);
692   } else {
693     if (action->lat_current > 0)
694       lmm_update_variable_bound(maxmin_system, action->variable,
695                                 min(action->rate,
696                                     SG_TCP_CTE_GAMMA / (2.0 *
697                                                         action->
698                                                         lat_current)));
699     else
700       lmm_update_variable_bound(maxmin_system, action->variable,
701                                 action->rate);
702   }
703
704   lmm_update_variable_latency(maxmin_system, action->variable,
705                               action->latency); /* Should be useless */
706
707   for (i = 0; i < route_size; i++)
708     lmm_expand(maxmin_system, route->links[i]->constraint,
709                action->variable, 1.0);
710   if (card_src->bus)
711     lmm_expand(maxmin_system, card_src->bus, action->variable, 1.0);
712   if (card_dst->bus)
713     lmm_expand(maxmin_system, card_dst->bus, action->variable, 1.0);
714   lmm_expand(maxmin_system, card_src->constraint, action->variable, 0.0);
715   lmm_expand(maxmin_system, card_dst->constraint, action->variable, 0.0);
716
717   XBT_OUT;
718   return (surf_action_t) action;
719 }
720
721 static surf_action_t execute_parallel_task(int workstation_nb,
722                                            void **workstation_list,
723                                            double *computation_amount,
724                                            double *communication_amount,
725                                            double amount, double rate)
726 {
727   surf_action_workstation_KCCFLN05_t action = NULL;
728   int i, j, k;
729   int nb_link = 0;
730   int nb_host = 0;
731
732   if (parallel_task_network_link_set == NULL) {
733     parallel_task_network_link_set =
734         xbt_dict_new_ext(workstation_nb * workstation_nb * 10);
735   }
736
737   /* Compute the number of affected resources... */
738   for (i = 0; i < workstation_nb; i++) {
739     for (j = 0; j < workstation_nb; j++) {
740       cpu_KCCFLN05_t card_src = workstation_list[i];
741       cpu_KCCFLN05_t card_dst = workstation_list[j];
742       int route_size = ROUTE(card_src->id, card_dst->id).size;
743       network_link_KCCFLN05_t *route =
744           ROUTE(card_src->id, card_dst->id).links;
745
746       if (communication_amount[i * workstation_nb + j] > 0)
747         for (k = 0; k < route_size; k++) {
748           xbt_dict_set(parallel_task_network_link_set, route[k]->name,
749                        route[k], NULL);
750         }
751     }
752   }
753   nb_link = xbt_dict_length(parallel_task_network_link_set);
754   xbt_dict_reset(parallel_task_network_link_set);
755
756
757   for (i = 0; i < workstation_nb; i++)
758     if (computation_amount[i] > 0)
759       nb_host++;
760
761   action = xbt_new0(s_surf_action_workstation_KCCFLN05_t, 1);
762   DEBUG3("Creating a parallel task (%p) with %d cpus and %d links.",
763          action, nb_host, nb_link);
764   action->generic_action.using = 1;
765   action->generic_action.cost = amount;
766   action->generic_action.remains = amount;
767   action->generic_action.max_duration = NO_MAX_DURATION;
768   action->generic_action.start = -1.0;
769   action->generic_action.finish = -1.0;
770   action->generic_action.model_type =
771       (surf_model_t) surf_workstation_model;
772   action->suspended = 0;        /* Should be useless because of the
773                                    calloc but it seems to help valgrind... */
774   action->generic_action.state_set =
775       surf_workstation_model->common_public->states.running_action_set;
776
777   xbt_swag_insert(action, action->generic_action.state_set);
778   action->rate = rate;
779
780   if (action->rate > 0)
781     action->variable = lmm_variable_new(maxmin_system, action, 1.0, -1.0,
782                                         nb_host + nb_link);
783   else
784     action->variable =
785         lmm_variable_new(maxmin_system, action, 1.0, action->rate,
786                          nb_host + nb_link);
787
788   for (i = 0; i < workstation_nb; i++)
789     if (computation_amount[i] > 0)
790       lmm_expand(maxmin_system,
791                  ((cpu_KCCFLN05_t) workstation_list[i])->constraint,
792                  action->variable, computation_amount[i]);
793
794   for (i = 0; i < workstation_nb; i++) {
795     for (j = 0; j < workstation_nb; j++) {
796       cpu_KCCFLN05_t card_src = workstation_list[i];
797       cpu_KCCFLN05_t card_dst = workstation_list[j];
798       int route_size = ROUTE(card_src->id, card_dst->id).size;
799       network_link_KCCFLN05_t *route =
800           ROUTE(card_src->id, card_dst->id).links;
801
802       for (k = 0; k < route_size; k++) {
803         if (communication_amount[i * workstation_nb + j] > 0) {
804           lmm_expand_add(maxmin_system, route[k]->constraint,
805                          action->variable,
806                          communication_amount[i * workstation_nb + j]);
807         }
808       }
809     }
810   }
811
812   if (nb_link + nb_host == 0) {
813     action->generic_action.cost = 1.0;
814     action->generic_action.remains = 0.0;
815   }
816
817   return (surf_action_t) action;
818 }
819
820 /* returns an array of network_link_KCCFLN05_t */
821 static const void **get_route(void *src, void *dst)
822 {
823   cpu_KCCFLN05_t card_src = src;
824   cpu_KCCFLN05_t card_dst = dst;
825   route_KCCFLN05_t route = &(ROUTE(card_src->id, card_dst->id));
826
827   return (const void **) route->links;
828 }
829
830 static int get_route_size(void *src, void *dst)
831 {
832   cpu_KCCFLN05_t card_src = src;
833   cpu_KCCFLN05_t card_dst = dst;
834   route_KCCFLN05_t route = &(ROUTE(card_src->id, card_dst->id));
835   return route->size;
836 }
837
838 static const char *get_link_name(const void *link)
839 {
840   return ((network_link_KCCFLN05_t) link)->name;
841 }
842
843 static double get_link_bandwidth(const void *link)
844 {
845   return ((network_link_KCCFLN05_t) link)->bw_current;
846 }
847
848 static double get_link_latency(const void *link)
849 {
850   return ((network_link_KCCFLN05_t) link)->lat_current;
851 }
852
853 /**************************************/
854 /*** Resource Creation & Destruction **/
855 /**************************************/
856
857
858 static void router_free(void *router)
859 {
860   free(((router_KCCFLN05_t) router)->name);
861 }
862
863 static void router_new(const char *name)
864 {
865   static unsigned int nb_routers = 0;
866
867   INFO1("Creating a router %s", name);
868
869   router_KCCFLN05_t router;
870   router = xbt_new0(s_router_KCCFLN05_t, 1);
871
872   router->name = xbt_strdup(name);
873   router->id = nb_routers++;
874   xbt_dict_set(router_set, name, router, router_free);
875 }
876
877 static void parse_routers(void)
878 {
879   //add a dumb router just to be GTNETS compatible
880   router_new(A_surfxml_router_name);
881 }
882
883 static void cpu_free(void *cpu)
884 {
885   free(((cpu_KCCFLN05_t) cpu)->name);
886   xbt_dynar_free(&(((cpu_KCCFLN05_t) cpu)->incomming_communications));
887   xbt_dynar_free(&(((cpu_KCCFLN05_t) cpu)->outgoing_communications));
888   free(cpu);
889 }
890
891 static cpu_KCCFLN05_t cpu_new(const char *name, double power_scale,
892                               double power_initial,
893                               tmgr_trace_t power_trace,
894                               e_surf_cpu_state_t state_initial,
895                               tmgr_trace_t state_trace,
896                               double interference_send,
897                               double interference_recv,
898                               double interference_send_recv,
899                               double max_outgoing_rate)
900 {
901   cpu_KCCFLN05_t cpu = xbt_new0(s_cpu_KCCFLN05_t, 1);
902
903   cpu->model = (surf_model_t) surf_workstation_model;
904   cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
905   cpu->name = xbt_strdup(name);
906   cpu->id = nb_workstation++;
907
908   cpu->power_scale = power_scale;
909   xbt_assert0(cpu->power_scale > 0, "Power has to be >0");
910
911   cpu->power_current = power_initial;
912   if (power_trace)
913     cpu->power_event =
914         tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
915
916   cpu->state_current = state_initial;
917   if (state_trace)
918     cpu->state_event =
919         tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
920
921   cpu->interference_send = interference_send;
922   cpu->interference_recv = interference_recv;
923   cpu->interference_send_recv = interference_send_recv;
924
925   cpu->constraint =
926       lmm_constraint_new(maxmin_system, cpu,
927                          cpu->power_current * cpu->power_scale);
928   if (max_outgoing_rate > 0)
929     cpu->bus = lmm_constraint_new(maxmin_system, cpu, max_outgoing_rate);
930
931   cpu->incomming_communications =
932       xbt_dynar_new(sizeof(surf_action_workstation_KCCFLN05_t), NULL);
933   cpu->outgoing_communications =
934       xbt_dynar_new(sizeof(surf_action_workstation_KCCFLN05_t), NULL);
935
936   xbt_dict_set(workstation_set, name, cpu, cpu_free);
937
938   return cpu;
939 }
940
941 static void parse_cpu(void)
942 {
943   double power_scale = 0.0;
944   double power_initial = 0.0;
945   tmgr_trace_t power_trace = NULL;
946   e_surf_cpu_state_t state_initial = SURF_CPU_OFF;
947   tmgr_trace_t state_trace = NULL;
948   double interference_send = 0.0;
949   double interference_recv = 0.0;
950   double interference_send_recv = 0.0;
951   double max_outgoing_rate = -1.0;
952
953   surf_parse_get_double(&power_scale, A_surfxml_cpu_power);
954   surf_parse_get_double(&power_initial, A_surfxml_cpu_availability);
955   surf_parse_get_trace(&power_trace, A_surfxml_cpu_availability_file);
956
957   xbt_assert0((A_surfxml_cpu_state == A_surfxml_cpu_state_ON) ||
958               (A_surfxml_cpu_state == A_surfxml_cpu_state_OFF),
959               "Invalid state");
960   if (A_surfxml_cpu_state == A_surfxml_cpu_state_ON)
961     state_initial = SURF_CPU_ON;
962   if (A_surfxml_cpu_state == A_surfxml_cpu_state_OFF)
963     state_initial = SURF_CPU_OFF;
964   surf_parse_get_trace(&state_trace, A_surfxml_cpu_state_file);
965
966   surf_parse_get_double(&interference_send,
967                         A_surfxml_cpu_interference_send);
968   surf_parse_get_double(&interference_recv,
969                         A_surfxml_cpu_interference_recv);
970   surf_parse_get_double(&interference_send_recv,
971                         A_surfxml_cpu_interference_send_recv);
972   surf_parse_get_double(&max_outgoing_rate,
973                         A_surfxml_cpu_max_outgoing_rate);
974
975   cpu_new(A_surfxml_cpu_name, power_scale, power_initial, power_trace,
976           state_initial, state_trace, interference_send, interference_recv,
977           interference_send_recv, max_outgoing_rate);
978 }
979
980 static void create_routing_table(void)
981 {
982   routing_table =
983       xbt_new0(s_route_KCCFLN05_t, nb_workstation * nb_workstation);
984 }
985
986 static void network_link_free(void *nw_link)
987 {
988   free(((network_link_KCCFLN05_t) nw_link)->name);
989   free(nw_link);
990 }
991
992 static network_link_KCCFLN05_t network_link_new(char *name,
993                                                 double bw_initial,
994                                                 tmgr_trace_t bw_trace,
995                                                 double lat_initial,
996                                                 tmgr_trace_t lat_trace,
997                                                 e_surf_network_link_state_t
998                                                 state_initial,
999                                                 tmgr_trace_t state_trace,
1000                                                 e_surf_network_link_sharing_policy_t
1001                                                 policy)
1002 {
1003   network_link_KCCFLN05_t nw_link = xbt_new0(s_network_link_KCCFLN05_t, 1);
1004
1005
1006   nw_link->model = (surf_model_t) surf_workstation_model;
1007   nw_link->type = SURF_WORKSTATION_RESOURCE_LINK;
1008   nw_link->name = name;
1009   nw_link->bw_current = bw_initial;
1010   if (bw_trace)
1011     nw_link->bw_event =
1012         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
1013   nw_link->state_current = state_initial;
1014   nw_link->lat_current = lat_initial;
1015   if (lat_trace)
1016     nw_link->lat_event =
1017         tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
1018   if (state_trace)
1019     nw_link->state_event =
1020         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
1021
1022   nw_link->constraint =
1023       lmm_constraint_new(maxmin_system, nw_link, nw_link->bw_current);
1024
1025   if (policy == SURF_NETWORK_LINK_FATPIPE)
1026     lmm_constraint_shared(nw_link->constraint);
1027
1028   xbt_dict_set(network_link_set, name, nw_link, network_link_free);
1029
1030   return nw_link;
1031 }
1032
1033 static void parse_network_link(void)
1034 {
1035   char *name;
1036   double bw_initial;
1037   tmgr_trace_t bw_trace;
1038   double lat_initial;
1039   tmgr_trace_t lat_trace;
1040   e_surf_network_link_state_t state_initial = SURF_NETWORK_LINK_ON;
1041   e_surf_network_link_sharing_policy_t policy_initial =
1042       SURF_NETWORK_LINK_SHARED;
1043   tmgr_trace_t state_trace;
1044
1045   name = xbt_strdup(A_surfxml_network_link_name);
1046   surf_parse_get_double(&bw_initial, A_surfxml_network_link_bandwidth);
1047   surf_parse_get_trace(&bw_trace, A_surfxml_network_link_bandwidth_file);
1048   surf_parse_get_double(&lat_initial, A_surfxml_network_link_latency);
1049   surf_parse_get_trace(&lat_trace, A_surfxml_network_link_latency_file);
1050
1051   xbt_assert0((A_surfxml_network_link_state ==
1052                A_surfxml_network_link_state_ON)
1053               || (A_surfxml_network_link_state ==
1054                   A_surfxml_network_link_state_OFF), "Invalid state");
1055   if (A_surfxml_network_link_state == A_surfxml_network_link_state_ON)
1056     state_initial = SURF_NETWORK_LINK_ON;
1057   else if (A_surfxml_network_link_state ==
1058            A_surfxml_network_link_state_OFF)
1059     state_initial = SURF_NETWORK_LINK_OFF;
1060
1061   if (A_surfxml_network_link_sharing_policy ==
1062       A_surfxml_network_link_sharing_policy_SHARED)
1063     policy_initial = SURF_NETWORK_LINK_SHARED;
1064   else if (A_surfxml_network_link_sharing_policy ==
1065            A_surfxml_network_link_sharing_policy_FATPIPE)
1066     policy_initial = SURF_NETWORK_LINK_FATPIPE;
1067
1068   surf_parse_get_trace(&state_trace, A_surfxml_network_link_state_file);
1069
1070   network_link_new(name, bw_initial, bw_trace,
1071                    lat_initial, lat_trace, state_initial, state_trace,
1072                    policy_initial);
1073 }
1074
1075 static void route_new(int src_id, int dst_id,
1076                       network_link_KCCFLN05_t * link_list, int nb_link,
1077                       double impact_on_src, double impact_on_dst,
1078                       double impact_on_src_with_other_recv,
1079                       double impact_on_dst_with_other_send)
1080 {
1081   route_KCCFLN05_t route = &(ROUTE(src_id, dst_id));
1082
1083   route->size = nb_link;
1084   route->links = link_list =
1085       xbt_realloc(link_list, sizeof(network_link_KCCFLN05_t) * nb_link);
1086   route->impact_on_src = impact_on_src;
1087   route->impact_on_dst = impact_on_src;
1088   route->impact_on_src_with_other_recv = impact_on_src_with_other_recv;
1089   route->impact_on_dst_with_other_send = impact_on_dst_with_other_send;
1090 }
1091
1092 static int nb_link;
1093 static int link_list_capacity;
1094 static network_link_KCCFLN05_t *link_list = NULL;
1095 static int src_id = -1;
1096 static int dst_id = -1;
1097 static double impact_on_src;
1098 static double impact_on_dst;
1099 static double impact_on_src_with_other_recv;
1100 static double impact_on_dst_with_other_send;
1101
1102 static void parse_route_set_endpoints(void)
1103 {
1104   cpu_KCCFLN05_t cpu_tmp = NULL;
1105
1106   cpu_tmp = (cpu_KCCFLN05_t) name_service(A_surfxml_route_src);
1107   if (cpu_tmp != NULL) {
1108     src_id = cpu_tmp->id;
1109   } else {
1110     xbt_assert1(xbt_dict_get_or_null(router_set, A_surfxml_route_src),
1111                 "Invalid name '%s': neither a cpu nor a router!",
1112                 A_surfxml_route_src);
1113     src_id = -1;
1114     return;
1115   }
1116
1117   cpu_tmp = (cpu_KCCFLN05_t) name_service(A_surfxml_route_dst);
1118   if (cpu_tmp != NULL) {
1119     dst_id = cpu_tmp->id;
1120   } else {
1121     xbt_assert1(xbt_dict_get_or_null(router_set, A_surfxml_route_dst),
1122                 "Invalid name '%s': neither a cpu nor a router!",
1123                 A_surfxml_route_dst);
1124     dst_id = -1;
1125     return;
1126   }
1127
1128   surf_parse_get_double(&impact_on_src, A_surfxml_route_impact_on_src);
1129   surf_parse_get_double(&impact_on_dst, A_surfxml_route_impact_on_dst);
1130   surf_parse_get_double(&impact_on_src_with_other_recv,
1131                         A_surfxml_route_impact_on_src_with_other_recv);
1132   surf_parse_get_double(&impact_on_dst_with_other_send,
1133                         A_surfxml_route_impact_on_dst_with_other_send);
1134
1135   nb_link = 0;
1136   link_list_capacity = 1;
1137   link_list = xbt_new(network_link_KCCFLN05_t, link_list_capacity);
1138
1139 }
1140
1141 static void parse_route_elem(void)
1142 {
1143   xbt_ex_t e;
1144   if (nb_link == link_list_capacity) {
1145     link_list_capacity *= 2;
1146     link_list =
1147         xbt_realloc(link_list,
1148                     (link_list_capacity) *
1149                     sizeof(network_link_KCCFLN05_t));
1150   }
1151   TRY {
1152     link_list[nb_link++] =
1153         xbt_dict_get(network_link_set, A_surfxml_route_element_name);
1154   }
1155   CATCH(e) {
1156     RETHROW1("Link %s not found (dict raised this exception: %s)",
1157              A_surfxml_route_element_name);
1158   }
1159 }
1160
1161 static void parse_route_set_route(void)
1162 {
1163   if (src_id != -1 && dst_id != -1)
1164     route_new(src_id, dst_id, link_list, nb_link, impact_on_src,
1165               impact_on_dst, impact_on_src_with_other_recv,
1166               impact_on_dst_with_other_send);
1167 }
1168
1169 static void parse_file(const char *file)
1170 {
1171   int i;
1172
1173   /* Figuring out the cpus */
1174   surf_parse_reset_parser();
1175   ETag_surfxml_cpu_fun = parse_cpu;
1176   surf_parse_open(file);
1177   xbt_assert1((!surf_parse()), "Parse error in %s", file);
1178   surf_parse_close();
1179
1180   create_routing_table();
1181
1182   /* Figuring out the router (added after GTNETS) */
1183   surf_parse_reset_parser();
1184   STag_surfxml_router_fun = parse_routers;
1185   surf_parse_open(file);
1186   xbt_assert1((!surf_parse()), "Parse error in %s", file);
1187   surf_parse_close();
1188
1189   /* Figuring out the network links */
1190   surf_parse_reset_parser();
1191   ETag_surfxml_network_link_fun = parse_network_link;
1192   surf_parse_open(file);
1193   xbt_assert1((!surf_parse()), "Parse error in %s", file);
1194   surf_parse_close();
1195
1196   /* Building the routes */
1197   surf_parse_reset_parser();
1198   STag_surfxml_route_fun = parse_route_set_endpoints;
1199   ETag_surfxml_route_element_fun = parse_route_elem;
1200   ETag_surfxml_route_fun = parse_route_set_route;
1201   surf_parse_open(file);
1202   xbt_assert1((!surf_parse()), "Parse error in %s", file);
1203   surf_parse_close();
1204
1205   /* Adding loopback if needed */
1206   for (i = 0; i < nb_workstation; i++)
1207     if (!ROUTE(i, i).size) {
1208       if (!loopback)
1209         loopback = network_link_new(xbt_strdup("__MSG_loopback__"),
1210                                     498000000, NULL, 0.000015, NULL,
1211                                     SURF_NETWORK_LINK_ON, NULL,
1212                                     SURF_NETWORK_LINK_FATPIPE);
1213       ROUTE(i, i).size = 1;
1214       ROUTE(i, i).links = xbt_new0(network_link_KCCFLN05_t, 1);
1215       ROUTE(i, i).links[0] = loopback;
1216     }
1217
1218 }
1219
1220 /**************************************/
1221 /********* Module  creation ***********/
1222 /**************************************/
1223
1224 static void model_init_internal(void)
1225 {
1226   s_surf_action_t action;
1227
1228   surf_workstation_model = xbt_new0(s_surf_workstation_model_t, 1);
1229
1230   surf_workstation_model->common_private =
1231       xbt_new0(s_surf_model_private_t, 1);
1232   surf_workstation_model->common_public =
1233       xbt_new0(s_surf_model_public_t, 1);
1234   surf_workstation_model->extension_public =
1235       xbt_new0(s_surf_workstation_model_extension_public_t, 1);
1236
1237   surf_workstation_model->common_public->states.ready_action_set =
1238       xbt_swag_new(xbt_swag_offset(action, state_hookup));
1239   surf_workstation_model->common_public->states.running_action_set =
1240       xbt_swag_new(xbt_swag_offset(action, state_hookup));
1241   surf_workstation_model->common_public->states.failed_action_set =
1242       xbt_swag_new(xbt_swag_offset(action, state_hookup));
1243   surf_workstation_model->common_public->states.done_action_set =
1244       xbt_swag_new(xbt_swag_offset(action, state_hookup));
1245
1246   surf_workstation_model->common_public->name_service = name_service;
1247   surf_workstation_model->common_public->get_model_name =
1248       get_model_name;
1249   surf_workstation_model->common_public->action_get_state =
1250       surf_action_get_state;
1251   surf_workstation_model->common_public->action_get_start_time =
1252       surf_action_get_start_time;
1253   surf_workstation_model->common_public->action_get_finish_time =
1254       surf_action_get_finish_time;
1255   surf_workstation_model->common_public->action_use = action_use;
1256   surf_workstation_model->common_public->action_free = action_free;
1257   surf_workstation_model->common_public->action_cancel = action_cancel;
1258   surf_workstation_model->common_public->action_recycle =
1259       action_recycle;
1260   surf_workstation_model->common_public->action_change_state =
1261       surf_action_change_state;
1262   surf_workstation_model->common_public->action_set_data =
1263       surf_action_set_data;
1264   surf_workstation_model->common_public->suspend = action_suspend;
1265   surf_workstation_model->common_public->resume = action_resume;
1266   surf_workstation_model->common_public->is_suspended =
1267       action_is_suspended;
1268   surf_workstation_model->common_public->set_max_duration =
1269       action_set_max_duration;
1270   surf_workstation_model->common_public->set_priority =
1271       action_set_priority;
1272   surf_workstation_model->common_public->name = "Workstation KCCFLN05";
1273
1274   surf_workstation_model->common_private->model_used = model_used;
1275   surf_workstation_model->common_private->share_models =
1276       share_models;
1277   surf_workstation_model->common_private->update_actions_state =
1278       update_actions_state;
1279   surf_workstation_model->common_private->update_model_state =
1280       update_model_state;
1281   surf_workstation_model->common_private->finalize = finalize;
1282
1283   surf_workstation_model->extension_public->execute = execute;
1284   surf_workstation_model->extension_public->sleep = action_sleep;
1285   surf_workstation_model->extension_public->get_state =
1286       model_get_state;
1287   surf_workstation_model->extension_public->get_speed = get_speed;
1288   surf_workstation_model->extension_public->get_available_speed =
1289       get_available_speed;
1290   surf_workstation_model->extension_public->communicate = communicate;
1291   surf_workstation_model->extension_public->execute_parallel_task =
1292       execute_parallel_task;
1293   surf_workstation_model->extension_public->get_route = get_route;
1294   surf_workstation_model->extension_public->get_route_size =
1295       get_route_size;
1296   surf_workstation_model->extension_public->get_link_name =
1297       get_link_name;
1298   surf_workstation_model->extension_public->get_link_bandwidth =
1299       get_link_bandwidth;
1300   surf_workstation_model->extension_public->get_link_latency =
1301       get_link_latency;
1302
1303   workstation_set = xbt_dict_new();
1304   router_set = xbt_dict_new();
1305   network_link_set = xbt_dict_new();
1306
1307   xbt_assert0(maxmin_system, "surf_init has to be called first!");
1308 }
1309
1310 /**************************************/
1311 /*************** Generic **************/
1312 /**************************************/
1313 void surf_workstation_model_init_KCCFLN05(const char *filename)
1314 {
1315   xbt_assert0(!surf_cpu_model, "CPU model type already defined");
1316   xbt_assert0(!surf_network_model,
1317               "network model type already defined");
1318   model_init_internal();
1319   parse_file(filename);
1320
1321   xbt_dynar_push(model_list, &surf_workstation_model);
1322 }