Logo AND Algorithmique Numérique Distribuée

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