Logo AND Algorithmique Numérique Distribuée

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