Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
5656eb911d39141f9240e160221c7cea8847a9c4
[simgrid.git] / src / surf / surf_config.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 /* surf_config: configuration infrastructure for the simulation world       */
8
9 #include "xbt/config.h"
10 #include "xbt/str.h"
11 #include "surf/surf_private.h"
12 #include "surf/surf_routing.h"  /* COORD_HOST_LEVEL and COORD_ASR_LEVEL */
13 #include "simix/context.h"
14
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_config, surf,
16                                 "About the configuration of surf (and the rest of the simulation)");
17
18 xbt_cfg_t _surf_cfg_set = NULL;
19
20 /* Parse the command line, looking for options */
21 static void surf_config_cmd_line(int *argc, char **argv)
22 {
23   int i, j;
24   char *opt;
25
26   for (i = 1; i < *argc; i++) {
27     int remove_it = 0;
28     if (!strncmp(argv[i], "--cfg=", strlen("--cfg="))) {
29       opt = strchr(argv[i], '=');
30       opt++;
31
32       xbt_cfg_set_parse(_surf_cfg_set, opt);
33       XBT_DEBUG("Did apply '%s' as config setting", opt);
34       remove_it = 1;
35     } else if (!strncmp(argv[i], "--cfg-help", strlen("--cfg-help") + 1) ||
36                !strncmp(argv[i], "--help", strlen("--help") + 1)) {
37       printf
38           ("Description of the configuration accepted by this simulator:\n");
39       xbt_cfg_help(_surf_cfg_set);
40       printf("\nYou can also use --help-models to see the details of all models known by this simulator.\n");
41 #ifdef HAVE_TRACING
42       printf("\nYou can also use --help-tracing to see the details of all tracing options known by this simulator.\n");
43 #endif
44       exit(0);
45     } else if (!strncmp(argv[i], "--help-models", strlen("--help-models") + 1)) {
46       model_help("workstation", surf_workstation_model_description);
47       model_help("CPU", surf_cpu_model_description);
48       model_help("network", surf_network_model_description);
49       printf("\nLong description of all optimization levels accepted by the models of this simulator:\n");
50       for (i = 0; surf_optimization_mode_description[i].name; i++)
51         printf("  %s: %s\n", surf_optimization_mode_description[i].name, surf_optimization_mode_description[i].description);
52       printf("Both network and CPU models have 'Lazy' as default optimization level\n");
53       exit(0);
54 #ifdef HAVE_TRACING
55     } else if (!strncmp(argv[i], "--help-tracing", strlen("--help-tracing") + 1)) {
56       TRACE_help (1);
57       exit(0);
58 #endif
59     }
60     if (remove_it) {            /*remove this from argv */
61       for (j = i + 1; j < *argc; j++) {
62         argv[j - 1] = argv[j];
63       }
64
65       argv[j - 1] = NULL;
66       (*argc)--;
67       i--;                      /* compensate effect of next loop incrementation */
68     }
69   }
70 }
71
72
73 int _surf_init_status = 0;      /* 0: beginning of time;
74                                    1: pre-inited (cfg_set created);
75                                    2: inited (running) */
76
77 /* callback of the workstation/model variable */
78 static void _surf_cfg_cb__workstation_model(const char *name, int pos)
79 {
80   char *val;
81
82   xbt_assert(_surf_init_status < 2,
83               "Cannot change the model after the initialization");
84
85   val = xbt_cfg_get_string(_surf_cfg_set, name);
86
87   if (!strcmp(val, "help")) {
88     model_help("workstation", surf_workstation_model_description);
89     exit(0);
90   }
91
92   /* Make sure that the model exists */
93   find_model_description(surf_workstation_model_description, val);
94 }
95
96 /* callback of the cpu/model variable */
97 static void _surf_cfg_cb__cpu_model(const char *name, int pos)
98 {
99   char *val;
100
101   xbt_assert(_surf_init_status < 2,
102               "Cannot change the model after the initialization");
103
104   val = xbt_cfg_get_string(_surf_cfg_set, name);
105
106   if (!strcmp(val, "help")) {
107     model_help("CPU", surf_cpu_model_description);
108     exit(0);
109   }
110
111   /* New Module missing */
112   find_model_description(surf_cpu_model_description, val);
113 }
114
115 /* callback of the cpu/model variable */
116 static void _surf_cfg_cb__optimization_mode(const char *name, int pos)
117 {
118   char *val;
119
120   xbt_assert(_surf_init_status < 2,
121               "Cannot change the model after the initialization");
122
123   val = xbt_cfg_get_string(_surf_cfg_set, name);
124
125   if (!strcmp(val, "help")) {
126     model_help("optimization", surf_optimization_mode_description);
127     exit(0);
128   }
129
130   /* New Module missing */
131   find_model_description(surf_optimization_mode_description, val);
132 }
133
134 /* callback of the workstation_model variable */
135 static void _surf_cfg_cb__network_model(const char *name, int pos)
136 {
137   char *val;
138
139   xbt_assert(_surf_init_status < 2,
140               "Cannot change the model after the initialization");
141
142   val = xbt_cfg_get_string(_surf_cfg_set, name);
143
144   if (!strcmp(val, "help")) {
145     model_help("network", surf_network_model_description);
146     exit(0);
147   }
148
149   /* New Module missing */
150   find_model_description(surf_network_model_description, val);
151 }
152
153
154 /* callbacks of the network models values */
155 static void _surf_cfg_cb__tcp_gamma(const char *name, int pos)
156 {
157   sg_tcp_gamma = xbt_cfg_get_double(_surf_cfg_set, name);
158 }
159
160 static void _surf_cfg_cb__maxmin_precision(const char* name, int pos)
161 {
162   sg_maxmin_precision = xbt_cfg_get_double(_surf_cfg_set, name);
163 }
164
165 static void _surf_cfg_cb__sender_gap(const char* name, int pos)
166 {
167   sg_sender_gap = xbt_cfg_get_double(_surf_cfg_set, name);
168 }
169
170 static void _surf_cfg_cb__latency_factor(const char *name, int pos)
171 {
172   sg_latency_factor = xbt_cfg_get_double(_surf_cfg_set, name);
173 }
174
175 static void _surf_cfg_cb__bandwidth_factor(const char *name, int pos)
176 {
177   sg_bandwidth_factor = xbt_cfg_get_double(_surf_cfg_set, name);
178 }
179
180 static void _surf_cfg_cb__weight_S(const char *name, int pos)
181 {
182   sg_weight_S_parameter = xbt_cfg_get_double(_surf_cfg_set, name);
183 }
184
185 /* callback of the inclusion path */
186 static void _surf_cfg_cb__surf_path(const char *name, int pos)
187 {
188   char *path = xbt_cfg_get_string_at(_surf_cfg_set, name, pos);
189   xbt_dynar_push(surf_path, &path);
190 }
191
192 /* callback to decide if we want to use the model-checking */
193 #include "xbt_modinter.h"
194 extern int _surf_do_model_check;   /* this variable lives in xbt_main until I find a right location for it */
195
196 static void _surf_cfg_cb_model_check(const char *name, int pos)
197 {
198   _surf_do_model_check = xbt_cfg_get_int(_surf_cfg_set, name);
199
200   if (_surf_do_model_check) {
201     /* Tell modules using mallocators that they shouldn't. MC don't like them */
202     xbt_fifo_preinit();
203     xbt_dict_preinit();
204   }
205 }
206
207 extern int _surf_do_verbose_exit;
208
209 static void _surf_cfg_cb_verbose_exit(const char *name, int pos)
210 {
211   _surf_do_verbose_exit = xbt_cfg_get_int(_surf_cfg_set, name);
212 }
213
214
215 static void _surf_cfg_cb_context_factory(const char *name, int pos)
216 {
217   smx_context_factory_name = xbt_cfg_get_string(_surf_cfg_set, name);
218 }
219
220 static void _surf_cfg_cb_context_stack_size(const char *name, int pos)
221 {
222   smx_context_stack_size = xbt_cfg_get_int(_surf_cfg_set, name) * 1024;
223 }
224
225 static void _surf_cfg_cb_contexts_nthreads(const char *name, int pos)
226 {
227   SIMIX_context_set_nthreads(xbt_cfg_get_int(_surf_cfg_set, name));
228 }
229
230 static void _surf_cfg_cb_contexts_parallel_threshold(const char *name, int pos)
231 {
232   SIMIX_context_set_parallel_threshold(xbt_cfg_get_int(_surf_cfg_set, name));
233 }
234
235 static void _surf_cfg_cb_contexts_parallel_mode(const char *name, int pos)
236 {
237   const char* mode_name = xbt_cfg_get_string(_surf_cfg_set, name);
238   if (!strcmp(mode_name, "posix")) {
239     SIMIX_context_set_parallel_mode(XBT_PARMAP_POSIX);
240   }
241   else if (!strcmp(mode_name, "futex")) {
242     SIMIX_context_set_parallel_mode(XBT_PARMAP_FUTEX);
243   }
244   else if (!strcmp(mode_name, "busy_wait")) {
245     SIMIX_context_set_parallel_mode(XBT_PARMAP_BUSY_WAIT);
246   }
247   else {
248     XBT_WARN("Command line setting of the parallel synchronization mode should "
249         "be one of \"posix\", \"futex\" or \"busy_wait\"");
250   }
251 }
252
253 static void _surf_cfg_cb__surf_network_coordinates(const char *name,
254                                                    int pos)
255 {
256   char *val = xbt_cfg_get_string(_surf_cfg_set, name);
257   if (!strcmp(val, "yes")) {
258     if (!COORD_HOST_LEVEL) {
259       COORD_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_dynar_free_voidp);
260       COORD_ASR_LEVEL  = xbt_lib_add_level(as_router_lib,xbt_dynar_free_voidp);
261     }
262   } else if (!strcmp(val, "no")) {
263     if (COORD_HOST_LEVEL)
264       XBT_WARN("Setting of whether to use coordinate cannot be disabled once set.");
265   } else {
266     XBT_WARN("Command line setting of whether to use coordinates must be either \"yes\" or \"no\"");
267   }
268 }
269
270 static void _surf_cfg_cb__surf_network_crosstraffic(const char *name,
271                                                   int pos)
272 {
273   sg_network_crosstraffic = xbt_cfg_get_int(_surf_cfg_set, name);
274 }
275
276 #ifdef HAVE_GTNETS
277 static void _surf_cfg_cb__gtnets_jitter(const char *name, int pos)
278 {
279   sg_gtnets_jitter = xbt_cfg_get_double(_surf_cfg_set, name);
280 }
281
282 static void _surf_cfg_cb__gtnets_jitter_seed(const char *name, int pos)
283 {
284   sg_gtnets_jitter_seed = xbt_cfg_get_int(_surf_cfg_set, name);
285 }
286 #endif
287
288 /* create the config set, register what should be and parse the command line*/
289 void surf_config_init(int *argc, char **argv)
290 {
291   char *description = xbt_malloc(1024), *p = description;
292   char *default_value;
293   double double_default_value;
294   int default_value_int;
295   int i;
296
297   /* Create the configuration support */
298   if (_surf_init_status == 0) { /* Only create stuff if not already inited */
299     _surf_init_status = 1;
300
301     sprintf(description,
302             "The model to use for the CPU. Possible values: ");
303     p = description;
304     while (*(++p) != '\0');
305     for (i = 0; surf_cpu_model_description[i].name; i++)
306       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
307                    surf_cpu_model_description[i].name);
308     sprintf(p,
309             ".\n       (use 'help' as a value to see the long description of each model)");
310     default_value = xbt_strdup("Cas01");
311     xbt_cfg_register(&_surf_cfg_set,
312                      "cpu/model", description, xbt_cfgelm_string,
313                      &default_value, 1, 1, &_surf_cfg_cb__cpu_model, NULL);
314
315     sprintf(description,
316             "The optimization modes to use for the CPU. Possible values: ");
317     p = description;
318     while (*(++p) != '\0');
319     for (i = 0; surf_optimization_mode_description[i].name; i++)
320       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
321                    surf_optimization_mode_description[i].name);
322     sprintf(p,
323             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
324     default_value = xbt_strdup("Lazy");
325     xbt_cfg_register(&_surf_cfg_set,
326                      "cpu/optim", description, xbt_cfgelm_string,
327                      &default_value, 1, 1, &_surf_cfg_cb__optimization_mode, NULL);
328
329     sprintf(description,
330             "The model to use for the network. Possible values: ");
331     p = description;
332     while (*(++p) != '\0');
333     for (i = 0; surf_network_model_description[i].name; i++)
334       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
335                    surf_network_model_description[i].name);
336     sprintf(p,
337             ".\n       (use 'help' as a value to see the long description of each model)");
338     default_value = xbt_strdup("LV08");
339     xbt_cfg_register(&_surf_cfg_set,
340                      "network/model", description, xbt_cfgelm_string,
341                      &default_value, 1, 1, &_surf_cfg_cb__network_model,
342                      NULL);
343
344     sprintf(description,
345             "The optimization modes to use for the network. Possible values: ");
346     p = description;
347     while (*(++p) != '\0');
348     for (i = 0; surf_optimization_mode_description[i].name; i++)
349       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
350                    surf_optimization_mode_description[i].name);
351     sprintf(p,
352             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
353     default_value = xbt_strdup("Lazy");
354     xbt_cfg_register(&_surf_cfg_set,
355                      "network/optim", description, xbt_cfgelm_string,
356                      &default_value, 1, 1, &_surf_cfg_cb__optimization_mode, NULL);
357
358     sprintf(description,
359             "The model to use for the workstation. Possible values: ");
360     p = description;
361     while (*(++p) != '\0');
362     for (i = 0; surf_workstation_model_description[i].name; i++)
363       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
364                    surf_workstation_model_description[i].name);
365     sprintf(p,
366             ".\n       (use 'help' as a value to see the long description of each model)");
367     default_value = xbt_strdup("current_default");
368     xbt_cfg_register(&_surf_cfg_set,
369                      "workstation/model", description, xbt_cfgelm_string,
370                      &default_value, 1, 1,
371                      &_surf_cfg_cb__workstation_model, NULL);
372
373     xbt_free(description);
374
375     default_value = xbt_strdup("Full");
376     xbt_cfg_register(&_surf_cfg_set, "routing",
377                      "Model to use to store the routing information",
378                      xbt_cfgelm_string, &default_value, 1, 1, NULL, NULL);
379
380     xbt_cfg_register(&_surf_cfg_set, "TCP_gamma",
381                      "Size of the biggest TCP window (cat /proc/sys/net/ipv4/tcp_[rw]mem for recv/send window; Use the last given value, which is the max window size)",
382                      xbt_cfgelm_double, NULL, 1, 1,
383                      _surf_cfg_cb__tcp_gamma, NULL);
384     xbt_cfg_setdefault_double(_surf_cfg_set, "TCP_gamma", 20000.0);
385
386     xbt_cfg_register(&_surf_cfg_set, "maxmin/precision",
387                      "Minimum retained action value when updating simulation",
388                      xbt_cfgelm_double, NULL, 1, 1, _surf_cfg_cb__maxmin_precision, NULL);
389     xbt_cfg_setdefault_double(_surf_cfg_set, "maxmin/precision", 0.00001); // FIXME use setdefault everywhere here!
390
391     /* The parameters of network models */
392
393     double_default_value = 0.0;
394     xbt_cfg_register(&_surf_cfg_set, "network/sender_gap",
395                      "Minimum gap between two overlapping sends",
396                      xbt_cfgelm_double, &double_default_value, 1, 1,
397                      _surf_cfg_cb__sender_gap, NULL);
398
399     double_default_value = 1.0;
400     xbt_cfg_register(&_surf_cfg_set, "network/latency_factor",
401                      "Correction factor to apply to the provided latency (default value set by network model)",
402                      xbt_cfgelm_double, &double_default_value, 1, 1,
403                      _surf_cfg_cb__latency_factor, NULL);
404     double_default_value = 1.0;
405     xbt_cfg_register(&_surf_cfg_set, "network/bandwidth_factor",
406                      "Correction factor to apply to the provided bandwidth (default value set by network model)",
407                      xbt_cfgelm_double, &double_default_value, 1, 1,
408                      _surf_cfg_cb__bandwidth_factor, NULL);
409     double_default_value = 0.0;
410     xbt_cfg_register(&_surf_cfg_set, "network/weight_S",
411                      "Correction factor to apply to the weight of competing streams(default value set by network model)",
412                      xbt_cfgelm_double, &double_default_value, 1, 1,
413                      _surf_cfg_cb__weight_S, NULL);
414
415     /* Inclusion path */
416     xbt_cfg_register(&_surf_cfg_set, "path",
417                      "Lookup path for inclusions in platform and deployment XML files",
418                      xbt_cfgelm_string, NULL, 0, 0,
419                      _surf_cfg_cb__surf_path, NULL);
420
421     default_value_int = 0;
422     xbt_cfg_register(&_surf_cfg_set, "cpu/maxmin_selective_update",
423                      "Update the constraint set propagating recursively to others constraints (1 by default when optim is set to lazy)",
424                      xbt_cfgelm_int, &default_value_int, 0, 1,
425                      NULL, NULL);
426     default_value_int = 0;
427     xbt_cfg_register(&_surf_cfg_set, "network/maxmin_selective_update",
428                      "Update the constraint set propagating recursively to others constraints (1 by default when optim is set to lazy)",
429                      xbt_cfgelm_int, &default_value_int, 0, 1,
430                      NULL, NULL);
431
432     /* do model-check */
433     default_value_int = 0;
434     xbt_cfg_register(&_surf_cfg_set, "model-check",
435                      "Activate the model-checking of the \"simulated\" system (EXPERIMENTAL -- msg only for now)",
436                      xbt_cfgelm_int, &default_value_int, 0, 1,
437                      _surf_cfg_cb_model_check, NULL);
438     
439     /*
440        FIXME: this function is not setting model-check to it's default value because
441        internally it calls to variable->cb_set that in this case is the function 
442        _surf_cfg_cb_model_check which sets it's value to 1 (instead of the default value 0)
443        xbt_cfg_set_int(_surf_cfg_set, "model-check", default_value_int); */
444
445     /* do verbose-exit */
446     default_value_int = 0;
447     xbt_cfg_register(&_surf_cfg_set, "verbose-exit",
448                      "Activate the \"do nothing\" mode in Ctrl-C",
449                      xbt_cfgelm_int, &default_value_int, 0, 1,
450                      _surf_cfg_cb_verbose_exit, NULL);
451     
452     
453     /* context factory */
454     default_value = xbt_strdup("ucontext");
455     xbt_cfg_register(&_surf_cfg_set, "contexts/factory",
456                      "Context factory to use in SIMIX (ucontext, thread or raw)",
457                      xbt_cfgelm_string, &default_value, 1, 1, _surf_cfg_cb_context_factory, NULL);
458
459     /* stack size of contexts in Ko */
460     default_value_int = 128;
461     xbt_cfg_register(&_surf_cfg_set, "contexts/stack_size",
462                      "Stack size of contexts in Ko (ucontext or raw only)",
463                      xbt_cfgelm_int, &default_value_int, 1, 1,
464                      _surf_cfg_cb_context_stack_size, NULL);
465
466     /* number of parallel threads for user processes */
467     default_value_int = 1;
468     xbt_cfg_register(&_surf_cfg_set, "contexts/nthreads",
469                      "Number of parallel threads for user contexts (EXPERIMENTAL)",
470                      xbt_cfgelm_int, &default_value_int, 1, 1,
471                      _surf_cfg_cb_contexts_nthreads, NULL);
472
473     /* minimal number of user contexts to be run in parallel */
474     default_value_int = 1;
475     xbt_cfg_register(&_surf_cfg_set, "contexts/parallel_threshold",
476         "Minimal number of user contexts to be run in parallel (raw contexts only)",
477         xbt_cfgelm_int, &default_value_int, 1, 1,
478         _surf_cfg_cb_contexts_parallel_threshold, NULL);
479
480     /* minimal number of user contexts to be run in parallel */
481     default_value = xbt_strdup("futex");
482     xbt_cfg_register(&_surf_cfg_set, "contexts/parallel_mode",
483         "Synchronization mode to use when running contexts in parallel",
484         xbt_cfgelm_string, &default_value, 1, 1,
485         _surf_cfg_cb_contexts_parallel_mode, NULL);
486
487     default_value = xbt_strdup("no");
488     xbt_cfg_register(&_surf_cfg_set, "coordinates",
489                      "\"yes\" or \"no\" (FIXME: document)",
490                      xbt_cfgelm_string, &default_value, 1, 1,
491                      _surf_cfg_cb__surf_network_coordinates, NULL);
492     xbt_cfg_setdefault_string(_surf_cfg_set, "coordinates", default_value);
493
494     default_value_int = 0;
495     xbt_cfg_register(&_surf_cfg_set, "network/crosstraffic",
496                      "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
497                      xbt_cfgelm_int, &default_value_int, 0, 1,
498                      _surf_cfg_cb__surf_network_crosstraffic, NULL);
499     xbt_cfg_setdefault_int(_surf_cfg_set, "network/crosstraffic", default_value_int);
500
501 #ifdef HAVE_GTNETS
502     xbt_cfg_register(&_surf_cfg_set, "gtnets_jitter",
503                      "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)",
504                      xbt_cfgelm_double, NULL, 1, 1,
505                      _surf_cfg_cb__gtnets_jitter, NULL);
506     xbt_cfg_setdefault_double(_surf_cfg_set, "gtnets_jitter", 0.0);
507
508     default_value_int = 10;
509     xbt_cfg_register(&_surf_cfg_set, "gtnets_jitter_seed",
510                      "Use a positive seed to reproduce jitted results, value must be in [1,1e8], default is 10",
511                      xbt_cfgelm_int, &default_value_int, 0, 1,
512                      _surf_cfg_cb__gtnets_jitter_seed, NULL);
513 #endif
514 #ifdef HAVE_NS3
515     xbt_cfg_register(&_surf_cfg_set, "ns3/TcpModel",
516                      "The ns3 tcp model can be : NewReno or Reno or Tahoe",
517                      xbt_cfgelm_string, NULL, 1, 1,
518                      NULL, NULL);
519     xbt_cfg_setdefault_string(_surf_cfg_set, "ns3/TcpModel", "default");
520 #endif
521     if (!surf_path) {
522       /* retrieves the current directory of the        current process */
523       const char *initial_path = __surf_get_initial_path();
524       xbt_assert((initial_path),
525                   "__surf_get_initial_path() failed! Can't resolves current Windows directory");
526
527       surf_path = xbt_dynar_new(sizeof(char *), NULL);
528       xbt_cfg_setdefault_string(_surf_cfg_set, "path", initial_path);
529     }
530
531
532     surf_config_cmd_line(argc, argv);
533   } else {
534     XBT_WARN("Call to surf_config_init() after initialization ignored");
535   }
536 }
537
538 void surf_config_finalize(void)
539 {
540   if (!_surf_init_status)
541     return;                     /* Not initialized yet. Nothing to do */
542
543   xbt_cfg_free(&_surf_cfg_set);
544   _surf_init_status = 0;
545 }
546
547 /* Pick the right models for CPU, net and workstation, and call their model_init_preparse */
548 void surf_config_models_setup()
549 {
550   char *workstation_model_name;
551   int workstation_id = -1;
552   char *network_model_name = NULL;
553   char *cpu_model_name = NULL;
554
555   workstation_model_name =
556       xbt_cfg_get_string(_surf_cfg_set, "workstation/model");
557   network_model_name = xbt_cfg_get_string(_surf_cfg_set, "network/model");
558   cpu_model_name = xbt_cfg_get_string(_surf_cfg_set, "cpu/model");
559
560   /* Check whether we use a net/cpu model differing from the default ones, in which case
561    * we should switch to the "compound" workstation model to correctly dispatch stuff to
562    * the right net/cpu models.
563    */
564
565   if((!xbt_cfg_is_default_value(_surf_cfg_set, "network/model") ||
566           !xbt_cfg_is_default_value(_surf_cfg_set, "cpu/model")) &&
567           xbt_cfg_is_default_value(_surf_cfg_set, "workstation/model"))
568   {
569             const char *val = "compound";
570             XBT_INFO
571                 ("Switching workstation model to compound since you changed the network and/or cpu model(s)");
572             xbt_cfg_set_string(_surf_cfg_set, "workstation/model", val);
573             workstation_model_name = (char *) "compound";
574   }
575
576   XBT_DEBUG("Workstation model: %s", workstation_model_name);
577   workstation_id =
578       find_model_description(surf_workstation_model_description,
579                              workstation_model_name);
580   if (!strcmp(workstation_model_name, "compound")) {
581     int network_id = -1;
582     int cpu_id = -1;
583
584     xbt_assert(cpu_model_name,
585                 "Set a cpu model to use with the 'compound' workstation model");
586
587     xbt_assert(network_model_name,
588                 "Set a network model to use with the 'compound' workstation model");
589
590     network_id =
591         find_model_description(surf_network_model_description,
592                                network_model_name);
593     cpu_id =
594         find_model_description(surf_cpu_model_description, cpu_model_name);
595
596     surf_cpu_model_description[cpu_id].model_init_preparse();
597     surf_network_model_description[network_id].model_init_preparse();
598   }
599
600   XBT_DEBUG("Call workstation_model_init");
601   surf_workstation_model_description[workstation_id].model_init_preparse();
602 }