Logo AND Algorithmique Numérique Distribuée

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