Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Make SURF complain when you ask to perform a communication between two non-connected...
[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 "workstation_KCCFLN05_private.h"
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(workstation_KCCFLN05, surf,
13                                 "Logging specific to the SURF workstation module (KCCFLN05)");
14
15
16 static lmm_system_t maxmin_system_cpu_KCCFLN05 = NULL;
17 static lmm_system_t maxmin_system_network_KCCFLN05 = NULL;
18 static xbt_dict_t network_link_set = NULL;
19 static int nb_workstation = 0;
20 static s_route_KCCFLN05_t *routing_table = NULL;
21 #define ROUTE(i,j) routing_table[(i)+(j)*nb_workstation]
22
23 /**************************************/
24 /************* CPU object *************/
25 /**************************************/
26
27 /************ workstation creation *********/
28 static void workstation_free(void *workstation)
29 {
30   free(((workstation_KCCFLN05_t)workstation)->name);
31   xbt_dynar_free(&(((workstation_KCCFLN05_t)workstation)->incomming_communications));
32   xbt_dynar_free(&(((workstation_KCCFLN05_t)workstation)->outgoing_communications));
33   free(workstation);
34 }
35
36 static workstation_KCCFLN05_t workstation_new(const char *name,
37                                               double power_scale,
38                                               double power_initial,
39                                               tmgr_trace_t power_trace,
40                                               e_surf_cpu_state_t state_initial,
41                                               tmgr_trace_t state_trace,
42                                               double interference_send,
43                                               double interference_recv,
44                                               double interference_send_recv,
45                                               double max_outgoing_rate)
46 {
47   workstation_KCCFLN05_t workstation = xbt_new0(s_workstation_KCCFLN05_t, 1);
48
49   workstation->resource = (surf_resource_t) surf_workstation_resource;
50   workstation->name = xbt_strdup(name);
51   workstation->id = nb_workstation++;
52
53   workstation->power_scale = power_scale;
54   xbt_assert0(workstation->power_scale>0,"Power has to be >0");
55
56   workstation->power_current = power_initial;
57   if (power_trace)
58     workstation->power_event =
59         tmgr_history_add_trace(history, power_trace, 0.0, 0, workstation);
60
61   workstation->state_current = state_initial;
62   if (state_trace)
63     workstation->state_event =
64         tmgr_history_add_trace(history, state_trace, 0.0, 0, workstation);
65
66   workstation->interference_send=interference_send;
67   workstation->interference_recv=interference_recv;
68   workstation->interference_send_recv=interference_send_recv;
69
70   workstation->constraint =
71       lmm_constraint_new(maxmin_system_cpu_KCCFLN05, workstation,
72                          workstation->power_current * workstation->power_scale);
73   if(max_outgoing_rate>0) 
74     workstation->bus=
75       lmm_constraint_new(maxmin_system_cpu_KCCFLN05, workstation,
76                          max_outgoing_rate);
77
78   workstation->incomming_communications = 
79     xbt_dynar_new(sizeof(surf_action_network_KCCFLN05_t),NULL);
80   workstation->outgoing_communications = 
81     xbt_dynar_new(sizeof(surf_action_network_KCCFLN05_t),NULL);
82
83   xbt_dict_set(workstation_set, name, workstation, workstation_free);
84
85   return workstation;
86 }
87
88 static void parse_workstation(void)
89 {
90   double power_scale = 0.0;
91   double power_initial = 0.0;
92   tmgr_trace_t power_trace = NULL;
93   e_surf_cpu_state_t state_initial = SURF_CPU_OFF;
94   tmgr_trace_t state_trace = NULL;
95   double interference_send = 0.0;
96   double interference_recv = 0.0;
97   double interference_send_recv = 0.0;
98   double max_outgoing_rate = -1.0;
99
100   surf_parse_get_double(&power_scale,A_cpu_power);
101   surf_parse_get_double(&power_initial,A_cpu_availability);
102   surf_parse_get_trace(&power_trace,A_cpu_availability_file);
103
104   xbt_assert0((A_cpu_state==A_cpu_state_ON)||
105               (A_cpu_state==A_cpu_state_OFF),
106               "Invalid state")
107   if (A_cpu_state==A_cpu_state_ON) state_initial = SURF_CPU_ON;
108   if (A_cpu_state==A_cpu_state_OFF) state_initial = SURF_CPU_OFF;
109   surf_parse_get_trace(&state_trace,A_cpu_state_file);
110
111   surf_parse_get_double(&interference_send,A_cpu_interference_send);
112   surf_parse_get_double(&interference_recv,A_cpu_interference_recv);
113   surf_parse_get_double(&interference_send_recv,A_cpu_interference_send_recv);
114   surf_parse_get_double(&max_outgoing_rate,A_cpu_max_outgoing_rate);
115
116   workstation_new(A_cpu_name, power_scale, power_initial, power_trace, state_initial,
117                   state_trace, interference_send, interference_recv,
118                   interference_send_recv, max_outgoing_rate);
119 }
120
121 /*********** resource management ***********/
122
123 static void *name_service(const char *name)
124 {
125   return xbt_dict_get_or_null(workstation_set, name);
126 }
127
128 static const char *get_resource_name(void *resource_id)
129 {
130   return ((workstation_KCCFLN05_t) resource_id)->name;
131 }
132
133 static int cpu_used(void *resource_id)
134 {
135   return lmm_constraint_used(maxmin_system_cpu_KCCFLN05,
136                              ((workstation_KCCFLN05_t) resource_id)->constraint);
137 }
138
139 static int link_used(void *resource_id)
140 {
141   return lmm_constraint_used(maxmin_system_network_KCCFLN05,
142                              ((network_link_KCCFLN05_t) resource_id)->constraint);
143 }
144
145 static e_surf_cpu_state_t get_state(void *cpu)
146 {
147   return ((workstation_KCCFLN05_t) cpu)->state_current;
148 }
149
150 static void update_cpu_KCCFLN05_state(void *id,
151                                       tmgr_trace_event_t event_type,
152                                       double value)
153 {
154   workstation_KCCFLN05_t cpu = id;
155
156   if (event_type == cpu->power_event) {
157     cpu->power_current = value;
158     /*** The bound is updated in share_cpu_KCCFLN05_resources ***/
159     /*     lmm_update_constraint_bound(maxmin_system_cpu_KCCFLN05, cpu->constraint, */
160     /*                          cpu->power_current * cpu->power_scale); */
161   } else if (event_type == cpu->state_event) {
162     if (value > 0)
163       cpu->state_current = SURF_CPU_ON;
164     else
165       cpu->state_current = SURF_CPU_OFF;
166   } else {
167     CRITICAL0("Unknown event ! \n");
168     xbt_abort();
169   }
170
171   return;
172 }
173
174 /**************************************/
175 /*********** network object ***********/
176 /**************************************/
177
178 static void create_routing_table(void)
179 {
180   routing_table = xbt_new0(s_route_KCCFLN05_t, nb_workstation * nb_workstation);
181 }
182
183 static void network_link_free(void *nw_link)
184 {
185   free(((network_link_KCCFLN05_t)nw_link)->name);
186   free(nw_link);
187 }
188
189 static network_link_KCCFLN05_t network_link_new(char *name,
190                                                  double bw_initial,
191                                                  tmgr_trace_t bw_trace,
192                                                  e_surf_network_link_state_t
193                                                  state_initial,
194                                                  tmgr_trace_t state_trace)
195 {
196   network_link_KCCFLN05_t nw_link = xbt_new0(s_network_link_KCCFLN05_t, 1);
197
198
199   nw_link->resource = (surf_resource_t) surf_network_resource;
200   nw_link->name = name;
201   nw_link->bw_current = bw_initial;
202   if (bw_trace)
203     nw_link->bw_event =
204         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
205   nw_link->state_current = state_initial;
206   if (state_trace)
207     nw_link->state_event =
208         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
209
210   nw_link->constraint =
211       lmm_constraint_new(maxmin_system_network_KCCFLN05, nw_link, nw_link->bw_current);
212
213   xbt_dict_set(network_link_set, name, nw_link, network_link_free);
214
215   return nw_link;
216 }
217
218 static void parse_network_link(void)
219 {
220   char *name;
221   double bw_initial;
222   tmgr_trace_t bw_trace;
223   e_surf_network_link_state_t state_initial = SURF_NETWORK_LINK_ON;
224   tmgr_trace_t state_trace;
225
226   name = xbt_strdup(A_network_link_name);
227   surf_parse_get_double(&bw_initial,A_network_link_bandwidth);
228   surf_parse_get_trace(&bw_trace, A_network_link_bandwidth_file);
229
230   xbt_assert0((A_network_link_state==A_network_link_state_ON)||
231               (A_network_link_state==A_network_link_state_OFF),
232               "Invalid state")
233   if (A_network_link_state==A_network_link_state_ON) 
234     state_initial = SURF_NETWORK_LINK_ON;
235   if (A_network_link_state==A_network_link_state_OFF) 
236     state_initial = SURF_NETWORK_LINK_OFF;
237   surf_parse_get_trace(&state_trace,A_network_link_state_file);
238
239   network_link_new(name, bw_initial, bw_trace, state_initial, state_trace);
240 }
241
242 static void route_new(int src_id, int dst_id, char **links, int nb_link,
243                       double impact_on_src, double impact_on_dst,
244                       double impact_on_src_with_other_recv,
245                       double impact_on_dst_with_other_send)
246 {
247   network_link_KCCFLN05_t *link_list = NULL;
248   int i;
249   route_KCCFLN05_t route = &(ROUTE(src_id,dst_id));
250
251   route->size= nb_link;
252   link_list = route->links = xbt_new0(network_link_KCCFLN05_t, nb_link);
253   for (i = 0; i < nb_link; i++) {
254     link_list[i] = xbt_dict_get_or_null(network_link_set, links[i]);
255     free(links[i]);
256   }
257   free(links);
258   route->impact_on_src=impact_on_src;
259   route->impact_on_dst=impact_on_src;
260   route->impact_on_src_with_other_recv=impact_on_src_with_other_recv; 
261   route->impact_on_dst_with_other_send=impact_on_dst_with_other_send;
262 }
263
264 static int nb_link = 0;
265 static char **link_name = NULL;
266 static int src_id = -1;
267 static int dst_id = -1;
268 static double impact_on_src;
269 static double impact_on_dst;
270 static double impact_on_src_with_other_recv; 
271 static double impact_on_dst_with_other_send;
272
273 static void parse_route_set_endpoints(void)
274 {
275   src_id = ((workstation_KCCFLN05_t) name_service(A_route_src))->id;
276   dst_id = ((workstation_KCCFLN05_t) name_service(A_route_dst))->id;
277   surf_parse_get_double(&impact_on_src,A_route_impact_on_src);
278   surf_parse_get_double(&impact_on_dst,A_route_impact_on_dst);
279   surf_parse_get_double(&impact_on_src_with_other_recv,A_route_impact_on_src_with_other_recv);
280   surf_parse_get_double(&impact_on_dst_with_other_send,A_route_impact_on_dst_with_other_send);
281
282   nb_link = 0;
283   link_name = NULL;
284 }
285
286 static void parse_route_elem(void)
287 {
288   nb_link++;
289   link_name = xbt_realloc(link_name, (nb_link) * sizeof(char *));
290   link_name[(nb_link) - 1] = xbt_strdup(A_route_element_name);
291 }
292
293 static void parse_route_set_route(void)
294 {
295   route_new(src_id, dst_id, link_name, nb_link, impact_on_src, impact_on_dst,
296             impact_on_src_with_other_recv, impact_on_dst_with_other_send);
297 }
298
299 static void parse_file(const char *file)
300 {
301   /* Figuring out the workstations */
302   surf_parse_reset_parser();
303   ETag_cpu_fun=parse_workstation;
304   surf_parse_open(file);
305   xbt_assert1((!surf_parse()),"Parse error in %s",file);
306   surf_parse_close();
307
308   create_routing_table();
309
310   /* Figuring out the network links */
311   surf_parse_reset_parser();
312   ETag_network_link_fun=parse_network_link;
313   surf_parse_open(file);
314   xbt_assert1((!surf_parse()),"Parse error in %s",file);
315   surf_parse_close();
316
317   /* Building the routes */
318   surf_parse_reset_parser();
319   STag_route_fun=parse_route_set_endpoints;
320   ETag_route_element_fun=parse_route_elem;
321   ETag_route_fun=parse_route_set_route;
322   surf_parse_open(file);
323   xbt_assert1((!surf_parse()),"Parse error in %s",file);
324   surf_parse_close();
325 }
326
327 static void update_network_KCCFLN05_state(void *id,
328                                           tmgr_trace_event_t event_type,
329                                           double value)
330 {
331   network_link_KCCFLN05_t nw_link = id;
332
333   if (event_type == nw_link->bw_event) {
334     nw_link->bw_current = value;
335     lmm_update_constraint_bound(maxmin_system_network_KCCFLN05, nw_link->constraint,
336                                 nw_link->bw_current);
337   } else if (event_type == nw_link->state_event) {
338     if (value > 0)
339       nw_link->state_current = SURF_NETWORK_LINK_ON;
340     else
341       nw_link->state_current = SURF_NETWORK_LINK_OFF;
342   } else {
343     CRITICAL0("Unknown event ! \n");
344     xbt_abort();
345   }
346
347   return;
348 }
349
350 /**************************************/
351 /*************** actions **************/
352 /**************************************/
353 /*************** network **************/
354 static int action_network_KCCFLN05_free(surf_action_t action)
355 {
356   int cpt;
357   surf_action_t act = NULL;
358   workstation_KCCFLN05_t src = ((surf_action_network_KCCFLN05_t) action)->src;
359   workstation_KCCFLN05_t dst = ((surf_action_network_KCCFLN05_t) action)->dst;
360
361   action->using--;
362   if(!action->using) {
363
364     xbt_swag_remove(action, action->state_set);
365     if(((surf_action_network_KCCFLN05_t)action)->variable)
366       lmm_variable_free(maxmin_system_network_KCCFLN05, 
367                         ((surf_action_network_KCCFLN05_t) action)->variable);
368     
369     xbt_dynar_foreach (src->outgoing_communications,cpt,act) {
370       if(act==action) {
371         xbt_dynar_remove_at(src->outgoing_communications, cpt, &act);
372         break;
373       }
374     }
375     
376     xbt_dynar_foreach (dst->incomming_communications,cpt,act) {
377       if(act==action) {
378         xbt_dynar_remove_at(dst->incomming_communications, cpt, &act);
379         break;
380       }
381     }
382     
383     free(action);
384     return 1;
385   }
386   return 0;
387 }
388
389 static void action_network_KCCFLN05_use(surf_action_t action)
390 {
391   action->using++;
392 }
393
394 static double share_network_KCCFLN05_resources(double now)
395 {
396  s_surf_action_network_KCCFLN05_t action;
397  return generic_maxmin_share_resources2(surf_network_resource->common_public->
398                                         states.running_action_set,
399                                         xbt_swag_offset(action, variable),
400                                         maxmin_system_network_KCCFLN05);
401 }
402
403 static void action_network_KCCFLN05_change_state(surf_action_t action,
404                                                  e_surf_action_state_t state)
405 {
406   int cpt;
407   surf_action_t act = NULL;
408   workstation_KCCFLN05_t src = ((surf_action_network_KCCFLN05_t) action)->src;
409   workstation_KCCFLN05_t dst = ((surf_action_network_KCCFLN05_t) action)->dst;
410
411 /*   if((state==SURF_ACTION_DONE) || (state==SURF_ACTION_FAILED)) */
412 /*     if(((surf_action_network_KCCFLN05_t)action)->variable) { */
413 /*       lmm_variable_disable(maxmin_system_network_KCCFLN05,  */
414 /*                         ((surf_action_network_KCCFLN05_t)action)->variable); */
415 /*       ((surf_action_network_KCCFLN05_t)action)->variable = NULL; */
416 /*     } */
417
418   xbt_dynar_foreach (src->outgoing_communications,cpt,act) {
419     if(act==action) {
420       xbt_dynar_remove_at(src->outgoing_communications, cpt, &act);
421       break;
422     }
423   }
424
425   xbt_dynar_foreach (dst->incomming_communications,cpt,act) {
426     if(act==action) {
427       xbt_dynar_remove_at(dst->incomming_communications, cpt, &act);
428       break;
429     }
430   }
431   surf_action_change_state(action, state);
432   return;
433 }
434
435 static void update_actions_network_KCCFLN05_state(double now, double delta)
436 {
437   surf_action_network_KCCFLN05_t action = NULL;
438   surf_action_network_KCCFLN05_t next_action = NULL;
439   xbt_swag_t running_actions =
440       surf_network_resource->common_public->states.running_action_set;
441   /* FIXME: unused
442   xbt_swag_t failed_actions =
443       surf_network_resource->common_public->states.failed_action_set;
444   */
445   xbt_swag_foreach_safe(action, next_action, running_actions) {
446     surf_double_update(&(action->generic_action.remains),
447                        lmm_variable_getvalue(action->variable) * delta);
448     if (action->generic_action.max_duration != NO_MAX_DURATION)
449           surf_double_update(&(action->generic_action.max_duration), delta);
450     if ((action->generic_action.remains <= 0.0) && 
451         (lmm_get_variable_weight(action->variable)>0)) {
452       action->generic_action.finish = surf_get_clock();
453       action_network_KCCFLN05_change_state((surf_action_t) action, SURF_ACTION_DONE);
454     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
455                (action->generic_action.max_duration <= 0.0)) {
456       action->generic_action.finish = surf_get_clock();
457       action_network_KCCFLN05_change_state((surf_action_t) action, SURF_ACTION_DONE);
458     } else {                    /* Need to check that none of the resource has failed */
459       /* FIXME : FAILURES ARE NOT HANDLED YET */
460     }
461   }
462
463   return;
464 }
465
466 static surf_action_t communicate_KCCFLN05(void *src, void *dst, double size,
467                                           double rate)
468 {
469   surf_action_network_KCCFLN05_t action = NULL;
470   workstation_KCCFLN05_t card_src = src;
471   workstation_KCCFLN05_t card_dst = dst;
472   route_KCCFLN05_t route = &ROUTE(card_src->id, card_dst->id);
473   int i;
474
475   xbt_assert2(route->size,"You're trying to send data from %s to %s but there is no connexion between these two cards.", card_src->name, card_dst->name);
476
477   action = xbt_new0(s_surf_action_network_KCCFLN05_t, 1);
478
479   action->generic_action.using = 1;
480   action->generic_action.cost = size;
481   action->generic_action.remains = size;
482   action->generic_action.max_duration = NO_MAX_DURATION;
483   action->generic_action.start = -1.0;
484   action->generic_action.finish = -1.0;
485   action->generic_action.resource_type =
486       (surf_resource_t) surf_network_resource;
487
488   action->generic_action.state_set =
489       surf_network_resource->common_public->states.running_action_set;
490
491   xbt_swag_insert(action, action->generic_action.state_set);
492
493   if(rate>0)
494     action->variable = lmm_variable_new(maxmin_system_network_KCCFLN05, action, 1.0, rate,
495                                         route->size+1);
496   else
497     action->variable = lmm_variable_new(maxmin_system_network_KCCFLN05, action, 1.0, -1.0,
498                                         route->size+1);
499
500   for (i = 0; i < route->size; i++)
501     lmm_expand(maxmin_system_network_KCCFLN05, route->links[i]->constraint, 
502                action->variable, 1.0);
503
504   if(card_src->bus) 
505     lmm_expand(maxmin_system_network_KCCFLN05, card_src->bus, 
506                action->variable, 1.0);
507
508   action->src=src;
509   action->dst=dst;
510
511   xbt_dynar_push(card_src->outgoing_communications,&action);
512   xbt_dynar_push(card_dst->incomming_communications,&action);
513
514   return (surf_action_t) action;
515 }
516
517 static surf_action_t execute_parallel_task_KCCFLN05 (int workstation_nb,
518                                                      void **workstation_list,
519                                                      double *computation_amount,
520                                                      double *communication_amount,
521                                                      double amount,
522                                                      double rate)
523 {
524   DIE_IMPOSSIBLE;
525   return NULL;
526 }
527
528 static void network_KCCFLN05_action_suspend(surf_action_t action)
529 {
530   lmm_update_variable_weight(maxmin_system_network_KCCFLN05,
531                              ((surf_action_network_KCCFLN05_t) action)->variable, 0.0);
532 }
533
534 static void network_KCCFLN05_action_resume(surf_action_t action)
535 {
536   lmm_update_variable_weight(maxmin_system_network_KCCFLN05,
537                              ((surf_action_network_KCCFLN05_t) action)->variable, 1.0);
538 }
539
540 static int network_KCCFLN05_action_is_suspended(surf_action_t action)
541 {
542   return (lmm_get_variable_weight(((surf_action_network_KCCFLN05_t) action)->variable) == 0.0);
543 }
544
545 static void network_KCCFLN05_action_set_max_duration(surf_action_t action, double duration)
546 {
547   action->max_duration = duration;
548 }
549
550 /***************** CPU ****************/
551 static int action_cpu_KCCFLN05_free(surf_action_t action)
552 {
553   action->using--;
554   if(!action->using) {
555     xbt_swag_remove(action, action->state_set);
556     if(((surf_action_cpu_KCCFLN05_t)action)->variable)
557       lmm_variable_free(maxmin_system_cpu_KCCFLN05, ((surf_action_cpu_KCCFLN05_t)action)->variable);
558     free(action);
559     return 1;
560   }
561   return 0;
562 }
563
564 static void action_cpu_KCCFLN05_use(surf_action_t action)
565 {
566   action->using++;
567 }
568
569 static void action_cpu_KCCFLN05_change_state(surf_action_t action,
570                                 e_surf_action_state_t state)
571 {
572 /*   if((state==SURF_ACTION_DONE) || (state==SURF_ACTION_FAILED)) */
573 /*     if(((surf_action_cpu_KCCFLN05_t)action)->variable) { */
574 /*       lmm_variable_disable(maxmin_system_cpu_KCCFLN05,  */
575 /*                         ((surf_action_cpu_KCCFLN05_t)action)->variable); */
576 /*       ((surf_action_cpu_KCCFLN05_t)action)->variable = NULL; */
577 /*     } */
578
579   surf_action_change_state(action, state);
580   return;
581 }
582
583 static double share_cpu_KCCFLN05_resources(double now)
584 {
585   s_surf_action_cpu_KCCFLN05_t s_cpu_action;
586   lmm_constraint_t cnst = NULL;
587   workstation_KCCFLN05_t workstation = NULL;
588   double W=0.0;
589   double scale=0.0;
590   int cpt;
591   surf_action_network_KCCFLN05_t action;
592
593   if(surf_get_clock()>=475.895) 
594     {
595       W=0.0;
596     }
597
598   for(cnst = lmm_get_first_active_constraint(maxmin_system_cpu_KCCFLN05);
599       cnst;
600       cnst= lmm_get_next_active_constraint(maxmin_system_cpu_KCCFLN05, cnst))
601     {
602       workstation = lmm_constraint_id(cnst);
603       W=workstation->power_current * workstation->power_scale;
604       
605       if((!xbt_dynar_length(workstation->incomming_communications)) &&
606          (!xbt_dynar_length(workstation->outgoing_communications))) {
607         scale = 1.0;
608       } else if((!xbt_dynar_length(workstation->incomming_communications)) &&
609                 (xbt_dynar_length(workstation->outgoing_communications))) {
610         scale = workstation->interference_send;
611         xbt_dynar_foreach (workstation->outgoing_communications,cpt,action) {
612 /*        VOIRD(action->src->id); */
613 /*        VOIRD(action->dst->id); */
614 /*        VOIRP(&ROUTE(action->src->id,action->dst->id)); */
615 /*        VOIRG(ROUTE(action->src->id,action->dst->id).impact_on_src); */
616           scale -= ROUTE(action->src->id,action->dst->id).impact_on_src *
617             lmm_variable_getvalue(action->variable);
618         }
619         if(scale<0.0) scale=0.0;
620         xbt_assert0(scale>=0.0,"Negative interference !");
621       } else if((xbt_dynar_length(workstation->incomming_communications)) &&
622                 (!xbt_dynar_length(workstation->outgoing_communications))) {
623         scale = workstation->interference_recv;
624         xbt_dynar_foreach (workstation->incomming_communications,cpt,action) {
625           scale -= ROUTE(action->src->id,action->dst->id).impact_on_dst *
626             lmm_variable_getvalue(action->variable);
627         }
628         if(scale<0.0) scale=0.0;
629         xbt_assert0(scale>=0.0,"Negative interference !");
630       } else {
631         scale = workstation->interference_send_recv;
632         xbt_dynar_foreach (workstation->outgoing_communications,cpt,action) {
633           scale -= ROUTE(action->src->id,action->dst->id).impact_on_src_with_other_recv *
634             lmm_variable_getvalue(action->variable);
635         }
636         xbt_dynar_foreach (workstation->incomming_communications,cpt,action) {
637           scale -= ROUTE(action->src->id,action->dst->id).impact_on_dst_with_other_send *
638             lmm_variable_getvalue(action->variable);
639         }
640         if(scale<0.0) scale=0.1;
641         xbt_assert0(scale>=0.0,"Negative interference !");
642       }
643       lmm_update_constraint_bound(maxmin_system_cpu_KCCFLN05,workstation->constraint,
644                                   W*scale);
645     }
646
647   return generic_maxmin_share_resources2(surf_cpu_resource->common_public->
648                                          states.running_action_set,
649                                          xbt_swag_offset(s_cpu_action, variable),
650                                          maxmin_system_cpu_KCCFLN05);
651 }
652
653 static void update_actions_cpu_KCCFLN05_state(double now, double delta)
654 {
655   surf_action_cpu_KCCFLN05_t action = NULL;
656   surf_action_cpu_KCCFLN05_t next_action = NULL;
657   xbt_swag_t running_actions =
658       surf_cpu_resource->common_public->states.running_action_set;
659   /*
660   xbt_swag_t failed_actions =
661       surf_cpu_resource->common_public->states.failed_action_set;
662   */
663
664   xbt_swag_foreach_safe(action, next_action, running_actions) {
665     surf_double_update(&(action->generic_action.remains),
666         lmm_variable_getvalue(action->variable) * delta);
667     if (action->generic_action.max_duration != NO_MAX_DURATION)
668       action->generic_action.max_duration -= delta;
669     if ((action->generic_action.remains <= 0) && 
670         (lmm_get_variable_weight(action->variable)>0)) {
671       action->generic_action.finish = surf_get_clock();
672       action_cpu_KCCFLN05_change_state((surf_action_t) action, SURF_ACTION_DONE);
673     } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
674                (action->generic_action.max_duration <= 0)) {
675       action->generic_action.finish = surf_get_clock();
676       action_cpu_KCCFLN05_change_state((surf_action_t) action, SURF_ACTION_DONE);
677     } else {                    /* Need to check that none of the resource has failed */
678       lmm_constraint_t cnst = NULL;
679       int i = 0;
680       workstation_KCCFLN05_t cpu = NULL;
681
682       while ((cnst =
683               lmm_get_cnst_from_var(maxmin_system_cpu_KCCFLN05, action->variable,
684                                     i++))) {
685         cpu = lmm_constraint_id(cnst);
686         if (cpu->state_current == SURF_CPU_OFF) {
687           action->generic_action.finish = surf_get_clock();
688           action_cpu_KCCFLN05_change_state((surf_action_t) action, SURF_ACTION_FAILED);
689           break;
690         }
691       }
692     }
693   }
694
695   return;
696 }
697
698 static surf_action_t execute_KCCFLN05(void *cpu, double size)
699 {
700   surf_action_cpu_KCCFLN05_t action = NULL;
701   workstation_KCCFLN05_t CPU = cpu;
702
703   action = xbt_new0(s_surf_action_cpu_KCCFLN05_t, 1);
704
705   action->generic_action.using = 1;
706   action->generic_action.cost = size;
707   action->generic_action.remains = size;
708   action->generic_action.max_duration = NO_MAX_DURATION;
709   action->generic_action.start = surf_get_clock();
710   action->generic_action.finish = -1.0;
711   action->generic_action.resource_type =
712       (surf_resource_t) surf_cpu_resource;
713
714   if (CPU->state_current == SURF_CPU_ON)
715     action->generic_action.state_set =
716         surf_cpu_resource->common_public->states.running_action_set;
717   else
718     action->generic_action.state_set =
719         surf_cpu_resource->common_public->states.failed_action_set;
720   xbt_swag_insert(action, action->generic_action.state_set);
721
722   action->variable = lmm_variable_new(maxmin_system_cpu_KCCFLN05, action, 1.0, -1.0, 1);
723   lmm_expand(maxmin_system_cpu_KCCFLN05, CPU->constraint, action->variable,
724              1.0);
725
726   return (surf_action_t) action;
727 }
728
729 static void cpu_KCCFLN05_action_suspend(surf_action_t action)
730 {
731   lmm_update_variable_weight(maxmin_system_cpu_KCCFLN05,
732                              ((surf_action_cpu_KCCFLN05_t) action)->variable, 0.0);
733 }
734
735 static void cpu_KCCFLN05_action_resume(surf_action_t action)
736 {
737   lmm_update_variable_weight(maxmin_system_cpu_KCCFLN05,
738                              ((surf_action_cpu_KCCFLN05_t) action)->variable, 1.0);
739 }
740
741 static int cpu_KCCFLN05_action_is_suspended(surf_action_t action)
742 {
743   return (lmm_get_variable_weight(((surf_action_cpu_KCCFLN05_t) action)->variable) == 0.0);
744 }
745
746 static void cpu_KCCFLN05_action_set_max_duration(surf_action_t action, double duration)
747 {
748   action->max_duration = duration;
749 }
750
751 /************* workstation ************/
752 static void action_change_state(surf_action_t action,
753                                 e_surf_action_state_t state)
754 {
755   if(action->resource_type==(surf_resource_t)surf_network_resource) 
756     surf_network_resource->common_public->action_change_state(action,state);
757   else if(action->resource_type==(surf_resource_t)surf_cpu_resource) 
758     surf_cpu_resource->common_public->action_change_state(action,state);
759   else DIE_IMPOSSIBLE;
760   return;
761 }
762
763 static int action_free(surf_action_t action)
764 {
765   if(action->resource_type==(surf_resource_t)surf_network_resource) 
766     return surf_network_resource->common_public->action_free(action);
767   else if(action->resource_type==(surf_resource_t)surf_cpu_resource) 
768     return surf_cpu_resource->common_public->action_free(action);
769   else DIE_IMPOSSIBLE;
770   return 1;
771 }
772
773 static void action_use(surf_action_t action)
774 {
775   if(action->resource_type==(surf_resource_t)surf_network_resource) 
776     surf_network_resource->common_public->action_use(action);
777   else if(action->resource_type==(surf_resource_t)surf_cpu_resource) 
778     surf_cpu_resource->common_public->action_use(action);
779   else DIE_IMPOSSIBLE;
780   return;
781 }
782
783 static int resource_used(void *resource_id)
784 {
785   xbt_assert0(0, "Workstation is a virtual resource. I should not be there!");
786   return 0;
787 }
788
789 static double share_resources(double now)
790 {
791   return -1.0;
792 }
793
794 static void update_actions_state(double now, double delta)
795 {
796   return;
797 }
798
799 static void update_resource_state(void *id,
800                                   tmgr_trace_event_t event_type,
801                                   double value)
802 {
803   xbt_assert0(0, "Workstation is a virtual resource. I should not be there!");
804   return;
805 }
806
807 static void action_suspend(surf_action_t action)
808 {
809   if(action->resource_type==(surf_resource_t)surf_network_resource) 
810     surf_network_resource->common_public->suspend(action);
811   else if(action->resource_type==(surf_resource_t)surf_cpu_resource) 
812     surf_cpu_resource->common_public->suspend(action);
813   else DIE_IMPOSSIBLE;
814 }
815
816 static void action_resume(surf_action_t action)
817 {
818   if(action->resource_type==(surf_resource_t)surf_network_resource)
819     surf_network_resource->common_public->resume(action);
820   else if(action->resource_type==(surf_resource_t)surf_cpu_resource)
821     surf_cpu_resource->common_public->resume(action);
822   else DIE_IMPOSSIBLE;
823 }
824
825 static int action_is_suspended(surf_action_t action)
826 {
827   if(action->resource_type==(surf_resource_t)surf_network_resource) 
828     return surf_network_resource->common_public->is_suspended(action);
829   if(action->resource_type==(surf_resource_t)surf_cpu_resource) 
830     return surf_cpu_resource->common_public->is_suspended(action);
831   DIE_IMPOSSIBLE;
832 }
833
834 static void action_set_max_duration(surf_action_t action, double duration)
835 {
836   if(action->resource_type==(surf_resource_t)surf_network_resource) 
837     surf_network_resource->common_public->set_max_duration(action,duration);
838   else if(action->resource_type==(surf_resource_t)surf_cpu_resource) 
839     surf_cpu_resource->common_public->set_max_duration(action,duration);
840   else DIE_IMPOSSIBLE;
841 }
842
843
844 /**************************************/
845 /********* Module  creation ***********/
846 /**************************************/
847 static void cpu_KCCFLN05_finalize(void)
848 {
849   xbt_dict_free(&workstation_set);
850   xbt_swag_free(surf_cpu_resource->common_public->states.ready_action_set);
851   xbt_swag_free(surf_cpu_resource->common_public->states.
852                 running_action_set);
853   xbt_swag_free(surf_cpu_resource->common_public->states.
854                 failed_action_set);
855   xbt_swag_free(surf_cpu_resource->common_public->states.done_action_set);
856   free(surf_cpu_resource->common_public);
857   free(surf_cpu_resource->common_private);
858   free(surf_cpu_resource->extension_public);
859
860   free(surf_cpu_resource);
861   surf_cpu_resource = NULL;
862
863   if (maxmin_system_cpu_KCCFLN05) {
864     lmm_system_free(maxmin_system_cpu_KCCFLN05);
865     maxmin_system_cpu_KCCFLN05 = NULL;
866   }
867 }
868
869 static void cpu_KCCFLN05_resource_init_internal(void)
870 {
871   s_surf_action_t action;
872
873   surf_cpu_resource = xbt_new0(s_surf_cpu_resource_t, 1);
874
875   surf_cpu_resource->common_private =
876       xbt_new0(s_surf_resource_private_t, 1);
877   surf_cpu_resource->common_public = 
878     xbt_new0(s_surf_resource_public_t, 1);
879
880   surf_cpu_resource->extension_public =
881       xbt_new0(s_surf_cpu_resource_extension_public_t, 1);
882
883   surf_cpu_resource->common_public->states.ready_action_set =
884       xbt_swag_new(xbt_swag_offset(action, state_hookup));
885   surf_cpu_resource->common_public->states.running_action_set =
886       xbt_swag_new(xbt_swag_offset(action, state_hookup));
887   surf_cpu_resource->common_public->states.failed_action_set =
888       xbt_swag_new(xbt_swag_offset(action, state_hookup));
889   surf_cpu_resource->common_public->states.done_action_set =
890       xbt_swag_new(xbt_swag_offset(action, state_hookup));
891
892   surf_cpu_resource->common_public->name_service = name_service;
893   surf_cpu_resource->common_public->get_resource_name = get_resource_name; 
894   surf_cpu_resource->common_public->action_get_state =
895       surf_action_get_state;
896   surf_cpu_resource->common_public->action_free = action_cpu_KCCFLN05_free;
897   surf_cpu_resource->common_public->action_use = action_cpu_KCCFLN05_use;
898   surf_cpu_resource->common_public->action_cancel = NULL;
899   surf_cpu_resource->common_public->action_recycle = NULL;
900   surf_cpu_resource->common_public->action_change_state = action_cpu_KCCFLN05_change_state;
901   surf_cpu_resource->common_public->action_set_data = surf_action_set_data;
902   surf_cpu_resource->common_public->name = "CPU KCCFLN05";
903
904   surf_cpu_resource->common_private->resource_used = cpu_used;
905   surf_cpu_resource->common_private->share_resources = share_cpu_KCCFLN05_resources;
906   surf_cpu_resource->common_private->update_actions_state =
907     update_actions_cpu_KCCFLN05_state;
908   surf_cpu_resource->common_private->update_resource_state =
909       update_cpu_KCCFLN05_state;
910   surf_cpu_resource->common_private->finalize = cpu_KCCFLN05_finalize;
911
912   surf_cpu_resource->extension_public->execute = execute_KCCFLN05;
913 /*FIXME*//*   surf_cpu_resource->extension_public->sleep = action_sleep; */
914
915   surf_cpu_resource->common_public->suspend = cpu_KCCFLN05_action_suspend;
916   surf_cpu_resource->common_public->resume = cpu_KCCFLN05_action_resume;
917   surf_cpu_resource->common_public->is_suspended = cpu_KCCFLN05_action_is_suspended;
918
919   surf_cpu_resource->extension_public->get_state = get_state;
920
921   workstation_set = xbt_dict_new();
922
923   maxmin_system_cpu_KCCFLN05 = lmm_system_new();
924 }
925
926 static void network_KCCFLN05_finalize(void)
927 {
928   int i,j;
929
930   xbt_dict_free(&network_link_set);
931   xbt_swag_free(surf_network_resource->common_public->states.
932                 ready_action_set);
933   xbt_swag_free(surf_network_resource->common_public->states.
934                 running_action_set);
935   xbt_swag_free(surf_network_resource->common_public->states.
936                 failed_action_set);
937   xbt_swag_free(surf_network_resource->common_public->states.
938                 done_action_set);
939   free(surf_network_resource->common_public);
940   free(surf_network_resource->common_private);
941   free(surf_network_resource->extension_public);
942
943   free(surf_network_resource);
944   surf_network_resource = NULL;
945
946   for (i = 0; i < nb_workstation; i++) 
947     for (j = 0; j < nb_workstation; j++) 
948       free(ROUTE(i,j).links);
949   free(routing_table);
950   routing_table = NULL;
951   nb_workstation = 0;
952
953   if (maxmin_system_network_KCCFLN05) {
954     lmm_system_free(maxmin_system_network_KCCFLN05);
955     maxmin_system_network_KCCFLN05 = NULL;
956   }
957 }
958
959 static void network_KCCFLN05_resource_init_internal(void)
960 {
961   s_surf_action_t action;
962
963   surf_network_resource = xbt_new0(s_surf_network_resource_t, 1);
964
965   surf_network_resource->common_private =
966       xbt_new0(s_surf_resource_private_t, 1);
967   surf_network_resource->common_public =
968       xbt_new0(s_surf_resource_public_t, 1);
969   surf_network_resource->extension_public =
970       xbt_new0(s_surf_network_resource_extension_public_t, 1);
971
972   surf_network_resource->common_public->states.ready_action_set =
973       xbt_swag_new(xbt_swag_offset(action, state_hookup));
974   surf_network_resource->common_public->states.running_action_set =
975       xbt_swag_new(xbt_swag_offset(action, state_hookup));
976   surf_network_resource->common_public->states.failed_action_set =
977       xbt_swag_new(xbt_swag_offset(action, state_hookup));
978   surf_network_resource->common_public->states.done_action_set =
979       xbt_swag_new(xbt_swag_offset(action, state_hookup));
980
981   surf_network_resource->common_public->name_service = name_service;
982   surf_network_resource->common_public->get_resource_name = get_resource_name;
983   surf_network_resource->common_public->action_get_state =
984       surf_action_get_state;
985   surf_network_resource->common_public->action_free = action_network_KCCFLN05_free;
986   surf_network_resource->common_public->action_use = action_network_KCCFLN05_use;
987   surf_network_resource->common_public->action_cancel = NULL;
988   surf_network_resource->common_public->action_recycle = NULL;
989   surf_network_resource->common_public->action_change_state = action_network_KCCFLN05_change_state;
990   surf_network_resource->common_public->action_set_data = surf_action_set_data;
991   surf_network_resource->common_public->name = "network KCCFLN05";
992
993   surf_network_resource->common_private->resource_used = link_used;
994   surf_network_resource->common_private->share_resources = share_network_KCCFLN05_resources;
995   surf_network_resource->common_private->update_actions_state =
996     update_actions_network_KCCFLN05_state;
997   surf_network_resource->common_private->update_resource_state =
998     update_network_KCCFLN05_state;
999   surf_network_resource->common_private->finalize = network_KCCFLN05_finalize;
1000
1001   surf_network_resource->common_public->suspend = network_KCCFLN05_action_suspend;
1002   surf_network_resource->common_public->resume = network_KCCFLN05_action_resume;
1003   surf_network_resource->common_public->is_suspended = network_KCCFLN05_action_is_suspended;
1004
1005   surf_network_resource->extension_public->communicate = communicate_KCCFLN05;
1006
1007   network_link_set = xbt_dict_new();
1008
1009   maxmin_system_network_KCCFLN05 = lmm_system_new();
1010 }
1011
1012 static void workstation_KCCFLN05_finalize(void)
1013 {
1014   xbt_swag_free(surf_workstation_resource->common_public->states.ready_action_set);
1015   xbt_swag_free(surf_workstation_resource->common_public->states.running_action_set);
1016   xbt_swag_free(surf_workstation_resource->common_public->states.failed_action_set);
1017   xbt_swag_free(surf_workstation_resource->common_public->states.done_action_set);
1018
1019   free(surf_workstation_resource->common_public);
1020   free(surf_workstation_resource->common_private);
1021   free(surf_workstation_resource->extension_public);
1022
1023   free(surf_workstation_resource);
1024   surf_workstation_resource = NULL;
1025 }
1026
1027 static void workstation_KCCFLN05_resource_init_internal(void)
1028 {
1029   s_surf_action_t action;
1030
1031   surf_workstation_resource = xbt_new0(s_surf_workstation_resource_t, 1);
1032
1033   surf_workstation_resource->common_private =
1034       xbt_new0(s_surf_resource_private_t, 1);
1035   surf_workstation_resource->common_public =
1036       xbt_new0(s_surf_resource_public_t, 1);
1037   surf_workstation_resource->extension_public =
1038       xbt_new0(s_surf_workstation_resource_extension_public_t, 1);
1039
1040   surf_workstation_resource->common_public->states.ready_action_set =
1041       xbt_swag_new(xbt_swag_offset(action, state_hookup));
1042   surf_workstation_resource->common_public->states.running_action_set =
1043       xbt_swag_new(xbt_swag_offset(action, state_hookup));
1044   surf_workstation_resource->common_public->states.failed_action_set =
1045       xbt_swag_new(xbt_swag_offset(action, state_hookup));
1046   surf_workstation_resource->common_public->states.done_action_set =
1047       xbt_swag_new(xbt_swag_offset(action, state_hookup));
1048
1049   surf_workstation_resource->common_public->name_service = name_service;
1050   surf_workstation_resource->common_public->get_resource_name =
1051       get_resource_name;
1052   surf_workstation_resource->common_public->action_get_state =
1053       surf_action_get_state;
1054   surf_workstation_resource->common_public->action_free = action_free;
1055   surf_workstation_resource->common_public->action_use = action_use;
1056   surf_workstation_resource->common_public->action_cancel = NULL;
1057   surf_workstation_resource->common_public->action_recycle = NULL;
1058   surf_workstation_resource->common_public->action_change_state = action_change_state;
1059   surf_workstation_resource->common_public->action_set_data = surf_action_set_data;
1060   surf_workstation_resource->common_public->name = "Workstation KCCFLN05";
1061
1062   surf_workstation_resource->common_private->resource_used = resource_used;
1063   surf_workstation_resource->common_private->share_resources = share_resources;
1064   surf_workstation_resource->common_private->update_actions_state = update_actions_state;
1065   surf_workstation_resource->common_private->update_resource_state = update_resource_state;
1066   surf_workstation_resource->common_private->finalize = workstation_KCCFLN05_finalize;
1067
1068
1069   surf_workstation_resource->common_public->suspend = action_suspend;
1070   surf_workstation_resource->common_public->resume = action_resume;
1071   surf_workstation_resource->common_public->is_suspended = action_is_suspended;
1072   surf_workstation_resource->common_public->set_max_duration = action_set_max_duration;
1073
1074   surf_workstation_resource->extension_public->execute = execute_KCCFLN05;
1075 /*FIXME*//*  surf_workstation_resource->extension_public->sleep = action_sleep; */
1076   surf_workstation_resource->extension_public->get_state = get_state;
1077   surf_workstation_resource->extension_public->communicate = communicate_KCCFLN05;
1078   surf_workstation_resource->extension_public->execute_parallel_task = 
1079     execute_parallel_task_KCCFLN05;
1080
1081 }
1082
1083 /**************************************/
1084 /*************** Generic **************/
1085 /**************************************/
1086
1087 void surf_workstation_resource_init_KCCFLN05(const char *filename)
1088 {
1089   xbt_assert0(!surf_cpu_resource,"CPU resource type already defined");
1090   cpu_KCCFLN05_resource_init_internal();
1091   xbt_assert0(!surf_network_resource,"network resource type already defined");
1092   network_KCCFLN05_resource_init_internal();
1093   workstation_KCCFLN05_resource_init_internal();
1094   parse_file(filename);
1095
1096   xbt_dynar_push(resource_list, &surf_network_resource);
1097   xbt_dynar_push(resource_list, &surf_cpu_resource);
1098   xbt_dynar_push(resource_list, &surf_workstation_resource);
1099
1100   if (maxmin_system) { /* To avoid using this useless system */
1101     lmm_system_free(maxmin_system);
1102     maxmin_system = NULL;
1103   }
1104 }