Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
further parser cleanups
[simgrid.git] / src / surf / cpu_im.c
1 /* Copyright (c) 2009, 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "surf_private.h"
8
9 #undef GENERIC_LMM_ACTION
10 #undef GENERIC_ACTION
11 #undef ACTION_GET_CPU
12 #define GENERIC_LMM_ACTION(action) action->generic_lmm_action
13 #define GENERIC_ACTION(action) GENERIC_LMM_ACTION(action).generic_action
14 #define ACTION_GET_CPU(action) ((surf_action_cpu_Cas01_im_t) action)->cpu
15
16 typedef struct surf_action_cpu_cas01_im {
17   s_surf_action_lmm_t generic_lmm_action;
18   s_xbt_swag_hookup_t cpu_list_hookup;
19   int index_heap;
20   void *cpu;
21 } s_surf_action_cpu_Cas01_im_t, *surf_action_cpu_Cas01_im_t;
22
23 typedef struct cpu_Cas01_im {
24   s_surf_resource_t generic_resource;
25   s_xbt_swag_hookup_t modified_cpu_hookup;
26   double power_peak;
27   double power_scale;
28   tmgr_trace_event_t power_event;
29   int core;
30   e_surf_resource_state_t state_current;
31   tmgr_trace_event_t state_event;
32   lmm_constraint_t constraint;
33   xbt_swag_t action_set;
34   double last_update;
35 } s_cpu_Cas01_im_t, *cpu_Cas01_im_t;
36
37 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_im, surf,
38                                 "Logging specific to the SURF CPU IMPROVED module");
39
40
41 lmm_system_t cpu_im_maxmin_system = NULL;
42 static xbt_swag_t cpu_im_modified_cpu = NULL;
43 static xbt_heap_t cpu_im_action_heap = NULL;
44 extern int sg_maxmin_selective_update;
45
46
47 static xbt_swag_t
48     cpu_im_running_action_set_that_does_not_need_being_checked = NULL;
49
50 static void* cpu_im_create_resource(const char *name, double power_peak,
51                                  double power_scale,
52                                  tmgr_trace_t power_trace,
53                                  int core,
54                                  e_surf_resource_state_t state_initial,
55                                  tmgr_trace_t state_trace,
56                                  xbt_dict_t cpu_properties)
57 {
58   cpu_Cas01_im_t cpu = NULL;
59   s_surf_action_cpu_Cas01_im_t action;
60
61   xbt_assert(!surf_cpu_resource_by_name(name),
62               "Host '%s' declared several times in the platform file",
63               name);
64   cpu = (cpu_Cas01_im_t) surf_resource_new(sizeof(s_cpu_Cas01_im_t),
65           surf_cpu_model, name,cpu_properties);
66   cpu->power_peak = power_peak;
67   xbt_assert(cpu->power_peak > 0, "Power has to be >0");
68   cpu->power_scale = power_scale;
69   if (power_trace)
70     cpu->power_event =
71         tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
72   cpu->core = core;
73   xbt_assert(core>0,"Invalid number of cores %d",core);
74
75   cpu->state_current = state_initial;
76   if (state_trace)
77     cpu->state_event =
78         tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
79
80   cpu->constraint =
81       lmm_constraint_new(cpu_im_maxmin_system, cpu,
82                          cpu->core * cpu->power_scale * cpu->power_peak);
83
84   xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, cpu);
85   cpu->action_set = xbt_swag_new(xbt_swag_offset(action, cpu_list_hookup));
86
87   return cpu;
88 }
89
90
91 static void parse_cpu_im_init(sg_platf_host_cbarg_t host)
92 {
93         cpu_im_create_resource(host->V_host_id,
94                           host->V_host_power_peak,
95                           host->V_host_power_scale,
96                           host->V_host_power_trace,
97                           host->V_host_core,
98                           host->V_host_state_initial,
99                           host->V_host_state_trace,
100                           host->properties);
101 }
102
103 static void cpu_im_add_traces_cpu(void)
104 {
105   xbt_dict_cursor_t cursor = NULL;
106   char *trace_name, *elm;
107   static int called = 0;
108   if (called)
109     return;
110   called = 1;
111
112   /* connect all traces relative to hosts */
113   xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
114     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
115     cpu_Cas01_im_t host = surf_cpu_resource_by_name(elm);
116
117     xbt_assert(host, "Host %s undefined", elm);
118     xbt_assert(trace, "Trace %s undefined", trace_name);
119
120     host->state_event =
121         tmgr_history_add_trace(history, trace, 0.0, 0, host);
122   }
123
124   xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
125     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
126     cpu_Cas01_im_t host = surf_cpu_resource_by_name(elm);
127
128     xbt_assert(host, "Host %s undefined", elm);
129     xbt_assert(trace, "Trace %s undefined", trace_name);
130
131     host->power_event =
132         tmgr_history_add_trace(history, trace, 0.0, 0, host);
133   }
134 }
135
136 static void cpu_im_define_callbacks()
137 {
138   sg_platf_host_add_cb(parse_cpu_im_init);
139   sg_platf_postparse_add_cb(cpu_im_add_traces_cpu);
140 }
141
142 static int cpu_im_resource_used(void *resource)
143 {
144   return lmm_constraint_used(cpu_im_maxmin_system,
145                              ((cpu_Cas01_im_t) resource)->constraint);
146 }
147
148 static int cpu_im_action_unref(surf_action_t action)
149 {
150   action->refcount--;
151   if (!action->refcount) {
152     xbt_swag_remove(action, action->state_set);
153     if (((surf_action_lmm_t) action)->variable)
154       lmm_variable_free(cpu_im_maxmin_system,
155                         ((surf_action_lmm_t) action)->variable);
156     /* remove from heap */
157     xbt_heap_remove(cpu_im_action_heap,
158                     ((surf_action_cpu_Cas01_im_t) action)->index_heap);
159     xbt_swag_remove(action,
160                     ((cpu_Cas01_im_t) ACTION_GET_CPU(action))->action_set);
161     xbt_swag_insert(ACTION_GET_CPU(action), cpu_im_modified_cpu);
162 #ifdef HAVE_TRACING
163     if (action->category)
164       xbt_free(action->category);
165 #endif
166     surf_action_free(&action);
167     return 1;
168   }
169   return 0;
170 }
171
172 static void cpu_im_action_cancel(surf_action_t action)
173 {
174   surf_action_state_set(action, SURF_ACTION_FAILED);
175   xbt_heap_remove(cpu_im_action_heap,
176                   ((surf_action_cpu_Cas01_im_t) action)->index_heap);
177   xbt_swag_remove(action,
178                   ((cpu_Cas01_im_t) ACTION_GET_CPU(action))->action_set);
179   return;
180 }
181
182 static void cpu_im_cpu_action_state_set(surf_action_t action,
183                                         e_surf_action_state_t state)
184 {
185 /*   if((state==SURF_ACTION_DONE) || (state==SURF_ACTION_FAILED)) */
186 /*     if(((surf_action_lmm_t)action)->variable) { */
187 /*       lmm_variable_disable(cpu_im_maxmin_system, ((surf_action_lmm_t)action)->variable); */
188 /*       ((surf_action_lmm_t)action)->variable = NULL; */
189 /*     } */
190
191   surf_action_state_set(action, state);
192   return;
193 }
194
195 static void cpu_im_update_remains(cpu_Cas01_im_t cpu, double now)
196 {
197   surf_action_cpu_Cas01_im_t action;
198
199   if (cpu->last_update >= now)
200     return;
201   xbt_swag_foreach(action, cpu->action_set) {
202     if (GENERIC_ACTION(action).state_set !=
203         surf_cpu_model->states.running_action_set)
204       continue;
205
206     /* bogus priority, skip it */
207     if (GENERIC_ACTION(action).priority <= 0)
208       continue;
209
210     if (GENERIC_ACTION(action).remains > 0) {
211       double_update(&(GENERIC_ACTION(action).remains),
212                     lmm_variable_getvalue(GENERIC_LMM_ACTION
213                                           (action).variable) * (now -
214                                                                 cpu->last_update));
215 #ifdef HAVE_TRACING
216       if (TRACE_is_enabled()) {
217         TRACE_surf_host_set_utilization(cpu->generic_resource.name,
218                                         action->
219                                         generic_lmm_action.generic_action.
220                                         data, (surf_action_t) action,
221                                         lmm_variable_getvalue
222                                         (GENERIC_LMM_ACTION
223                                          (action).variable),
224                                         cpu->last_update,
225                                         now - cpu->last_update);
226       }
227 #endif
228       XBT_DEBUG("Update action(%p) remains %lf", action,
229              GENERIC_ACTION(action).remains);
230     }
231   }
232   cpu->last_update = now;
233 }
234
235 static double cpu_im_share_resources(double now)
236 {
237   surf_action_cpu_Cas01_im_t action;
238   double min;
239   double value;
240   cpu_Cas01_im_t cpu, cpu_next;
241
242   xbt_swag_foreach(cpu, cpu_im_modified_cpu)
243       cpu_im_update_remains(cpu, now);
244
245   lmm_solve(cpu_im_maxmin_system);
246
247   xbt_swag_foreach_safe(cpu, cpu_next, cpu_im_modified_cpu) {
248     xbt_swag_foreach(action, cpu->action_set) {
249       if (GENERIC_ACTION(action).state_set !=
250           surf_cpu_model->states.running_action_set)
251         continue;
252
253       /* bogus priority, skip it */
254       if (GENERIC_ACTION(action).priority <= 0)
255         continue;
256
257       min = -1;
258       value = lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable);
259       if (value > 0) {
260         if (GENERIC_ACTION(action).remains > 0) {
261           value = GENERIC_ACTION(action).remains / value;
262           min = now + value;
263         } else {
264           value = 0.0;
265           min = now;
266         }
267       }
268
269       if ((GENERIC_ACTION(action).max_duration != NO_MAX_DURATION)
270           && (min == -1
271               || GENERIC_ACTION(action).start +
272               GENERIC_ACTION(action).max_duration < min))
273         min =
274             GENERIC_ACTION(action).start +
275             GENERIC_ACTION(action).max_duration;
276
277       XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
278              GENERIC_ACTION(action).start, now + value,
279              GENERIC_ACTION(action).max_duration);
280
281       if (action->index_heap >= 0) {
282         surf_action_cpu_Cas01_im_t heap_act =
283             xbt_heap_remove(cpu_im_action_heap, action->index_heap);
284         if (heap_act != action)
285           DIE_IMPOSSIBLE;
286       }
287       if (min != -1) {
288         xbt_heap_push(cpu_im_action_heap, action, min);
289         XBT_DEBUG("Insert at heap action(%p) min %lf", action, min);
290       }
291     }
292     xbt_swag_remove(cpu, cpu_im_modified_cpu);
293   }
294   return xbt_heap_size(cpu_im_action_heap) >
295       0 ? xbt_heap_maxkey(cpu_im_action_heap) - now : -1;
296 }
297
298 static void cpu_im_update_actions_state(double now, double delta)
299 {
300   surf_action_cpu_Cas01_im_t action;
301
302   while ((xbt_heap_size(cpu_im_action_heap) > 0)
303          && (double_equals(xbt_heap_maxkey(cpu_im_action_heap), now))) {
304     action = xbt_heap_pop(cpu_im_action_heap);
305     XBT_DEBUG("Action %p: finish", action);
306     GENERIC_ACTION(action).finish = surf_get_clock();
307     /* set the remains to 0 due to precision problems when updating the remaining amount */
308 #ifdef HAVE_TRACING
309     if (TRACE_is_enabled()) {
310       cpu_Cas01_im_t cpu = ((cpu_Cas01_im_t)(action->cpu));
311       TRACE_surf_host_set_utilization(cpu->generic_resource.name,
312           action->generic_lmm_action.generic_action.data,
313           (surf_action_t) action,
314           lmm_variable_getvalue (GENERIC_LMM_ACTION(action).variable),
315           cpu->last_update,
316           now - cpu->last_update);
317     }
318 #endif
319     GENERIC_ACTION(action).remains = 0;
320     cpu_im_cpu_action_state_set((surf_action_t) action, SURF_ACTION_DONE);
321     cpu_im_update_remains(action->cpu, surf_get_clock());
322   }
323 #ifdef HAVE_TRACING
324   if (TRACE_is_enabled()) {
325     //defining the last timestamp that we can safely dump to trace file
326     //without losing the event ascending order (considering all CPU's)
327     void **data;
328     cpu_Cas01_im_t cpu;
329     xbt_lib_cursor_t cursor;
330     char *key;
331     double smaller = -1;
332     xbt_lib_foreach(host_lib, cursor, key, data){
333       if(data[SURF_CPU_LEVEL]){
334         cpu = data[SURF_CPU_LEVEL];
335         if (smaller < 0){
336           smaller = cpu->last_update;
337           continue;
338         }
339         if (cpu->last_update < smaller){
340           smaller = cpu->last_update;
341         }
342       }
343     }
344     if (smaller > 0) {
345       TRACE_last_timestamp_to_dump = smaller;
346     }
347   }
348 #endif
349   return;
350 }
351
352 static void cpu_im_update_resource_state(void *id,
353                                          tmgr_trace_event_t event_type,
354                                          double value, double date)
355 {
356   cpu_Cas01_im_t cpu = id;
357   lmm_variable_t var = NULL;
358   lmm_element_t elem = NULL;
359
360   if (event_type == cpu->power_event) {
361     cpu->power_scale = value;
362     lmm_update_constraint_bound(cpu_im_maxmin_system, cpu->constraint,
363                                 cpu->core * cpu->power_scale * cpu->power_peak);
364 #ifdef HAVE_TRACING
365     TRACE_surf_host_set_power(date, cpu->generic_resource.name,
366                               cpu->core * cpu->power_scale * cpu->power_peak);
367 #endif
368     while ((var = lmm_get_var_from_cnst
369             (cpu_im_maxmin_system, cpu->constraint, &elem))) {
370         surf_action_cpu_Cas01_im_t action = lmm_variable_id(var);
371         lmm_update_variable_bound(cpu_im_maxmin_system, action->generic_lmm_action.variable,
372                                   cpu->power_scale * cpu->power_peak);
373     }
374     xbt_swag_insert(cpu, cpu_im_modified_cpu);
375     if (tmgr_trace_event_free(event_type))
376       cpu->power_event = NULL;
377   } else if (event_type == cpu->state_event) {
378     if (value > 0)
379       cpu->state_current = SURF_RESOURCE_ON;
380     else {
381       lmm_constraint_t cnst = cpu->constraint;
382       lmm_variable_t var = NULL;
383       lmm_element_t elem = NULL;
384
385       cpu->state_current = SURF_RESOURCE_OFF;
386
387       while ((var =
388               lmm_get_var_from_cnst(cpu_im_maxmin_system, cnst, &elem))) {
389         surf_action_t action = lmm_variable_id(var);
390
391         if (surf_action_state_get(action) == SURF_ACTION_RUNNING ||
392             surf_action_state_get(action) == SURF_ACTION_READY ||
393             surf_action_state_get(action) ==
394             SURF_ACTION_NOT_IN_THE_SYSTEM) {
395           action->finish = date;
396           cpu_im_cpu_action_state_set(action, SURF_ACTION_FAILED);
397         }
398       }
399     }
400     if (tmgr_trace_event_free(event_type))
401       cpu->state_event = NULL;
402   } else {
403     XBT_CRITICAL("Unknown event ! \n");
404     xbt_abort();
405   }
406
407   return;
408 }
409
410 static surf_action_t cpu_im_execute(void *cpu, double size)
411 {
412   surf_action_cpu_Cas01_im_t action = NULL;
413   cpu_Cas01_im_t CPU = cpu;
414
415   XBT_IN("(%s,%g)", surf_resource_name(CPU), size);
416   action =
417       surf_action_new(sizeof(s_surf_action_cpu_Cas01_im_t), size,
418                       surf_cpu_model,
419                       CPU->state_current != SURF_RESOURCE_ON);
420
421   GENERIC_LMM_ACTION(action).suspended = 0;     /* Should be useless because of the
422                                                    calloc but it seems to help valgrind... */
423
424   GENERIC_LMM_ACTION(action).variable =
425       lmm_variable_new(cpu_im_maxmin_system, action,
426                        GENERIC_ACTION(action).priority, CPU->power_scale * CPU->power_peak, 1);
427   action->index_heap = -1;
428   action->cpu = CPU;
429   xbt_swag_insert(CPU, cpu_im_modified_cpu);
430   xbt_swag_insert(action, CPU->action_set);
431   lmm_expand(cpu_im_maxmin_system, CPU->constraint,
432              GENERIC_LMM_ACTION(action).variable, 1.0);
433   XBT_OUT();
434   return (surf_action_t) action;
435 }
436
437 static surf_action_t cpu_im_action_sleep(void *cpu, double duration)
438 {
439   surf_action_cpu_Cas01_im_t action = NULL;
440
441   if (duration > 0)
442     duration = MAX(duration, MAXMIN_PRECISION);
443
444   XBT_IN("(%s,%g)", surf_resource_name(cpu), duration);
445   action = (surf_action_cpu_Cas01_im_t) cpu_im_execute(cpu, 1.0);
446   GENERIC_ACTION(action).max_duration = duration;
447   GENERIC_LMM_ACTION(action).suspended = 2;
448   if (duration == NO_MAX_DURATION) {
449     /* Move to the *end* of the corresponding action set. This convention
450        is used to speed up update_resource_state  */
451     xbt_swag_remove(action, ((surf_action_t) action)->state_set);
452     ((surf_action_t) action)->state_set =
453         cpu_im_running_action_set_that_does_not_need_being_checked;
454     xbt_swag_insert(action, ((surf_action_t) action)->state_set);
455   }
456
457   lmm_update_variable_weight(cpu_im_maxmin_system,
458                              GENERIC_LMM_ACTION(action).variable, 0.0);
459   xbt_swag_insert(cpu, cpu_im_modified_cpu);
460   XBT_OUT();
461   return (surf_action_t) action;
462 }
463
464 static void cpu_im_action_suspend(surf_action_t action)
465 {
466   XBT_IN("(%p)", action);
467   if (((surf_action_lmm_t) action)->suspended != 2) {
468     lmm_update_variable_weight(cpu_im_maxmin_system,
469                                ((surf_action_lmm_t) action)->variable,
470                                0.0);
471     ((surf_action_lmm_t) action)->suspended = 1;
472     xbt_heap_remove(cpu_im_action_heap,
473                     ((surf_action_cpu_Cas01_im_t) action)->index_heap);
474     xbt_swag_insert(ACTION_GET_CPU(action), cpu_im_modified_cpu);
475   }
476   XBT_OUT();
477 }
478
479 static void cpu_im_action_resume(surf_action_t action)
480 {
481
482   XBT_IN("(%p)", action);
483   if (((surf_action_lmm_t) action)->suspended != 2) {
484     lmm_update_variable_weight(cpu_im_maxmin_system,
485                                ((surf_action_lmm_t) action)->variable,
486                                action->priority);
487     ((surf_action_lmm_t) action)->suspended = 0;
488     xbt_swag_insert(ACTION_GET_CPU(action), cpu_im_modified_cpu);
489   }
490   XBT_OUT();
491 }
492
493 static int cpu_im_action_is_suspended(surf_action_t action)
494 {
495   return (((surf_action_lmm_t) action)->suspended == 1);
496 }
497
498 static void cpu_im_action_set_max_duration(surf_action_t action,
499                                            double duration)
500 {
501   XBT_IN("(%p,%g)", action, duration);
502
503   action->max_duration = duration;
504   /* insert cpu in modified_cpu set to notice the max duration change */
505   xbt_swag_insert(ACTION_GET_CPU(action), cpu_im_modified_cpu);
506   XBT_OUT();
507 }
508
509 static void cpu_im_action_set_priority(surf_action_t action,
510                                        double priority)
511 {
512   XBT_IN("(%p,%g)", action, priority);
513   action->priority = priority;
514   lmm_update_variable_weight(cpu_im_maxmin_system,
515                              ((surf_action_lmm_t) action)->variable,
516                              priority);
517
518   xbt_swag_insert(ACTION_GET_CPU(action), cpu_im_modified_cpu);
519   XBT_OUT();
520 }
521
522 #ifdef HAVE_TRACING
523 static void cpu_im_action_set_category(surf_action_t action,
524                                        const char *category)
525 {
526   XBT_IN("(%p,%s)", action, category);
527   action->category = xbt_strdup (category);
528   XBT_OUT();
529 }
530 #endif
531
532 static double cpu_im_action_get_remains(surf_action_t action)
533 {
534   XBT_IN("(%p)", action);
535   /* update remains before return it */
536   cpu_im_update_remains(ACTION_GET_CPU(action), surf_get_clock());
537   return action->remains;
538   XBT_OUT();
539 }
540
541 static e_surf_resource_state_t cpu_im_get_state(void *cpu)
542 {
543   return ((cpu_Cas01_im_t) cpu)->state_current;
544 }
545
546 static double cpu_im_get_speed(void *cpu, double load)
547 {
548   return load * (((cpu_Cas01_im_t) cpu)->power_peak);
549 }
550
551 static double cpu_im_get_available_speed(void *cpu)
552 {
553   /* number between 0 and 1 */
554   return ((cpu_Cas01_im_t) cpu)->power_scale;
555 }
556
557 static void cpu_im_action_update_index_heap(void *action, int i)
558 {
559   ((surf_action_cpu_Cas01_im_t) action)->index_heap = i;
560 }
561
562 static void cpu_im_finalize(void)
563 {
564   void **cpu;
565   xbt_lib_cursor_t cursor;
566   char *key;
567
568   xbt_lib_foreach(host_lib, cursor, key, cpu){
569           if(cpu[SURF_CPU_LEVEL])
570           {
571                     cpu_Cas01_im_t CPU = cpu[SURF_CPU_LEVEL];
572                     xbt_swag_free(CPU->action_set);
573           }
574   }
575
576   lmm_system_free(cpu_im_maxmin_system);
577   cpu_im_maxmin_system = NULL;
578
579   surf_model_exit(surf_cpu_model);
580   surf_cpu_model = NULL;
581
582   xbt_swag_free
583       (cpu_im_running_action_set_that_does_not_need_being_checked);
584   cpu_im_running_action_set_that_does_not_need_being_checked = NULL;
585   xbt_heap_free(cpu_im_action_heap);
586   xbt_swag_free(cpu_im_modified_cpu);
587 }
588
589 static void surf_cpu_im_model_init_internal(void)
590 {
591   s_surf_action_t action;
592   s_cpu_Cas01_im_t cpu;
593
594   surf_cpu_model = surf_model_init();
595
596   cpu_im_running_action_set_that_does_not_need_being_checked =
597       xbt_swag_new(xbt_swag_offset(action, state_hookup));
598
599   surf_cpu_model->name = "CPU_IM";
600
601   surf_cpu_model->action_unref = cpu_im_action_unref;
602   surf_cpu_model->action_cancel = cpu_im_action_cancel;
603   surf_cpu_model->action_state_set = cpu_im_cpu_action_state_set;
604
605   surf_cpu_model->model_private->resource_used = cpu_im_resource_used;
606   surf_cpu_model->model_private->share_resources = cpu_im_share_resources;
607   surf_cpu_model->model_private->update_actions_state =
608       cpu_im_update_actions_state;
609   surf_cpu_model->model_private->update_resource_state =
610       cpu_im_update_resource_state;
611   surf_cpu_model->model_private->finalize = cpu_im_finalize;
612
613   surf_cpu_model->suspend = cpu_im_action_suspend;
614   surf_cpu_model->resume = cpu_im_action_resume;
615   surf_cpu_model->is_suspended = cpu_im_action_is_suspended;
616   surf_cpu_model->set_max_duration = cpu_im_action_set_max_duration;
617   surf_cpu_model->set_priority = cpu_im_action_set_priority;
618 #ifdef HAVE_TRACING
619   surf_cpu_model->set_category = cpu_im_action_set_category;
620 #endif
621   surf_cpu_model->get_remains = cpu_im_action_get_remains;
622
623   surf_cpu_model->extension.cpu.execute = cpu_im_execute;
624   surf_cpu_model->extension.cpu.sleep = cpu_im_action_sleep;
625
626   surf_cpu_model->extension.cpu.get_state = cpu_im_get_state;
627   surf_cpu_model->extension.cpu.get_speed = cpu_im_get_speed;
628   surf_cpu_model->extension.cpu.get_available_speed =
629       cpu_im_get_available_speed;
630   surf_cpu_model->extension.cpu.create_resource = cpu_im_create_resource;
631   surf_cpu_model->extension.cpu.add_traces = cpu_im_add_traces_cpu;
632
633   if (!cpu_im_maxmin_system) {
634     sg_maxmin_selective_update = 1;
635     cpu_im_maxmin_system = lmm_system_new();
636   }
637   cpu_im_action_heap = xbt_heap_new(8, NULL);
638   xbt_heap_set_update_callback(cpu_im_action_heap,
639                                cpu_im_action_update_index_heap);
640   cpu_im_modified_cpu =
641       xbt_swag_new(xbt_swag_offset(cpu, modified_cpu_hookup));
642 }
643
644 /*********************************************************************/
645 /* Basic sharing model for CPU: that is where all this started... ;) */
646 /*********************************************************************/
647 /* @InProceedings{casanova01simgrid, */
648 /*   author =       "H. Casanova", */
649 /*   booktitle =    "Proceedings of the IEEE Symposium on Cluster Computing */
650 /*                  and the Grid (CCGrid'01)", */
651 /*   publisher =    "IEEE Computer Society", */
652 /*   title =        "Simgrid: {A} Toolkit for the Simulation of Application */
653 /*                  Scheduling", */
654 /*   year =         "2001", */
655 /*   month =        may, */
656 /*   note =         "Available at */
657 /*                  \url{http://grail.sdsc.edu/papers/simgrid_ccgrid01.ps.gz}." */
658 /* } */
659 void surf_cpu_model_init_Cas01_im()
660 {
661   if (surf_cpu_model)
662     return;
663   surf_cpu_im_model_init_internal();
664   cpu_im_define_callbacks();
665   xbt_dynar_push(model_list, &surf_cpu_model);
666 }