Logo AND Algorithmique Numérique Distribuée

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