Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
remove a nasty iteration causing big slow down
[simgrid.git] / src / surf / workstation.c
1 /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 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 "xbt/ex.h"
8 #include "xbt/dict.h"
9 #include "portable.h"
10 #include "surf_private.h"
11 #include "storage_private.h"
12 #include "surf/surf_resource.h"
13 #include "simgrid/sg_config.h"
14 #include "workstation_private.h"
15 #include "vm_workstation_private.h"
16 #include "cpu_cas01_private.h"
17 #include "maxmin_private.h"
18
19 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf,
20                                 "Logging specific to the SURF workstation module");
21
22 surf_model_t surf_workstation_model = NULL;
23
24
25 static void workstation_new(sg_platf_host_cbarg_t host)
26 {
27   const char *name = host->id;
28
29   /* NOTE: The properties object is NULL, because the current code uses that of
30    * that of a cpu resource. */
31   workstation_CLM03_t ws = (workstation_CLM03_t) surf_resource_new(sizeof(s_workstation_CLM03_t), surf_workstation_model, name, NULL);
32
33   ws->storage = xbt_lib_get_or_null(storage_lib, name, ROUTING_STORAGE_HOST_LEVEL);
34   ws->net_elm = xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
35
36   XBT_DEBUG("Create ws %s with %ld mounted disks", name, xbt_dynar_length(ws->storage));
37   xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, ws);
38 }
39
40 static void ws_parallel_action_cancel(surf_action_t action)
41 {
42   THROW_UNIMPLEMENTED;          /* This model does not implement parallel tasks */
43 }
44
45 static int ws_parallel_action_free(surf_action_t action)
46 {
47   THROW_UNIMPLEMENTED;          /* This model does not implement parallel tasks */
48   return -1;
49 }
50
51 int ws_action_unref(surf_action_t action)
52 {
53   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
54     return surf_network_model->action_unref(action);
55   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
56     return action->model_obj->action_unref(action);
57       // previously was: Adrien/Arnaud 6 feb
58           // surf_cpu_model->action_unref(action);
59   else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
60     return ws_parallel_action_free(action);
61   else
62     DIE_IMPOSSIBLE;
63   return 0;
64 }
65
66 void ws_action_cancel(surf_action_t action)
67 {
68   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
69     surf_network_model->action_cancel(action);
70   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
71     action->model_obj->action_cancel(action);
72   else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
73     ws_parallel_action_cancel(action);
74   else
75     DIE_IMPOSSIBLE;
76   return;
77 }
78
79 static void ws_action_state_set(surf_action_t action,
80                                 e_surf_action_state_t state)
81 {
82   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
83     surf_network_model->action_state_set(action, state);
84   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
85     action->model_obj->action_state_set(action, state);
86   else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
87     surf_action_state_set(action, state);
88   else
89     DIE_IMPOSSIBLE;
90   return;
91 }
92
93
94 /* -- The callback functions at model_private -- */
95 /* These callbacks are also used for the vm workstation model. */
96 int ws_resource_used(void *resource_id)
97 {
98   /* This model does not implement parallel tasks */
99   THROW_IMPOSSIBLE;
100   return -1;
101 }
102
103
104 /* TODO: iterating active constraint_set may be faster? */
105 #if 0
106 static void deactivate_dummy_cpu_action(void)
107 {
108   lmm_system_t sys = surf_cpu_model_vm->model_private->maxmin_system;
109
110   lmm_constraint_t cnst;
111   xbt_swag_foreach(cnst, &sys->active_constraint_set) {
112     /* get vcpu resource */
113     surf_resource_t cpu = lmm_constraint_id(cnst);
114     xbt_assert(cpu->model == surf_cpu_model_vm);
115
116     /* get vm_ws resource */
117     workstation_CLM03_t ws = xbt_lib_get_or_null(host_lib, cpu->name, SURF_WKS_LEVEL);
118
119     /* make sure we can cast */
120     xbt_assert(ws->generic_resouce.model == surf_vm_workstation_model);
121     workstation_VM2013_t vm_ws = (workstation_VM2013_t) ws;
122
123     /* make it active in the PM layer */
124     surf_action_set_priority(vm_ws->cpu_action, 1);
125   }
126 }
127 #endif
128
129
130 /* TODO: Delete this unused code if everything looks good. */
131 #if 0
132 static int constraint_is_active(cpu_Cas01_t cpu_cas01)
133 {
134   surf_model_t cpu_model = cpu_cas01->generic_resource.model;
135   lmm_system_t sys = cpu_model->model_private->maxmin_system;
136   int found = 0;
137   lmm_constraint_t cnst_tmp;
138
139   xbt_swag_foreach(cnst_tmp, &sys->active_constraint_set) {
140     if (cnst_tmp == cpu_cas01->constraint) {
141       found = 1;
142       break;
143     }
144   }
145
146   return found;
147 }
148 #endif
149
150
151 /* Each VM has a dummy CPU action on the PM layer. This CPU action works as the
152  * constraint (capacity) of the VM in the PM layer. If the VM does not have any
153  * active task, the dummy CPU action must be deactivated, so that the VM does
154  * not get any CPU share in the PM layer. */
155 static void adjust_weight_of_dummy_cpu_actions(void)
156 {
157   /* iterate for all hosts including virtual machines */
158   xbt_lib_cursor_t cursor;
159   char *key;
160   void **ind_host;
161
162   xbt_lib_foreach(host_lib, cursor, key, ind_host) {
163     workstation_CLM03_t ws_clm03 = ind_host[SURF_WKS_LEVEL];
164     cpu_Cas01_t cpu_cas01 = ind_host[SURF_CPU_LEVEL];
165
166     if (!ws_clm03)
167       continue;
168     /* skip if it is not a virtual machine */
169     if (ws_clm03->generic_resource.model != surf_vm_workstation_model)
170       continue;
171     xbt_assert(cpu_cas01, "cpu-less workstation");
172
173     /* It is a virtual machine, so we can cast it to workstation_VM2013_t */
174     workstation_VM2013_t ws_vm2013 = (workstation_VM2013_t) ws_clm03;
175
176     lmm_system_t sys = surf_cpu_model_vm->model_private->maxmin_system;
177     int is_active = lmm_constraint_used(sys, cpu_cas01->constraint);
178     // int is_active_old = constraint_is_active(cpu_cas01);
179
180     // {
181     //   xbt_assert(is_active == is_active_old, "%d %d", is_active, is_active_old);
182     // }
183
184     if (is_active) {
185       /* some tasks exist on this VM */
186       XBT_DEBUG("set the weight of the dummy CPU action on PM to 1");
187
188       /* FIXME: we shoud use lmm_update_variable_weight() ? */
189       /* FIXME: If we assgign 1.05 and 0.05, the system makes apparently wrong values. */
190       surf_action_set_priority(ws_vm2013->cpu_action, 1);
191
192     } else {
193       /* no task exits on this VM */
194       XBT_DEBUG("set the weight of the dummy CPU action on PM to 0");
195
196       surf_action_set_priority(ws_vm2013->cpu_action, 0);
197     }
198   }
199 }
200
201
202 double ws_share_resources(surf_model_t workstation_model, double now)
203 {
204   if (workstation_model->type == SURF_MODEL_TYPE_WORKSTATION)
205     adjust_weight_of_dummy_cpu_actions();
206
207   /* Invoke the share_resources() callback of the physical cpu model object and
208    * the network model objects. */
209   surf_model_t cpu_model = workstation_model->extension.workstation.cpu_model;
210   surf_model_t net_model = surf_network_model;
211
212   double min_by_cpu = cpu_model->model_private->share_resources(cpu_model, now);
213   double min_by_net = net_model->model_private->share_resources(net_model, now);
214
215   XBT_DEBUG("model %p, %s min_by_cpu %f, %s min_by_net %f",
216       workstation_model, cpu_model->name, min_by_cpu, net_model->name, min_by_net);
217
218   if (min_by_cpu >= 0.0 && min_by_net >= 0.0)
219     return min(min_by_cpu, min_by_net);
220   else if (min_by_cpu >= 0.0)
221     return min_by_cpu;
222   else if (min_by_net >= 0.0)
223     return min_by_net;
224   else
225     return min_by_cpu;  /* probably min_by_cpu == min_by_net == -1 */
226 }
227
228 void ws_update_actions_state(surf_model_t workstation_model, double now, double delta)
229 {
230   return;
231 }
232
233 void ws_update_resource_state(void *id, tmgr_trace_event_t event_type, double value, double date)
234 {
235   /* This model does not implement parallel tasks */
236   THROW_IMPOSSIBLE;
237 }
238
239 void ws_finalize(surf_model_t workstation_model)
240 {
241   surf_model_exit(workstation_model);
242   workstation_model = NULL;
243 }
244
245
246
247 surf_action_t ws_execute(void *workstation, double size)
248 {
249   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
250   return cpu->model->extension.cpu.execute(workstation, size);
251 }
252
253 surf_action_t ws_action_sleep(void *workstation, double duration)
254 {
255   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
256   return cpu->model->extension.cpu.sleep(workstation, duration);
257 }
258
259 void ws_action_suspend(surf_action_t action)
260 {
261   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
262     surf_network_model->suspend(action);
263   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
264     action->model_obj->suspend(action);
265   else
266     DIE_IMPOSSIBLE;
267 }
268
269 void ws_action_resume(surf_action_t action)
270 {
271   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
272     surf_network_model->resume(action);
273   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
274     action->model_obj->resume(action);
275   else
276     DIE_IMPOSSIBLE;
277 }
278
279 static int ws_action_is_suspended(surf_action_t action)
280 {
281   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
282     return surf_network_model->is_suspended(action);
283   if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
284     return action->model_obj->is_suspended(action);
285   DIE_IMPOSSIBLE;
286   return -1;
287 }
288
289 static void ws_action_set_max_duration(surf_action_t action,
290                                        double duration)
291 {
292   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
293     surf_network_model->set_max_duration(action, duration);
294   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
295     action->model_obj->set_max_duration(action, duration);
296   else
297     DIE_IMPOSSIBLE;
298 }
299
300 void ws_action_set_priority(surf_action_t action, double priority)
301 {
302   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
303     surf_network_model->set_priority(action, priority);
304   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
305     action->model_obj->set_priority(action, priority);
306   else
307     DIE_IMPOSSIBLE;
308 }
309
310 void ws_action_set_bound(surf_action_t action, double bound)
311 {
312   /* FIXME: only for CPU model object? */
313   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
314     surf_network_model->set_bound(action, bound);
315   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
316     action->model_obj->set_bound(action, bound);
317   else
318     DIE_IMPOSSIBLE;
319 }
320
321 #ifdef HAVE_TRACING
322 static void ws_action_set_category(surf_action_t action, const char *category)
323 {
324   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
325     surf_network_model->set_category(action, category);
326   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
327     action->model_obj->set_category(action, category);
328   else
329     DIE_IMPOSSIBLE;
330 }
331 #endif
332
333 #ifdef HAVE_LATENCY_BOUND_TRACKING
334 static int ws_get_latency_limited(surf_action_t action)
335 {
336   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
337     return surf_network_model->get_latency_limited(action);
338   else
339     return 0;
340 }
341 #endif
342
343 double ws_action_get_remains(surf_action_t action)
344 {
345   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
346     return surf_network_model->get_remains(action);
347   if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
348     return action->model_obj->get_remains(action);
349   DIE_IMPOSSIBLE;
350   return -1.0;
351 }
352
353 static surf_action_t ws_communicate(void *workstation_src,
354                                     void *workstation_dst, double size,
355                                     double rate)
356 {
357   workstation_CLM03_t src = surf_workstation_resource_priv(workstation_src);
358   workstation_CLM03_t dst = surf_workstation_resource_priv(workstation_dst);
359   return surf_network_model->extension.network.
360       communicate(src->net_elm,
361                   dst->net_elm, size, rate);
362 }
363
364 e_surf_resource_state_t ws_get_state(void *workstation)
365 {
366   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
367   return cpu->model->extension.cpu.get_state(workstation);
368 }
369
370 static void ws_set_state(void *workstation, e_surf_resource_state_t state)
371 {
372   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
373   cpu->model->extension.cpu.set_state(workstation, state);
374 }
375
376 double ws_get_speed(void *workstation, double load)
377 {
378   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
379   return cpu->model->extension.cpu.get_speed(workstation, load);
380 }
381
382 static int ws_get_core(void *workstation)
383 {
384   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
385   return cpu->model->extension.cpu.get_core(workstation);
386 }
387 static double ws_get_available_speed(void *workstation)
388 {
389   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
390   return cpu->model->extension.cpu.get_available_speed(workstation);
391 }
392
393 static surf_action_t ws_execute_parallel_task(int workstation_nb,
394                                               void **workstation_list,
395                                               double *computation_amount,
396                                               double *communication_amount,
397                                               double rate)
398 {
399 #define cost_or_zero(array,pos) ((array)?(array)[pos]:0.0)
400   if ((workstation_nb == 1)
401       && (cost_or_zero(communication_amount, 0) == 0.0))
402     return ws_execute(workstation_list[0], computation_amount[0]);
403   else if ((workstation_nb == 1)
404            && (cost_or_zero(computation_amount, 0) == 0.0))
405     return ws_communicate(workstation_list[0], workstation_list[0],communication_amount[0], rate);
406   else if ((workstation_nb == 2)
407              && (cost_or_zero(computation_amount, 0) == 0.0)
408              && (cost_or_zero(computation_amount, 1) == 0.0)) {
409     int i,nb = 0;
410     double value = 0.0;
411
412     for (i = 0; i < workstation_nb * workstation_nb; i++) {
413       if (cost_or_zero(communication_amount, i) > 0.0) {
414         nb++;
415         value = cost_or_zero(communication_amount, i);
416       }
417     }
418     if (nb == 1)
419       return ws_communicate(workstation_list[0], workstation_list[1],value, rate);
420   }
421 #undef cost_or_zero
422
423   THROW_UNIMPLEMENTED;          /* This model does not implement parallel tasks */
424   return NULL;
425 }
426
427
428 /* returns an array of network_link_CM02_t */
429 static xbt_dynar_t ws_get_route(void *workstation_src, void *workstation_dst)
430 {
431   XBT_DEBUG("ws_get_route");
432   workstation_CLM03_t src = surf_workstation_resource_priv(workstation_src);
433   workstation_CLM03_t dst = surf_workstation_resource_priv(workstation_dst);
434   return surf_network_model->extension.
435       network.get_route(src->net_elm,
436                   dst->net_elm);
437 }
438
439 static double ws_get_link_bandwidth(const void *link)
440 {
441   return surf_network_model->extension.network.get_link_bandwidth(link);
442 }
443
444 static double ws_get_link_latency(const void *link)
445 {
446   return surf_network_model->extension.network.get_link_latency(link);
447 }
448
449 static int ws_link_shared(const void *link)
450 {
451   return surf_network_model->extension.network.link_shared(link);
452 }
453
454 static xbt_dict_t ws_get_properties(const void *ws)
455 {
456   return surf_resource_properties(surf_cpu_resource_priv(ws));
457 }
458
459 static storage_t find_storage_on_mount_list(void *workstation,const char* storage)
460 {
461   storage_t st = NULL;
462   s_mount_t mnt;
463   unsigned int cursor;
464   workstation_CLM03_t ws = (workstation_CLM03_t) surf_workstation_resource_priv(workstation);
465   xbt_dynar_t storage_list = ws->storage;
466
467   XBT_DEBUG("Search for storage name '%s' on '%s'",storage,ws->generic_resource.name);
468   xbt_dynar_foreach(storage_list,cursor,mnt)
469   {
470     XBT_DEBUG("See '%s'",mnt.name);
471     if(!strcmp(storage,mnt.name)){
472       st = mnt.id;
473       break;
474     }
475   }
476   if(!st) xbt_die("Can't find mount '%s' for '%s'",storage,ws->generic_resource.name);
477   return st;
478 }
479
480 static surf_action_t ws_action_open(void *workstation, const char* mount,
481                                     const char* path)
482 {
483   storage_t st = find_storage_on_mount_list(workstation, mount);
484   XBT_DEBUG("OPEN on disk '%s'",st->generic_resource.name);
485   surf_model_t model = st->generic_resource.model;
486   return model->extension.storage.open(st, mount, path);
487 }
488
489 static surf_action_t ws_action_close(void *workstation, surf_file_t fd)
490 {
491   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
492   XBT_DEBUG("CLOSE on disk '%s'",st->generic_resource.name);
493   surf_model_t model = st->generic_resource.model;
494   return model->extension.storage.close(st, fd);
495 }
496
497 static surf_action_t ws_action_read(void *workstation, void* ptr, size_t size,
498                                     surf_file_t fd)
499 {
500   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
501   XBT_DEBUG("READ on disk '%s'",st->generic_resource.name);
502   surf_model_t model = st->generic_resource.model;
503   return model->extension.storage.read(st, ptr, size, fd);
504 }
505
506 static surf_action_t ws_action_write(void *workstation, const void* ptr,
507                                      size_t size, surf_file_t fd)
508 {
509   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
510   XBT_DEBUG("WRITE on disk '%s'",st->generic_resource.name);
511   surf_model_t model = st->generic_resource.model;
512   return model->extension.storage.write(st,  ptr, size, fd);
513 }
514
515 static int ws_file_unlink(void *workstation, surf_file_t fd)
516 {
517   if (!fd){
518     XBT_WARN("No such file descriptor. Impossible to unlink");
519     return 0;
520   } else {
521 //    XBT_INFO("%s %zu", fd->storage, fd->size);
522     storage_t st = find_storage_on_mount_list(workstation, fd->storage);
523     xbt_dict_t content_dict = (st)->content;
524     /* Check if the file is on this storage */
525     if (!xbt_dict_get_or_null(content_dict, fd->name)){
526       XBT_WARN("File %s is not on disk %s. Impossible to unlink", fd->name,
527           st->generic_resource.name);
528       return 0;
529     } else {
530       XBT_DEBUG("UNLINK on disk '%s'",st->generic_resource.name);
531       st->used_size -= fd->size;
532
533       // Remove the file from storage
534       xbt_dict_remove(content_dict,fd->name);
535
536       free(fd->name);
537       free(fd->storage);
538       xbt_free(fd);
539       return 1;
540     }
541   }
542 }
543
544 static surf_action_t ws_action_ls(void *workstation, const char* mount,
545                                   const char *path)
546 {
547   XBT_DEBUG("LS on mount '%s' and file '%s'",mount, path);
548   storage_t st = find_storage_on_mount_list(workstation, mount);
549   surf_model_t model = st->generic_resource.model;
550   return model->extension.storage.ls(st, path);
551 }
552
553 static size_t ws_file_get_size(void *workstation, surf_file_t fd)
554 {
555   return fd->size;
556 }
557
558 void ws_get_params(void *ws, ws_params_t params)
559 {
560   workstation_CLM03_t ws_clm03 = surf_workstation_resource_priv(ws);
561   memcpy(params, &ws_clm03->params, sizeof(s_ws_params_t));
562 }
563
564 void ws_set_params(void *ws, ws_params_t params)
565 {
566   workstation_CLM03_t ws_clm03 = surf_workstation_resource_priv(ws);
567   /* may check something here. */
568   memcpy(&ws_clm03->params, params, sizeof(s_ws_params_t));
569 }
570
571 static xbt_dynar_t ws_get_vms(void *pm)
572 {
573   xbt_dynar_t dyn = xbt_dynar_new(sizeof(smx_host_t), NULL);
574
575   /* iterate for all hosts including virtual machines */
576   xbt_lib_cursor_t cursor;
577   char *key;
578   void **ind_host;
579   xbt_lib_foreach(host_lib, cursor, key, ind_host) {
580     workstation_CLM03_t ws_clm03 = ind_host[SURF_WKS_LEVEL];
581     if (!ws_clm03)
582       continue;
583     /* skip if it is not a virtual machine */
584     if (ws_clm03->generic_resource.model != surf_vm_workstation_model)
585       continue;
586
587     /* It is a virtual machine, so we can cast it to workstation_VM2013_t */
588     workstation_VM2013_t ws_vm2013 = (workstation_VM2013_t) ws_clm03;
589     if (pm == ws_vm2013->sub_ws)
590       xbt_dynar_push(dyn, &ws_vm2013->sub_ws);
591   }
592
593   return dyn;
594 }
595
596
597 static void surf_workstation_model_init_internal(void)
598 {
599   surf_model_t model = surf_model_init();
600
601   model->name = "Workstation";
602   model->type = SURF_MODEL_TYPE_WORKSTATION;
603   model->action_unref     = ws_action_unref;
604   model->action_cancel    = ws_action_cancel;
605   model->action_state_set = ws_action_state_set;
606
607   model->model_private->resource_used         = ws_resource_used;
608   model->model_private->share_resources       = ws_share_resources;
609   model->model_private->update_actions_state  = ws_update_actions_state;
610   model->model_private->update_resource_state = ws_update_resource_state;
611   model->model_private->finalize              = ws_finalize;
612
613   model->suspend          = ws_action_suspend;
614   model->resume           = ws_action_resume;
615   model->is_suspended     = ws_action_is_suspended;
616   model->set_max_duration = ws_action_set_max_duration;
617   model->set_priority     = ws_action_set_priority;
618   model->set_bound        = ws_action_set_bound;
619   #ifdef HAVE_TRACING
620   model->set_category     = ws_action_set_category;
621   #endif
622   model->get_remains      = ws_action_get_remains;
623   #ifdef HAVE_LATENCY_BOUND_TRACKING
624   model->get_latency_limited = ws_get_latency_limited;
625   #endif
626
627   /* For VM support, we have a surf cpu model object for each workstation model
628    * object. The physical workstation model object has the cpu model object of
629    * the physical machine layer. */
630   xbt_assert(surf_cpu_model_pm);
631   model->extension.workstation.cpu_model = surf_cpu_model_pm;
632
633   model->extension.workstation.execute   = ws_execute;
634   model->extension.workstation.sleep     = ws_action_sleep;
635   model->extension.workstation.get_state = ws_get_state;
636   model->extension.workstation.set_state = ws_set_state;
637   model->extension.workstation.get_core  = ws_get_core;
638   model->extension.workstation.get_speed = ws_get_speed;
639   model->extension.workstation.get_available_speed =
640       ws_get_available_speed;
641
642   model->extension.workstation.communicate           = ws_communicate;
643   model->extension.workstation.get_route             = ws_get_route;
644   model->extension.workstation.execute_parallel_task = ws_execute_parallel_task;
645   model->extension.workstation.get_link_bandwidth    = ws_get_link_bandwidth;
646   model->extension.workstation.get_link_latency      = ws_get_link_latency;
647   model->extension.workstation.link_shared           = ws_link_shared;
648   model->extension.workstation.get_properties        = ws_get_properties;
649
650   model->extension.workstation.open   = ws_action_open;
651   model->extension.workstation.close  = ws_action_close;
652   model->extension.workstation.read   = ws_action_read;
653   model->extension.workstation.write  = ws_action_write;
654   model->extension.workstation.unlink = ws_file_unlink;
655   model->extension.workstation.ls     = ws_action_ls;
656
657   model->extension.workstation.get_params = ws_get_params;
658   model->extension.workstation.set_params = ws_set_params;
659   model->extension.workstation.get_vms    = ws_get_vms;
660
661   surf_workstation_model = model;
662 }
663
664 void surf_workstation_model_init_current_default(void)
665 {
666   xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", xbt_strdup("yes"));
667   surf_cpu_model_init_Cas01();
668   surf_network_model_init_LegrandVelho();
669
670   /* surf_cpu_mode_pm and surf_network_model must be initialized in advance. */
671   xbt_assert(surf_cpu_model_pm);
672   xbt_assert(surf_network_model);
673   surf_workstation_model_init_internal();
674
675   xbt_dynar_push(model_list, &surf_workstation_model);
676   xbt_dynar_push(model_list_invoke, &surf_workstation_model);
677   sg_platf_host_add_cb(workstation_new);
678 }
679
680 void surf_workstation_model_init_compound()
681 {
682   xbt_assert(surf_cpu_model_pm, "No CPU model defined yet!");
683   xbt_assert(surf_network_model, "No network model defined yet!");
684
685   surf_workstation_model_init_internal();
686   xbt_dynar_push(model_list, &surf_workstation_model);
687   xbt_dynar_push(model_list_invoke, &surf_workstation_model);
688   sg_platf_host_add_cb(workstation_new);
689 }