Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'hypervisor' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid...
[simgrid.git] / src / simgrid / sg_config.c
1 /* Copyright (c) 2009-2010, 2012-2013. 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 /* sg_config: configuration infrastructure for the simulation world       */
8
9 #include "xbt/misc.h"
10 #include "xbt/config.h"
11 #include "xbt/log.h"
12 #include "xbt/mallocator.h"
13 #include "xbt/str.h"
14 #include "xbt/lib.h"
15 #include "xbt/sysdep.h"
16 #include "surf/surf.h"
17 #include "surf/maxmin.h"
18 #include "instr/instr_interface.h"
19 #include "simgrid/simix.h"
20 #include "simgrid/sg_config.h"
21 #include "smpi/smpi_interface.h"
22 #include "mc/mc.h"
23 #include "instr/instr.h"
24 #include "surf/vm_workstation_private.h"
25
26 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_config, surf,
27                                 "About the configuration of simgrid");
28
29 xbt_cfg_t _sg_cfg_set = NULL;
30
31 /* 0: beginning of time (config cannot be changed yet);
32  * 1: initialized: cfg_set created (config can now be changed);
33  * 2: configured: command line parsed and config part of platform file was
34  *    integrated also, platform construction ongoing or done.
35  *    (Config cannot be changed anymore!)
36  */
37 int _sg_cfg_init_status = 0;
38
39 /* instruct the upper layer (simix or simdag) to exit as soon as possible
40  */
41 int _sg_cfg_exit_asap = 0;
42
43 #define sg_cfg_exit_early() do { _sg_cfg_exit_asap = 1; return; } while (0)
44
45 /* Parse the command line, looking for options */
46 static void sg_config_cmd_line(int *argc, char **argv)
47 {
48   int shall_exit = 0;
49   int i, j;
50   char *opt;
51
52   for (j = i = 1; i < *argc; i++) {
53     if (!strncmp(argv[i], "--cfg=", strlen("--cfg="))) {
54       opt = strchr(argv[i], '=');
55       opt++;
56
57       xbt_cfg_set_parse(_sg_cfg_set, opt);
58       XBT_DEBUG("Did apply '%s' as config setting", opt);
59     } else if (!strcmp(argv[i], "--cfg-help") || !strcmp(argv[i], "--help")) {
60       printf
61           ("Description of the configuration accepted by this simulator:\n");
62       xbt_cfg_help(_sg_cfg_set);
63       printf(
64 "\n"
65 "Each of these configurations can be used by adding\n"
66 "    --cfg=<option name>:<option value>\n"
67 "to the command line.\n"
68 "You can also use --help-models to see the details of all models known by this simulator.\n"
69 #ifdef HAVE_TRACING
70 "\n"
71 "You can also use --help-tracing to see the details of all tracing options known by this simulator.\n"
72 #endif
73 "\n"
74 "You can also use --help-logs and --help-log-categories to see the details of logging output.\n"
75 "\n"
76         );
77       shall_exit = 1;
78     } else if (!strcmp(argv[i], "--help-models")) {
79       int k;
80
81       model_help("workstation", surf_workstation_model_description);
82       printf("\n");
83       model_help("CPU", surf_cpu_model_description);
84       printf("\n");
85       model_help("network", surf_network_model_description);
86       printf("\nLong description of all optimization levels accepted by the models of this simulator:\n");
87       for (k = 0; surf_optimization_mode_description[k].name; k++)
88         printf("  %s: %s\n",
89                surf_optimization_mode_description[k].name,
90                surf_optimization_mode_description[k].description);
91       printf("Both network and CPU models have 'Lazy' as default optimization level\n\n");
92       shall_exit = 1;
93 #ifdef HAVE_TRACING
94     } else if (!strcmp(argv[i], "--help-tracing")) {
95       TRACE_help (1);
96       shall_exit = 1;
97 #endif
98     } else {
99       argv[j++] = argv[i];
100     }
101   }
102   if (j < *argc) {
103     argv[j] = NULL;
104     *argc = j;
105   }
106   if (shall_exit)
107     sg_cfg_exit_early();
108 }
109
110 /* callback of the workstation/model variable */
111 static void _sg_cfg_cb__workstation_model(const char *name, int pos)
112 {
113   char *val;
114
115   xbt_assert(_sg_cfg_init_status < 2,
116               "Cannot change the model after the initialization");
117
118   val = xbt_cfg_get_string(_sg_cfg_set, name);
119
120   if (!strcmp(val, "help")) {
121     model_help("workstation", surf_workstation_model_description);
122     sg_cfg_exit_early();
123   }
124
125   /* Make sure that the model exists */
126   find_model_description(surf_workstation_model_description, val);
127 }
128
129 /* callback of the cpu/model variable */
130 static void _sg_cfg_cb__cpu_model(const char *name, int pos)
131 {
132   char *val;
133
134   xbt_assert(_sg_cfg_init_status < 2,
135               "Cannot change the model after the initialization");
136
137   val = xbt_cfg_get_string(_sg_cfg_set, name);
138
139   if (!strcmp(val, "help")) {
140     model_help("CPU", surf_cpu_model_description);
141     sg_cfg_exit_early();
142   }
143
144   /* New Module missing */
145   find_model_description(surf_cpu_model_description, val);
146 }
147
148 /* callback of the cpu/model variable */
149 static void _sg_cfg_cb__optimization_mode(const char *name, int pos)
150 {
151   char *val;
152
153   xbt_assert(_sg_cfg_init_status < 2,
154               "Cannot change the model after the initialization");
155
156   val = xbt_cfg_get_string(_sg_cfg_set, name);
157
158   if (!strcmp(val, "help")) {
159     model_help("optimization", surf_optimization_mode_description);
160     sg_cfg_exit_early();
161   }
162
163   /* New Module missing */
164   find_model_description(surf_optimization_mode_description, val);
165 }
166
167 /* callback of the cpu/model variable */
168 static void _sg_cfg_cb__storage_mode(const char *name, int pos)
169 {
170   char *val;
171
172   xbt_assert(_sg_cfg_init_status < 2,
173               "Cannot change the model after the initialization");
174
175   val = xbt_cfg_get_string(_sg_cfg_set, name);
176
177   if (!strcmp(val, "help")) {
178     model_help("storage", surf_storage_model_description);
179     sg_cfg_exit_early();
180   }
181
182   /* New Module missing */
183   find_model_description(surf_storage_model_description, val);
184 }
185
186 /* callback of the workstation_model variable */
187 static void _sg_cfg_cb__network_model(const char *name, int pos)
188 {
189   char *val;
190
191   xbt_assert(_sg_cfg_init_status < 2,
192               "Cannot change the model after the initialization");
193
194   val = xbt_cfg_get_string(_sg_cfg_set, name);
195
196   if (!strcmp(val, "help")) {
197     model_help("network", surf_network_model_description);
198     sg_cfg_exit_early();
199   }
200
201   /* New Module missing */
202   find_model_description(surf_network_model_description, val);
203 }
204
205 /* callbacks of the network models values */
206 static void _sg_cfg_cb__tcp_gamma(const char *name, int pos)
207 {
208   sg_tcp_gamma = xbt_cfg_get_double(_sg_cfg_set, name);
209 }
210
211 static void _sg_cfg_cb__maxmin_precision(const char* name, int pos)
212 {
213   sg_maxmin_precision = xbt_cfg_get_double(_sg_cfg_set, name);
214 }
215
216 static void _sg_cfg_cb__sender_gap(const char* name, int pos)
217 {
218   sg_sender_gap = xbt_cfg_get_double(_sg_cfg_set, name);
219 }
220
221 static void _sg_cfg_cb__latency_factor(const char *name, int pos)
222 {
223   sg_latency_factor = xbt_cfg_get_double(_sg_cfg_set, name);
224 }
225
226 static void _sg_cfg_cb__bandwidth_factor(const char *name, int pos)
227 {
228   sg_bandwidth_factor = xbt_cfg_get_double(_sg_cfg_set, name);
229 }
230
231 static void _sg_cfg_cb__weight_S(const char *name, int pos)
232 {
233   sg_weight_S_parameter = xbt_cfg_get_double(_sg_cfg_set, name);
234 }
235
236 #ifdef HAVE_SMPI
237 /* callback of the mpi collectives */
238 static void _sg_cfg_cb__coll(const char *category,
239                              s_mpi_coll_description_t * table,
240                              const char *name, int pos)
241 {
242   char *val;
243
244   xbt_assert(_sg_cfg_init_status < 2,
245               "Cannot change the model after the initialization");
246
247   val = xbt_cfg_get_string(_sg_cfg_set, name);
248
249   if (!strcmp(val, "help")) {
250     coll_help(category, table);
251     sg_cfg_exit_early();
252   }
253
254   /* New Module missing */
255   find_coll_description(table, val);
256 }
257 static void _sg_cfg_cb__coll_gather(const char *name, int pos){
258   _sg_cfg_cb__coll("gather", mpi_coll_gather_description, name, pos);
259 }
260 static void _sg_cfg_cb__coll_allgather(const char *name, int pos){
261   _sg_cfg_cb__coll("allgather", mpi_coll_allgather_description, name, pos);
262 }
263 static void _sg_cfg_cb__coll_allgatherv(const char *name, int pos){
264   _sg_cfg_cb__coll("allgatherv", mpi_coll_allgatherv_description, name, pos);
265 }
266 static void _sg_cfg_cb__coll_allreduce(const char *name, int pos)
267 {
268   _sg_cfg_cb__coll("allreduce", mpi_coll_allreduce_description, name, pos);
269 }
270 static void _sg_cfg_cb__coll_alltoall(const char *name, int pos)
271 {
272   _sg_cfg_cb__coll("alltoall", mpi_coll_alltoall_description, name, pos);
273 }
274 static void _sg_cfg_cb__coll_alltoallv(const char *name, int pos)
275 {
276   _sg_cfg_cb__coll("alltoallv", mpi_coll_alltoallv_description, name, pos);
277 }
278 static void _sg_cfg_cb__coll_bcast(const char *name, int pos)
279 {
280   _sg_cfg_cb__coll("bcast", mpi_coll_bcast_description, name, pos);
281 }
282 static void _sg_cfg_cb__coll_reduce(const char *name, int pos)
283 {
284   _sg_cfg_cb__coll("reduce", mpi_coll_reduce_description, name, pos);
285 }
286 static void _sg_cfg_cb__coll_reduce_scatter(const char *name, int pos){
287   _sg_cfg_cb__coll("reduce_scatter", mpi_coll_reduce_scatter_description, name, pos);
288 }
289 static void _sg_cfg_cb__coll_scatter(const char *name, int pos){
290   _sg_cfg_cb__coll("scatter", mpi_coll_scatter_description, name, pos);
291 }
292 static void _sg_cfg_cb__coll_barrier(const char *name, int pos){
293   _sg_cfg_cb__coll("barrier", mpi_coll_barrier_description, name, pos);
294 }
295 #endif
296
297 /* callback of the inclusion path */
298 static void _sg_cfg_cb__surf_path(const char *name, int pos)
299 {
300   char *path = xbt_cfg_get_string_at(_sg_cfg_set, name, pos);
301   xbt_dynar_push(surf_path, &path);
302 }
303
304 /* callback to decide if we want to use the model-checking */
305 #include "xbt_modinter.h"
306 #ifdef HAVE_MC
307 extern int _sg_do_model_check;   /* this variable lives in xbt_main until I find a right location for it */
308 #endif
309
310 static void _sg_cfg_cb_model_check(const char *name, int pos)
311 {
312 #ifdef HAVE_MC
313   _sg_do_model_check = xbt_cfg_get_boolean(_sg_cfg_set, name);
314 #else
315   if (xbt_cfg_get_boolean(_sg_cfg_set, name)) {
316     xbt_die("You tried to activate the model-checking from the command line, but it was not compiled in. Change your settings in cmake, recompile and try again");
317   }
318 #endif
319 }
320
321 extern int _sg_do_verbose_exit;
322
323 static void _sg_cfg_cb_verbose_exit(const char *name, int pos)
324 {
325   _sg_do_verbose_exit = xbt_cfg_get_boolean(_sg_cfg_set, name);
326 }
327
328 extern int _sg_do_clean_atexit;
329
330 static void _sg_cfg_cb_clean_atexit(const char *name, int pos)
331 {
332   _sg_do_clean_atexit = xbt_cfg_get_boolean(_sg_cfg_set, name);
333 }
334
335 static void _sg_cfg_cb_context_factory(const char *name, int pos)
336 {
337   smx_context_factory_name = xbt_cfg_get_string(_sg_cfg_set, name);
338 }
339
340 static void _sg_cfg_cb_context_stack_size(const char *name, int pos)
341 {
342   smx_context_stack_size_was_set = 1;
343   smx_context_stack_size = xbt_cfg_get_int(_sg_cfg_set, name) * 1024;
344 }
345
346 static void _sg_cfg_cb_contexts_nthreads(const char *name, int pos)
347 {
348   SIMIX_context_set_nthreads(xbt_cfg_get_int(_sg_cfg_set, name));
349 }
350
351 static void _sg_cfg_cb_contexts_parallel_threshold(const char *name, int pos)
352 {
353   SIMIX_context_set_parallel_threshold(xbt_cfg_get_int(_sg_cfg_set, name));
354 }
355
356 static void _sg_cfg_cb_contexts_parallel_mode(const char *name, int pos)
357 {
358   const char* mode_name = xbt_cfg_get_string(_sg_cfg_set, name);
359   if (!strcmp(mode_name, "posix")) {
360     SIMIX_context_set_parallel_mode(XBT_PARMAP_POSIX);
361   }
362   else if (!strcmp(mode_name, "futex")) {
363     SIMIX_context_set_parallel_mode(XBT_PARMAP_FUTEX);
364   }
365   else if (!strcmp(mode_name, "busy_wait")) {
366     SIMIX_context_set_parallel_mode(XBT_PARMAP_BUSY_WAIT);
367   }
368   else {
369     xbt_die("Command line setting of the parallel synchronization mode should "
370             "be one of \"posix\", \"futex\" or \"busy_wait\"");
371   }
372 }
373
374 static void _sg_cfg_cb__surf_network_coordinates(const char *name,
375                                                  int pos)
376 {
377   int val = xbt_cfg_get_boolean(_sg_cfg_set, name);
378   if (val) {
379     if (!COORD_HOST_LEVEL) {
380       COORD_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_dynar_free_voidp);
381       COORD_ASR_LEVEL  = xbt_lib_add_level(as_router_lib,xbt_dynar_free_voidp);
382     }
383   } else
384     if (COORD_HOST_LEVEL)
385       xbt_die("Setting of whether to use coordinate cannot be disabled once set.");
386 }
387
388 static void _sg_cfg_cb__surf_network_crosstraffic(const char *name,
389                                                   int pos)
390 {
391   sg_network_crosstraffic = xbt_cfg_get_boolean(_sg_cfg_set, name);
392 }
393
394 #ifdef HAVE_GTNETS
395 static void _sg_cfg_cb__gtnets_jitter(const char *name, int pos)
396 {
397   sg_gtnets_jitter = xbt_cfg_get_double(_sg_cfg_set, name);
398 }
399
400 static void _sg_cfg_cb__gtnets_jitter_seed(const char *name, int pos)
401 {
402   sg_gtnets_jitter_seed = xbt_cfg_get_int(_sg_cfg_set, name);
403 }
404 #endif
405
406 /* create the config set, register what should be and parse the command line*/
407 void sg_config_init(int *argc, char **argv)
408 {
409   char *description = xbt_malloc(1024);
410   char *p;
411   int i;
412
413   /* Create the configuration support */
414   if (_sg_cfg_init_status == 0) { /* Only create stuff if not already inited */
415     sprintf(description,
416             "The model to use for the CPU. Possible values: ");
417     p = description;
418     while (*(++p) != '\0');
419     for (i = 0; surf_cpu_model_description[i].name; i++)
420       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
421                    surf_cpu_model_description[i].name);
422     sprintf(p,
423             ".\n       (use 'help' as a value to see the long description of each model)");
424     xbt_cfg_register(&_sg_cfg_set, "cpu/model", description,
425                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__cpu_model, NULL);
426     xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/model", "Cas01");
427
428     while (*(++p) != '\0');
429     for (i = 0; surf_optimization_mode_description[i].name; i++)
430       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
431                    surf_optimization_mode_description[i].name);
432     sprintf(p,
433             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
434     xbt_cfg_register(&_sg_cfg_set, "cpu/optim", description,
435                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
436     xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/optim", "Lazy");
437
438     sprintf(description,
439             "The model to use for the storage. Possible values: ");
440     p = description;
441     while (*(++p) != '\0');
442     for (i = 0; surf_storage_model_description[i].name; i++)
443       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
444                    surf_storage_model_description[i].name);
445     sprintf(p,
446             ".\n       (use 'help' as a value to see the long description of each model)");
447     xbt_cfg_register(&_sg_cfg_set, "storage/model", description,
448                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
449     xbt_cfg_setdefault_string(_sg_cfg_set, "storage/model", "default");
450
451     /* ********************************************************************* */
452     /* TUTORIAL: New model                                                   */
453     sprintf(description,
454             "The model to use for the New model. Possible values: ");
455     p = description;
456     while (*(++p) != '\0');
457     for (i = 0; surf_new_model_description[i].name; i++)
458       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
459                    surf_new_model_description[i].name);
460     sprintf(p,
461             ".\n       (use 'help' as a value to see the long description of each model)");
462     xbt_cfg_register(&_sg_cfg_set, "new_model/model", description,
463                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
464     xbt_cfg_setdefault_string(_sg_cfg_set, "new_model/model", "default");
465     /* ********************************************************************* */
466
467     sprintf(description,
468             "The model to use for the network. Possible values: ");
469     p = description;
470     while (*(++p) != '\0');
471     for (i = 0; surf_network_model_description[i].name; i++)
472       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
473                    surf_network_model_description[i].name);
474     sprintf(p,
475             ".\n       (use 'help' as a value to see the long description of each model)");
476     xbt_cfg_register(&_sg_cfg_set, "network/model", description,
477                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__network_model, NULL);
478     xbt_cfg_setdefault_string(_sg_cfg_set, "network/model", "LV08");
479
480     sprintf(description,
481             "The optimization modes to use for the network. Possible values: ");
482     p = description;
483     while (*(++p) != '\0');
484     for (i = 0; surf_optimization_mode_description[i].name; i++)
485       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
486                    surf_optimization_mode_description[i].name);
487     sprintf(p,
488             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
489     xbt_cfg_register(&_sg_cfg_set, "network/optim", description,
490                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
491     xbt_cfg_setdefault_string(_sg_cfg_set, "network/optim", "Lazy");
492
493     sprintf(description,
494             "The model to use for the workstation. Possible values: ");
495     p = description;
496     while (*(++p) != '\0');
497     for (i = 0; surf_workstation_model_description[i].name; i++)
498       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
499                    surf_workstation_model_description[i].name);
500     sprintf(p,
501             ".\n       (use 'help' as a value to see the long description of each model)");
502     xbt_cfg_register(&_sg_cfg_set, "workstation/model", description,
503                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__workstation_model, NULL);
504     xbt_cfg_setdefault_string(_sg_cfg_set, "workstation/model", "default");
505
506     xbt_cfg_register(&_sg_cfg_set, "network/TCP_gamma",
507                      "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)",
508                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__tcp_gamma, NULL);
509     xbt_cfg_setdefault_double(_sg_cfg_set, "network/TCP_gamma", 4194304.0);
510
511     xbt_cfg_register(&_sg_cfg_set, "maxmin/precision",
512                      "Numerical precision used when updating simulation models (epsilon in double comparisons)",
513                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__maxmin_precision, NULL);
514     xbt_cfg_setdefault_double(_sg_cfg_set, "maxmin/precision", 0.00001);
515
516     /* The parameters of network models */
517
518     xbt_cfg_register(&_sg_cfg_set, "network/sender_gap",
519                      "Minimum gap between two overlapping sends",
520                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__sender_gap, NULL);
521     /* default for "network/sender_gap" is set in network.c */
522
523     xbt_cfg_register(&_sg_cfg_set, "network/latency_factor",
524                      "Correction factor to apply to the provided latency (default value set by network model)",
525                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__latency_factor, NULL);
526     xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 1.0);
527
528     xbt_cfg_register(&_sg_cfg_set, "network/bandwidth_factor",
529                      "Correction factor to apply to the provided bandwidth (default value set by network model)",
530                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__bandwidth_factor, NULL);
531     xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", 1.0);
532
533     xbt_cfg_register(&_sg_cfg_set, "network/weight_S",
534                      "Correction factor to apply to the weight of competing streams (default value set by network model)",
535                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__weight_S, NULL);
536     /* default for "network/weight_S" is set in network.c */
537
538     /* Inclusion path */
539     xbt_cfg_register(&_sg_cfg_set, "path",
540                      "Lookup path for inclusions in platform and deployment XML files",
541                      xbt_cfgelm_string, 0, 0, _sg_cfg_cb__surf_path, NULL);
542
543     xbt_cfg_register(&_sg_cfg_set, "cpu/maxmin_selective_update",
544                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
545                      xbt_cfgelm_boolean, 0, 1, NULL, NULL);
546     xbt_cfg_setdefault_boolean(_sg_cfg_set, "cpu/maxmin_selective_update", "no");
547
548     xbt_cfg_register(&_sg_cfg_set, "network/maxmin_selective_update",
549                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
550                      xbt_cfgelm_boolean, 0, 1, NULL, NULL);
551     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/maxmin_selective_update", "no");
552
553 #ifdef HAVE_MC
554     /* do model-checking */
555     xbt_cfg_register(&_sg_cfg_set, "model-check",
556                      "Verify the system through model-checking instead of simulating it (EXPERIMENTAL)",
557                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_model_check, NULL);
558     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", "no");
559
560     /* do stateful model-checking */
561     xbt_cfg_register(&_sg_cfg_set, "model-check/checkpoint",
562                      "Specify the amount of steps between checkpoints during stateful model-checking (default: 0 => stateless verification). "
563                      "If value=on, one checkpoint is saved for each step => faster verification, but huge memory consumption; higher values are good compromises between speed and memory consumption.",
564                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_checkpoint, NULL);
565     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0);
566
567     /* do liveness model-checking */
568     xbt_cfg_register(&_sg_cfg_set, "model-check/property",
569                      "Specify the name of the file containing the property. It must be the result of the ltl2ba program.",
570                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_property, NULL);
571     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/property", "");
572
573     /* Specify the kind of model-checking reduction */
574     xbt_cfg_register(&_sg_cfg_set, "model-check/reduction",
575                      "Specify the kind of exploration reduction (either none or DPOR)",
576                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_reduce, NULL);
577     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/reduction", "dpor");
578
579     /* Enable/disable timeout for wait requests with model-checking */
580     xbt_cfg_register(&_sg_cfg_set, "model-check/timeout",
581                      "Enable/Disable timeout for wait requests",
582                      xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_timeout, NULL);
583     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", "no");
584
585     /* Set max depth exploration */
586     xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
587                      "Specify the max depth of exploration (default : 1000)",
588                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_max_depth, NULL);
589     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/max_depth", 1000);
590
591     /* Set number of visited state stored for state comparison reduction*/
592     xbt_cfg_register(&_sg_cfg_set, "model-check/visited",
593                      "Specify the number of visited state stored for state comparison reduction. If value=5, the last 5 visited states are stored",
594                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_visited, NULL);
595     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
596
597     /* Set file name for dot output of graph state */
598     xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
599                      "Specify the name of dot file corresponding to graph state",
600                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_dot_output, NULL);
601     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
602 #endif
603
604     /* do verbose-exit */
605     xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
606                      "Activate the \"do nothing\" mode in Ctrl-C",
607                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_verbose_exit, NULL);
608     xbt_cfg_setdefault_boolean(_sg_cfg_set, "verbose-exit", "yes");
609
610     /* context factory */
611     sprintf(description,
612             "Context factory to use in SIMIX. Possible values: thread");
613     const char *dflt_ctx_fact = "thread";
614 #ifdef CONTEXT_UCONTEXT
615     strcat(description, ", ucontext");
616     dflt_ctx_fact = "ucontext";
617 #endif
618 #ifdef HAVE_RAWCTX
619     strcat(description, ", raw");
620     dflt_ctx_fact = "raw";
621 #endif
622     strcat(description, ".");
623     xbt_cfg_register(&_sg_cfg_set, "contexts/factory", description,
624                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_context_factory, NULL);
625     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/factory", dflt_ctx_fact);
626
627     /* stack size of contexts in Ko */
628     xbt_cfg_register(&_sg_cfg_set, "contexts/stack_size",
629                      "Stack size of contexts in Kib",
630                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_stack_size, NULL);
631     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/stack_size", 128);
632
633     /* number of parallel threads for user processes */
634     xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
635                      "Number of parallel threads used to execute user contexts",
636                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_nthreads, NULL);
637     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/nthreads", 1);
638
639     /* minimal number of user contexts to be run in parallel */
640     xbt_cfg_register(&_sg_cfg_set, "contexts/parallel_threshold",
641                      "Minimal number of user contexts to be run in parallel (raw contexts only)",
642                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_parallel_threshold, NULL);
643     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/parallel_threshold", 2);
644
645     /* synchronization mode for parallel user contexts */
646     xbt_cfg_register(&_sg_cfg_set, "contexts/synchro",
647                      "Synchronization mode to use when running contexts in parallel (either futex, posix or busy_wait)",
648                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_contexts_parallel_mode, NULL);
649 #ifdef HAVE_FUTEX_H
650     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "futex");
651 #else //No futex on mac and posix is unimplememted yet
652     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "busy_wait");
653 #endif
654
655     xbt_cfg_register(&_sg_cfg_set, "network/coordinates",
656                      "\"yes\" or \"no\", specifying whether we use a coordinate-based routing (as Vivaldi)",
657                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb__surf_network_coordinates, NULL);
658     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", "no");
659
660     xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic",
661                      "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
662                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL);
663     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "no");
664
665 #ifdef HAVE_GTNETS
666     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter",
667                      "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)",
668                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__gtnets_jitter, NULL);
669     xbt_cfg_setdefault_double(_sg_cfg_set, "gtnets/jitter", 0.0);
670
671     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter_seed",
672                      "Use a positive seed to reproduce jitted results, value must be in [1,1e8], default is 10",
673                      xbt_cfgelm_int, 0, 1, _sg_cfg_cb__gtnets_jitter_seed, NULL);
674     xbt_cfg_setdefault_int(_sg_cfg_set, "gtnets/jitter_seed", 10);
675 #endif
676 #ifdef HAVE_NS3
677     xbt_cfg_register(&_sg_cfg_set, "ns3/TcpModel",
678                      "The ns3 tcp model can be : NewReno or Reno or Tahoe",
679                      xbt_cfgelm_string, 1, 1, NULL, NULL);
680     xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
681 #endif
682
683 #ifdef HAVE_SMPI
684     xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
685                      "Power of the host running the simulation (in flop/s). Used to bench the operations.",
686                      xbt_cfgelm_double, 1, 1, NULL, NULL);
687     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/running_power", 20000.0);
688
689     xbt_cfg_register(&_sg_cfg_set, "smpi/display_timing",
690                      "Boolean indicating whether we should display the timing after simulation.",
691                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
692     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", "no");
693
694     xbt_cfg_register(&_sg_cfg_set, "smpi/use_shared_malloc",
695                      "Boolean indicating whether we should use shared memory when using SMPI_SHARED_MALLOC. Allows user to disable it for debug purposes.",
696                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
697     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/use_shared_malloc", "yes");
698
699     xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold",
700                      "Minimal computation time (in seconds) not discarded.",
701                      xbt_cfgelm_double, 1, 1, NULL, NULL);
702     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/cpu_threshold", 1e-6);
703
704     xbt_cfg_register(&_sg_cfg_set, "smpi/async_small_thres",
705                      "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
706                      xbt_cfgelm_int, 1, 1, NULL, NULL);
707     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/async_small_thres", 0);
708
709     xbt_cfg_register(&_sg_cfg_set, "smpi/send_is_detached_thres",
710                      "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend",
711                      xbt_cfgelm_int, 1, 1, NULL, NULL);
712     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/send_is_detached_thres", 65536);
713
714     //For smpi/bw_factor and smpi/lat_factor
715     //Default value have to be "threshold0:value0;threshold1:value1;...;thresholdN:valueN"
716     //test is if( size >= thresholdN ) return valueN;
717     //Values can be modified with command line --cfg=smpi/bw_factor:"threshold0:value0;threshold1:value1;...;thresholdN:valueN"
718     //  or with tag config put line <prop id="smpi/bw_factor" value="threshold0:value0;threshold1:value1;...;thresholdN:valueN"></prop>
719     xbt_cfg_register(&_sg_cfg_set, "smpi/bw_factor",
720                      "Bandwidth factors for smpi.",
721                      xbt_cfgelm_string, 1, 1, NULL, NULL);
722     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/bw_factor", "65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493;1426:0.608902;732:0.341987;257:0.338112;0:0.812084");
723
724     xbt_cfg_register(&_sg_cfg_set, "smpi/lat_factor",
725                      "Latency factors for smpi.",
726                      xbt_cfgelm_string, 1, 1, NULL, NULL);
727     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/lat_factor", "65472:11.6436;15424:3.48845;9376:2.59299;5776:2.18796;3484:1.88101;1426:1.61075;732:1.9503;257:1.95341;0:2.01467");
728
729     xbt_cfg_register(&_sg_cfg_set, "smpi/os",
730                      "Small messages timings (MPI_Send minimum time for small messages)",
731                      xbt_cfgelm_string, 1, 1, NULL, NULL);
732     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/os", "1:0:0:0:0");
733
734     xbt_cfg_register(&_sg_cfg_set, "smpi/ois",
735                      "Small messages timings (MPI_Isend minimum time for small messages)",
736                      xbt_cfgelm_string, 1, 1, NULL, NULL);
737     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/ois", "1:0:0:0:0");
738
739     xbt_cfg_register(&_sg_cfg_set, "smpi/or",
740                      "Small messages timings (MPI_Recv minimum time for small messages)",
741                      xbt_cfgelm_string, 1, 1, NULL, NULL);
742     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
743     xbt_cfg_register(&_sg_cfg_set, "smpi/iprobe",
744                      "Minimum time to inject inside a call to MPI_Iprobe",
745                      xbt_cfgelm_double, 1, 1, NULL, NULL);
746     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/iprobe", 1e-4);
747     xbt_cfg_register(&_sg_cfg_set, "smpi/coll_selector",
748                      "Which collective selector to use",
749                      xbt_cfgelm_string, 1, 1, NULL, NULL);
750     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/coll_selector", "default");
751
752     xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
753                      "Which collective to use for gather",
754                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_gather, NULL);
755
756     xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
757                      "Which collective to use for allgather",
758                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgather, NULL);
759
760     xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
761                      "Which collective to use for barrier",
762                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_barrier, NULL);
763
764     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
765                      "Which collective to use for reduce_scatter",
766                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce_scatter, NULL);
767
768     xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
769                      "Which collective to use for scatter",
770                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_scatter, NULL);
771
772     xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
773                      "Which collective to use for allgatherv",
774                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgatherv, NULL);
775
776     xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
777                      "Which collective to use for allreduce",
778                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allreduce, NULL);
779
780     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
781                      "Which collective to use for alltoall",
782                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoall, NULL);
783
784     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
785                      "Which collective to use for alltoallv",
786                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoallv, NULL);
787
788     xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
789                      "Which collective to use for bcast",
790                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_bcast, NULL);
791
792     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
793                      "Which collective to use for reduce",
794                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce, NULL);
795 #endif // HAVE_SMPI
796
797     xbt_cfg_register(&_sg_cfg_set, "clean_atexit",
798                      "\"yes\" or \"no\". \"yes\" enables all the cleanups of SimGrid (XBT,SIMIX,MSG) to be registered with atexit. \"no\" may be useful if your code segfaults when calling the exit function.",
799                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_clean_atexit, NULL);
800     xbt_cfg_setdefault_boolean(_sg_cfg_set, "clean_atexit", "yes");
801
802     if (!surf_path) {
803       /* retrieves the current directory of the current process */
804       const char *initial_path = __surf_get_initial_path();
805       xbt_assert((initial_path),
806                   "__surf_get_initial_path() failed! Can't resolves current Windows directory");
807
808       surf_path = xbt_dynar_new(sizeof(char *), NULL);
809       xbt_cfg_setdefault_string(_sg_cfg_set, "path", initial_path);
810     }
811
812     _sg_cfg_init_status = 1;
813
814     sg_config_cmd_line(argc, argv);
815
816     xbt_mallocator_initialization_is_done(SIMIX_context_is_parallel());
817
818   } else {
819     XBT_WARN("Call to sg_config_init() after initialization ignored");
820   }
821
822   xbt_free(description);
823 }
824
825 void sg_config_finalize(void)
826 {
827   if (!_sg_cfg_init_status)
828     return;                     /* Not initialized yet. Nothing to do */
829
830   xbt_cfg_free(&_sg_cfg_set);
831   _sg_cfg_init_status = 0;
832 }
833
834 /* Pick the right models for CPU, net and workstation, and call their model_init_preparse */
835 void surf_config_models_setup()
836 {
837   const char *workstation_model_name;
838   int workstation_id = -1;
839   char *network_model_name = NULL;
840   char *cpu_model_name = NULL;
841   int storage_id = -1;
842   char *storage_model_name = NULL;
843
844   workstation_model_name =
845       xbt_cfg_get_string(_sg_cfg_set, "workstation/model");
846   network_model_name = xbt_cfg_get_string(_sg_cfg_set, "network/model");
847   cpu_model_name = xbt_cfg_get_string(_sg_cfg_set, "cpu/model");
848   storage_model_name = xbt_cfg_get_string(_sg_cfg_set, "storage/model");
849
850   /* Check whether we use a net/cpu model differing from the default ones, in which case
851    * we should switch to the "compound" workstation model to correctly dispatch stuff to
852    * the right net/cpu models.
853    */
854
855   if ((!xbt_cfg_is_default_value(_sg_cfg_set, "network/model") ||
856        !xbt_cfg_is_default_value(_sg_cfg_set, "cpu/model")) &&
857       xbt_cfg_is_default_value(_sg_cfg_set, "workstation/model")) {
858     XBT_INFO("Switching workstation model to compound since you changed the network and/or cpu model(s)");
859     workstation_model_name = "compound";
860     xbt_cfg_set_string(_sg_cfg_set, "workstation/model", workstation_model_name);
861   }
862
863   XBT_DEBUG("Workstation model: %s", workstation_model_name);
864   workstation_id =
865       find_model_description(surf_workstation_model_description,
866                              workstation_model_name);
867   if (!strcmp(workstation_model_name, "compound")) {
868     int network_id = -1;
869     int cpu_id = -1;
870
871     xbt_assert(cpu_model_name,
872                 "Set a cpu model to use with the 'compound' workstation model");
873
874     xbt_assert(network_model_name,
875                 "Set a network model to use with the 'compound' workstation model");
876
877     network_id =
878         find_model_description(surf_network_model_description,
879                                network_model_name);
880     cpu_id =
881         find_model_description(surf_cpu_model_description, cpu_model_name);
882
883     surf_cpu_model_description[cpu_id].model_init_preparse();
884     surf_network_model_description[network_id].model_init_preparse();
885   }
886
887   XBT_DEBUG("Call workstation_model_init");
888   surf_workstation_model_description[workstation_id].model_init_preparse();
889
890   XBT_DEBUG("Call vm_workstation_model_init");
891   surf_vm_workstation_model_init();
892
893   XBT_DEBUG("Call storage_model_init");
894   storage_id = find_model_description(surf_storage_model_description, storage_model_name);
895   surf_storage_model_description[storage_id].model_init_preparse();
896
897   /* ********************************************************************* */
898   /* TUTORIAL: New model                                                   */
899   int new_model_id = -1;
900   char *new_model_name = NULL;
901   new_model_name = xbt_cfg_get_string(_sg_cfg_set, "new_model/model");
902   XBT_DEBUG("Call new model_init");
903   new_model_id = find_model_description(surf_new_model_description, new_model_name);
904   surf_new_model_description[new_model_id].model_init_preparse();
905   /* ********************************************************************* */
906 }
907
908 int sg_cfg_get_int(const char* name)
909 {
910   return xbt_cfg_get_int(_sg_cfg_set,name);
911 }
912
913 double sg_cfg_get_double(const char* name)
914 {
915   return xbt_cfg_get_double(_sg_cfg_set,name);
916 }
917
918 char* sg_cfg_get_string(const char* name)
919 {
920   return xbt_cfg_get_string(_sg_cfg_set,name);
921 }
922
923 int sg_cfg_get_boolean(const char* name)
924 {
925   return xbt_cfg_get_boolean(_sg_cfg_set,name);
926 }
927
928 void sg_cfg_get_peer(const char *name, char **peer, int *port)
929 {
930   xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
931 }
932
933 xbt_dynar_t sg_cfg_get_dynar(const char* name)
934 {
935   return xbt_cfg_get_dynar(_sg_cfg_set,name);
936 }