Logo AND Algorithmique Numérique Distribuée

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