Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : minor fix
[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     /* Set max depth exploration */
596     xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
597                      "Specify the max depth of exploration (default : 1000)",
598                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_max_depth, NULL);
599     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/max_depth", 1000);
600
601     /* Set number of visited state stored for state comparison reduction*/
602     xbt_cfg_register(&_sg_cfg_set, "model-check/visited",
603                      "Specify the number of visited state stored for state comparison reduction. If value=5, the last 5 visited states are stored",
604                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_visited, NULL);
605     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
606
607     /* Set file name for dot output of graph state */
608     xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
609                      "Specify the name of dot file corresponding to graph state",
610                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_dot_output, NULL);
611     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
612 #endif
613
614     /* do verbose-exit */
615     xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
616                      "Activate the \"do nothing\" mode in Ctrl-C",
617                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_verbose_exit, NULL);
618     xbt_cfg_setdefault_boolean(_sg_cfg_set, "verbose-exit", "yes");
619
620     /* context factory */
621     sprintf(description,
622             "Context factory to use in SIMIX. Possible values: thread");
623     const char *dflt_ctx_fact = "thread";
624 #ifdef CONTEXT_UCONTEXT
625     dflt_ctx_fact = "ucontext";
626     strcat(strcat(description, ", "), dflt_ctx_fact);
627 #endif
628 #ifdef HAVE_RAWCTX
629     dflt_ctx_fact = "raw";
630     strcat(strcat(description, ", "), dflt_ctx_fact);
631 #endif
632     strcat(description, ".");
633     xbt_cfg_register(&_sg_cfg_set, "contexts/factory", description,
634                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_context_factory, NULL);
635     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/factory", dflt_ctx_fact);
636
637     /* stack size of contexts in Ko */
638     xbt_cfg_register(&_sg_cfg_set, "contexts/stack_size",
639                      "Stack size of contexts in Kib",
640                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_stack_size, NULL);
641     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/stack_size", 128);
642     /* No, it was not set yet (the above setdefault() changed this to 1). */
643     smx_context_stack_size_was_set = 0;
644
645     /* number of parallel threads for user processes */
646     xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
647                      "Number of parallel threads used to execute user contexts",
648                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_nthreads, NULL);
649     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/nthreads", 1);
650
651     /* minimal number of user contexts to be run in parallel */
652     xbt_cfg_register(&_sg_cfg_set, "contexts/parallel_threshold",
653                      "Minimal number of user contexts to be run in parallel (raw contexts only)",
654                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_parallel_threshold, NULL);
655     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/parallel_threshold", 2);
656
657     /* synchronization mode for parallel user contexts */
658     xbt_cfg_register(&_sg_cfg_set, "contexts/synchro",
659                      "Synchronization mode to use when running contexts in parallel (either futex, posix or busy_wait)",
660                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_contexts_parallel_mode, NULL);
661 #ifdef HAVE_FUTEX_H
662     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "futex");
663 #else //No futex on mac and posix is unimplememted yet
664     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "busy_wait");
665 #endif
666
667     xbt_cfg_register(&_sg_cfg_set, "network/coordinates",
668                      "\"yes\" or \"no\", specifying whether we use a coordinate-based routing (as Vivaldi)",
669                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb__surf_network_coordinates, NULL);
670     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", "no");
671
672     xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic",
673                      "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
674                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL);
675     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "no");
676
677 #ifdef HAVE_GTNETS
678     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter",
679                      "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)",
680                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__gtnets_jitter, NULL);
681     xbt_cfg_setdefault_double(_sg_cfg_set, "gtnets/jitter", 0.0);
682
683     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter_seed",
684                      "Use a positive seed to reproduce jitted results, value must be in [1,1e8], default is 10",
685                      xbt_cfgelm_int, 0, 1, _sg_cfg_cb__gtnets_jitter_seed, NULL);
686     xbt_cfg_setdefault_int(_sg_cfg_set, "gtnets/jitter_seed", 10);
687 #endif
688 #ifdef HAVE_NS3
689     xbt_cfg_register(&_sg_cfg_set, "ns3/TcpModel",
690                      "The ns3 tcp model can be : NewReno or Reno or Tahoe",
691                      xbt_cfgelm_string, 1, 1, NULL, NULL);
692     xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
693 #endif
694
695 #ifdef HAVE_SMPI
696     xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
697                      "Power of the host running the simulation (in flop/s). Used to bench the operations.",
698                      xbt_cfgelm_double, 1, 1, NULL, NULL);
699     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/running_power", 20000.0);
700
701     xbt_cfg_register(&_sg_cfg_set, "smpi/display_timing",
702                      "Boolean indicating whether we should display the timing after simulation.",
703                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
704     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", "no");
705
706     xbt_cfg_register(&_sg_cfg_set, "smpi/use_shared_malloc",
707                      "Boolean indicating whether we should use shared memory when using SMPI_SHARED_MALLOC. Allows user to disable it for debug purposes.",
708                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
709     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/use_shared_malloc", "yes");
710
711     xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold",
712                      "Minimal computation time (in seconds) not discarded, or -1 for infinity.",
713                      xbt_cfgelm_double, 1, 1, NULL, NULL);
714     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/cpu_threshold", 1e-6);
715
716     xbt_cfg_register(&_sg_cfg_set, "smpi/async_small_thres",
717                      "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
718                      xbt_cfgelm_int, 1, 1, NULL, NULL);
719     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/async_small_thres", 0);
720
721     xbt_cfg_register(&_sg_cfg_set, "smpi/send_is_detached_thres",
722                      "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend",
723                      xbt_cfgelm_int, 1, 1, NULL, NULL);
724     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/send_is_detached_thres", 65536);
725
726     //For smpi/bw_factor and smpi/lat_factor
727     //Default value have to be "threshold0:value0;threshold1:value1;...;thresholdN:valueN"
728     //test is if( size >= thresholdN ) return valueN;
729     //Values can be modified with command line --cfg=smpi/bw_factor:"threshold0:value0;threshold1:value1;...;thresholdN:valueN"
730     //  or with tag config put line <prop id="smpi/bw_factor" value="threshold0:value0;threshold1:value1;...;thresholdN:valueN"></prop>
731     xbt_cfg_register(&_sg_cfg_set, "smpi/bw_factor",
732                      "Bandwidth factors for smpi.",
733                      xbt_cfgelm_string, 1, 1, NULL, NULL);
734     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");
735
736     xbt_cfg_register(&_sg_cfg_set, "smpi/lat_factor",
737                      "Latency factors for smpi.",
738                      xbt_cfgelm_string, 1, 1, NULL, NULL);
739     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");
740
741     xbt_cfg_register(&_sg_cfg_set, "smpi/os",
742                      "Small messages timings (MPI_Send minimum time for small messages)",
743                      xbt_cfgelm_string, 1, 1, NULL, NULL);
744     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/os", "1:0:0:0:0");
745
746     xbt_cfg_register(&_sg_cfg_set, "smpi/ois",
747                      "Small messages timings (MPI_Isend minimum time for small messages)",
748                      xbt_cfgelm_string, 1, 1, NULL, NULL);
749     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/ois", "1:0:0:0:0");
750
751     xbt_cfg_register(&_sg_cfg_set, "smpi/or",
752                      "Small messages timings (MPI_Recv minimum time for small messages)",
753                      xbt_cfgelm_string, 1, 1, NULL, NULL);
754     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
755     xbt_cfg_register(&_sg_cfg_set, "smpi/iprobe",
756                      "Minimum time to inject inside a call to MPI_Iprobe",
757                      xbt_cfgelm_double, 1, 1, NULL, NULL);
758     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/iprobe", 1e-4);
759     xbt_cfg_register(&_sg_cfg_set, "smpi/coll_selector",
760                      "Which collective selector to use",
761                      xbt_cfgelm_string, 1, 1, NULL, NULL);
762     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/coll_selector", "default");
763
764     xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
765                      "Which collective to use for gather",
766                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_gather, NULL);
767
768     xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
769                      "Which collective to use for allgather",
770                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgather, NULL);
771
772     xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
773                      "Which collective to use for barrier",
774                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_barrier, NULL);
775
776     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
777                      "Which collective to use for reduce_scatter",
778                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce_scatter, NULL);
779
780     xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
781                      "Which collective to use for scatter",
782                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_scatter, NULL);
783
784     xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
785                      "Which collective to use for allgatherv",
786                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgatherv, NULL);
787
788     xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
789                      "Which collective to use for allreduce",
790                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allreduce, NULL);
791
792     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
793                      "Which collective to use for alltoall",
794                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoall, NULL);
795
796     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
797                      "Which collective to use for alltoallv",
798                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoallv, NULL);
799
800     xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
801                      "Which collective to use for bcast",
802                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_bcast, NULL);
803
804     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
805                      "Which collective to use for reduce",
806                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce, NULL);
807 #endif // HAVE_SMPI
808
809     xbt_cfg_register(&_sg_cfg_set, "clean_atexit",
810                      "\"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.",
811                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_clean_atexit, NULL);
812     xbt_cfg_setdefault_boolean(_sg_cfg_set, "clean_atexit", "yes");
813
814     if (!surf_path) {
815       /* retrieves the current directory of the current process */
816       const char *initial_path = __surf_get_initial_path();
817       xbt_assert((initial_path),
818                   "__surf_get_initial_path() failed! Can't resolves current Windows directory");
819
820       surf_path = xbt_dynar_new(sizeof(char *), NULL);
821       xbt_cfg_setdefault_string(_sg_cfg_set, "path", initial_path);
822     }
823
824     _sg_cfg_init_status = 1;
825
826     sg_config_cmd_line(argc, argv);
827
828     xbt_mallocator_initialization_is_done(SIMIX_context_is_parallel());
829
830   } else {
831     XBT_WARN("Call to sg_config_init() after initialization ignored");
832   }
833
834   xbt_free(description);
835 }
836
837 void sg_config_finalize(void)
838 {
839   if (!_sg_cfg_init_status)
840     return;                     /* Not initialized yet. Nothing to do */
841
842   xbt_cfg_free(&_sg_cfg_set);
843   _sg_cfg_init_status = 0;
844 }
845
846 /* Pick the right models for CPU, net and workstation, and call their model_init_preparse */
847 void surf_config_models_setup()
848 {
849   const char *workstation_model_name;
850   int workstation_id = -1;
851   char *network_model_name = NULL;
852   char *cpu_model_name = NULL;
853   int storage_id = -1;
854   char *storage_model_name = NULL;
855
856   workstation_model_name =
857       xbt_cfg_get_string(_sg_cfg_set, "workstation/model");
858   network_model_name = xbt_cfg_get_string(_sg_cfg_set, "network/model");
859   cpu_model_name = xbt_cfg_get_string(_sg_cfg_set, "cpu/model");
860   storage_model_name = xbt_cfg_get_string(_sg_cfg_set, "storage/model");
861
862   /* Check whether we use a net/cpu model differing from the default ones, in which case
863    * we should switch to the "compound" workstation model to correctly dispatch stuff to
864    * the right net/cpu models.
865    */
866
867   if ((!xbt_cfg_is_default_value(_sg_cfg_set, "network/model") ||
868        !xbt_cfg_is_default_value(_sg_cfg_set, "cpu/model")) &&
869       xbt_cfg_is_default_value(_sg_cfg_set, "workstation/model")) {
870     XBT_INFO("Switching workstation model to compound since you changed the network and/or cpu model(s)");
871     workstation_model_name = "compound";
872     xbt_cfg_set_string(_sg_cfg_set, "workstation/model", workstation_model_name);
873   }
874
875   XBT_DEBUG("Workstation model: %s", workstation_model_name);
876   workstation_id =
877       find_model_description(surf_workstation_model_description,
878                              workstation_model_name);
879   if (!strcmp(workstation_model_name, "compound")) {
880     int network_id = -1;
881     int cpu_id = -1;
882
883     xbt_assert(cpu_model_name,
884                 "Set a cpu model to use with the 'compound' workstation model");
885
886     xbt_assert(network_model_name,
887                 "Set a network model to use with the 'compound' workstation model");
888
889     network_id =
890         find_model_description(surf_network_model_description,
891                                network_model_name);
892     cpu_id =
893         find_model_description(surf_cpu_model_description, cpu_model_name);
894
895     surf_cpu_model_description[cpu_id].model_init_preparse();
896     surf_network_model_description[network_id].model_init_preparse();
897   }
898
899   XBT_DEBUG("Call workstation_model_init");
900   surf_workstation_model_description[workstation_id].model_init_preparse();
901
902   XBT_DEBUG("Call storage_model_init");
903   storage_id = find_model_description(surf_storage_model_description, storage_model_name);
904   surf_storage_model_description[storage_id].model_init_preparse();
905
906   /* ********************************************************************* */
907   /* TUTORIAL: New model                                                   */
908   int new_model_id = -1;
909   char *new_model_name = NULL;
910   new_model_name = xbt_cfg_get_string(_sg_cfg_set, "new_model/model");
911   XBT_DEBUG("Call new model_init");
912   new_model_id = find_model_description(surf_new_model_description, new_model_name);
913   surf_new_model_description[new_model_id].model_init_preparse();
914   /* ********************************************************************* */
915 }
916
917 int sg_cfg_get_int(const char* name)
918 {
919   return xbt_cfg_get_int(_sg_cfg_set,name);
920 }
921
922 double sg_cfg_get_double(const char* name)
923 {
924   return xbt_cfg_get_double(_sg_cfg_set,name);
925 }
926
927 char* sg_cfg_get_string(const char* name)
928 {
929   return xbt_cfg_get_string(_sg_cfg_set,name);
930 }
931
932 int sg_cfg_get_boolean(const char* name)
933 {
934   return xbt_cfg_get_boolean(_sg_cfg_set,name);
935 }
936
937 void sg_cfg_get_peer(const char *name, char **peer, int *port)
938 {
939   xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
940 }
941
942 xbt_dynar_t sg_cfg_get_dynar(const char* name)
943 {
944   return xbt_cfg_get_dynar(_sg_cfg_set,name);
945 }