Logo AND Algorithmique Numérique Distribuée

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