Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
attempt to make valgrind happier
[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 extern int _sg_do_clean_atexit;
322
323 static void _sg_cfg_cb_clean_atexit(const char *name, int pos)
324 {
325   _sg_do_clean_atexit = xbt_cfg_get_boolean(_sg_cfg_set, name);
326 }
327
328 static void _sg_cfg_cb_context_factory(const char *name, int pos) {
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   char *default_value;
403   double double_default_value;
404   int default_value_int;
405   int i;
406
407   /* Create the configuration support */
408   if (_sg_init_status == 0) { /* Only create stuff if not already inited */
409     sprintf(description,
410             "The model to use for the CPU. Possible values: ");
411     p = description;
412     while (*(++p) != '\0');
413     for (i = 0; surf_cpu_model_description[i].name; i++)
414       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
415                    surf_cpu_model_description[i].name);
416     sprintf(p,
417             ".\n       (use 'help' as a value to see the long description of each model)");
418     default_value = xbt_strdup("Cas01");
419     xbt_cfg_register(&_sg_cfg_set, "cpu/model", description, xbt_cfgelm_string,
420                      &default_value, 1, 1, &_sg_cfg_cb__cpu_model, NULL);
421
422     sprintf(description,
423             "The optimization modes to use for the CPU. Possible values: ");
424     p = description;
425     while (*(++p) != '\0');
426     for (i = 0; surf_optimization_mode_description[i].name; i++)
427       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
428                    surf_optimization_mode_description[i].name);
429     sprintf(p,
430             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
431     default_value = xbt_strdup("Lazy");
432     xbt_cfg_register(&_sg_cfg_set, "cpu/optim", description, xbt_cfgelm_string,
433                      &default_value, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
434
435     sprintf(description,
436             "The model to use for the storage. Possible values: ");
437     p = description;
438     while (*(++p) != '\0');
439     for (i = 0; surf_storage_model_description[i].name; i++)
440       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
441                    surf_storage_model_description[i].name);
442     sprintf(p,
443             ".\n       (use 'help' as a value to see the long description of each model)");
444     default_value = xbt_strdup("default");
445     xbt_cfg_register(&_sg_cfg_set, "storage/model", description, xbt_cfgelm_string,
446                      &default_value, 1, 1, &_sg_cfg_cb__storage_mode,
447                      NULL);
448
449     /* ********************************************************************* */
450     /* TUTORIAL: New model                                                   */
451     sprintf(description,
452             "The model to use for the New model. Possible values: ");
453     p = description;
454     while (*(++p) != '\0');
455     for (i = 0; surf_new_model_description[i].name; i++)
456       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
457                    surf_new_model_description[i].name);
458     sprintf(p,
459             ".\n       (use 'help' as a value to see the long description of each model)");
460     default_value = xbt_strdup("default");
461     xbt_cfg_register(&_sg_cfg_set, "new_model/model", description, xbt_cfgelm_string,
462                      &default_value, 1, 1, &_sg_cfg_cb__storage_mode,
463                      NULL);
464     /* ********************************************************************* */
465
466     sprintf(description,
467             "The model to use for the network. Possible values: ");
468     p = description;
469     while (*(++p) != '\0');
470     for (i = 0; surf_network_model_description[i].name; i++)
471       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
472                    surf_network_model_description[i].name);
473     sprintf(p,
474             ".\n       (use 'help' as a value to see the long description of each model)");
475     default_value = xbt_strdup("LV08");
476     xbt_cfg_register(&_sg_cfg_set, "network/model", description, xbt_cfgelm_string,
477                      &default_value, 1, 1, &_sg_cfg_cb__network_model,
478                      NULL);
479
480     sprintf(description,
481             "The optimization modes to use for the network. Possible values: ");
482     p = description;
483     while (*(++p) != '\0');
484     for (i = 0; surf_optimization_mode_description[i].name; i++)
485       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
486                    surf_optimization_mode_description[i].name);
487     sprintf(p,
488             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
489     default_value = xbt_strdup("Lazy");
490     xbt_cfg_register(&_sg_cfg_set, "network/optim", description, xbt_cfgelm_string,
491                      &default_value, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
492
493     sprintf(description,
494             "The model to use for the workstation. Possible values: ");
495     p = description;
496     while (*(++p) != '\0');
497     for (i = 0; surf_workstation_model_description[i].name; i++)
498       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
499                    surf_workstation_model_description[i].name);
500     sprintf(p,
501             ".\n       (use 'help' as a value to see the long description of each model)");
502     default_value = xbt_strdup("default");
503     xbt_cfg_register(&_sg_cfg_set, "workstation/model", description, xbt_cfgelm_string,
504                      &default_value, 1, 1,
505                      &_sg_cfg_cb__workstation_model, NULL);
506
507     xbt_free(description);
508
509     xbt_cfg_register(&_sg_cfg_set, "network/TCP_gamma",
510                      "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)",
511                      xbt_cfgelm_double, NULL, 1, 1,
512                      _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, NULL, 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, NULL, 1, 1, /* default is set in network.c */
525                      _sg_cfg_cb__sender_gap, NULL);
526
527     double_default_value = 1.0; // FIXME use setdefault everywhere here!
528     xbt_cfg_register(&_sg_cfg_set, "network/latency_factor",
529                      "Correction factor to apply to the provided latency (default value set by network model)",
530                      xbt_cfgelm_double, &double_default_value, 1, 1,
531                      _sg_cfg_cb__latency_factor, NULL);
532     double_default_value = 1.0;
533     xbt_cfg_register(&_sg_cfg_set, "network/bandwidth_factor",
534                      "Correction factor to apply to the provided bandwidth (default value set by network model)",
535                      xbt_cfgelm_double, &double_default_value, 1, 1,
536                      _sg_cfg_cb__bandwidth_factor, NULL);
537
538     xbt_cfg_register(&_sg_cfg_set, "network/weight_S",
539                      "Correction factor to apply to the weight of competing streams (default value set by network model)",
540                      xbt_cfgelm_double, NULL, 1, 1, /* default is set in network.c */
541                      _sg_cfg_cb__weight_S, NULL);
542
543     /* Inclusion path */
544     xbt_cfg_register(&_sg_cfg_set, "path",
545                      "Lookup path for inclusions in platform and deployment XML files",
546                      xbt_cfgelm_string, NULL, 0, 0,
547                      _sg_cfg_cb__surf_path, NULL);
548
549     default_value = (char*)"off";
550     xbt_cfg_register(&_sg_cfg_set, "cpu/maxmin_selective_update",
551                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
552                      xbt_cfgelm_boolean, &default_value, 0, 1,
553                      NULL, NULL);
554     default_value = (char*)"off";
555     xbt_cfg_register(&_sg_cfg_set, "network/maxmin_selective_update",
556                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
557                      xbt_cfgelm_boolean, &default_value, 0, 1,
558                      NULL, NULL);
559
560 #ifdef HAVE_MC
561     /* do model-checking */
562     default_value = (char*)"off";
563     xbt_cfg_register(&_sg_cfg_set, "model-check",
564                      "Verify the system through model-checking instead of simulating it (EXPERIMENTAL)",
565                      xbt_cfgelm_boolean, NULL, 0, 1,
566                      _sg_cfg_cb_model_check, NULL);
567     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", default_value);
568
569     /* do stateful model-checking */
570     default_value = (char*)"off";
571     xbt_cfg_register(&_sg_cfg_set, "model-check/checkpoint",
572                      "Specify the amount of steps between checkpoints during stateful model-checking (default: off => stateless verification). "
573                      "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.",
574                      xbt_cfgelm_boolean, NULL, 0, 1,
575                      _mc_cfg_cb_checkpoint, NULL);
576     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/checkpoint", default_value);
577     
578     /* do liveness model-checking */
579     xbt_cfg_register(&_sg_cfg_set, "model-check/property",
580                      "Specify the name of the file containing the property. It must be the result of the ltl2ba program.",
581                      xbt_cfgelm_string, NULL, 0, 1,
582                      _mc_cfg_cb_property, NULL);
583     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/property", "");
584
585     /* Specify the kind of model-checking reduction */
586     xbt_cfg_register(&_sg_cfg_set, "model-check/reduction",
587                      "Specify the kind of exploration reduction (either none or DPOR)",
588                      xbt_cfgelm_string, NULL, 0, 1,
589                      _mc_cfg_cb_reduce, NULL);
590     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/reduction", "dpor");
591
592     /* Enable/disable timeout for wait requests with model-checking */
593     default_value = (char*)"off";
594     xbt_cfg_register(&_sg_cfg_set, "model-check/timeout",
595                      "Enable/Disable timeout for wait requests",
596                      xbt_cfgelm_boolean, NULL, 0, 1,
597                      _mc_cfg_cb_timeout, NULL);
598     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", default_value);
599
600     /* Set max depth exploration */
601     xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
602                      "Specify the max depth of exploration (default : 1000)",
603                      xbt_cfgelm_int, NULL, 0, 1,
604                      _mc_cfg_cb_max_depth, NULL);
605     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/max_depth", 1000);
606
607     /* Set number of visited state stored for state comparison reduction*/
608     xbt_cfg_register(&_sg_cfg_set, "model-check/visited",
609                      "Specify the number of visited state stored for state comparison reduction. If value=5, the last 5 visited states are stored",
610                      xbt_cfgelm_int, NULL, 0, 1,
611                      _mc_cfg_cb_visited, NULL);
612     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
613
614     /* Set file name for dot output of graph state */
615     xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
616                      "Specify the name of dot file corresponding to graph state",
617                      xbt_cfgelm_string, NULL, 0, 1,
618                      _mc_cfg_cb_dot_output, NULL);
619     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
620 #endif
621
622     /* do verbose-exit */
623     default_value = (char*)"on";
624     xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
625                      "Activate the \"do nothing\" mode in Ctrl-C",
626                      xbt_cfgelm_boolean, &default_value, 0, 1,
627                      _sg_cfg_cb_verbose_exit, NULL);
628     
629     
630     /* context factory */
631     default_value = xbt_strdup("ucontext");
632     xbt_cfg_register(&_sg_cfg_set, "contexts/factory",
633                      "Context factory to use in SIMIX (ucontext, thread or raw)",
634                      xbt_cfgelm_string, &default_value, 1, 1, _sg_cfg_cb_context_factory, NULL);
635
636     /* stack size of contexts in Ko */
637     default_value_int = 128;
638     xbt_cfg_register(&_sg_cfg_set, "contexts/stack_size",
639                      "Stack size of contexts in Kib (ucontext or raw only)",
640                      xbt_cfgelm_int, &default_value_int, 1, 1,
641                      _sg_cfg_cb_context_stack_size, NULL);
642
643     /* number of parallel threads for user processes */
644     default_value_int = 1;
645     xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
646                      "Number of parallel threads used to execute user contexts",
647                      xbt_cfgelm_int, &default_value_int, 1, 1,
648                      _sg_cfg_cb_contexts_nthreads, NULL);
649
650     /* minimal number of user contexts to be run in parallel */
651     default_value_int = 2;
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, &default_value_int, 1, 1,
655         _sg_cfg_cb_contexts_parallel_threshold, NULL);
656
657     /* synchronization mode for parallel user contexts */
658 #ifdef HAVE_FUTEX_H
659     default_value = xbt_strdup("futex");
660 #else //No futex on mac and posix is unimplememted yet
661     default_value = xbt_strdup("busy_wait");
662 #endif
663     xbt_cfg_register(&_sg_cfg_set, "contexts/synchro",
664         "Synchronization mode to use when running contexts in parallel (either futex, posix or busy_wait)",
665         xbt_cfgelm_string, &default_value, 1, 1,
666         _sg_cfg_cb_contexts_parallel_mode, NULL);
667
668     default_value = (char*)"no";
669     xbt_cfg_register(&_sg_cfg_set, "network/coordinates",
670                      "\"yes\" or \"no\", specifying whether we use a coordinate-based routing (as Vivaldi)",
671                      xbt_cfgelm_boolean, &default_value, 1, 1,
672                      _sg_cfg_cb__surf_network_coordinates, NULL);
673     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", default_value);
674
675     default_value = (char*)"no";
676     xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic",
677                      "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
678                      xbt_cfgelm_boolean, &default_value, 0, 1,
679                      _sg_cfg_cb__surf_network_crosstraffic, NULL);
680     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", default_value);
681
682 #ifdef HAVE_GTNETS
683     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter",
684                      "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)",
685                      xbt_cfgelm_double, NULL, 1, 1,
686                      _sg_cfg_cb__gtnets_jitter, NULL);
687     xbt_cfg_setdefault_double(_sg_cfg_set, "gtnets/jitter", 0.0);
688
689     default_value_int = 10;
690     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter_seed",
691                      "Use a positive seed to reproduce jitted results, value must be in [1,1e8], default is 10",
692                      xbt_cfgelm_int, &default_value_int, 0, 1,
693                      _sg_cfg_cb__gtnets_jitter_seed, NULL);
694 #endif
695 #ifdef HAVE_NS3
696     xbt_cfg_register(&_sg_cfg_set, "ns3/TcpModel",
697                      "The ns3 tcp model can be : NewReno or Reno or Tahoe",
698                      xbt_cfgelm_string, NULL, 1, 1,
699                      NULL, NULL);
700     xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
701 #endif
702
703 #ifdef HAVE_SMPI
704     double default_reference_speed = 20000.0;
705     xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
706                      "Power of the host running the simulation (in flop/s). Used to bench the operations.",
707                      xbt_cfgelm_double, &default_reference_speed, 1, 1, NULL,
708                      NULL);
709
710     default_value = xbt_strdup("no");
711     xbt_cfg_register(&_sg_cfg_set, "smpi/display_timing",
712                      "Boolean indicating whether we should display the timing after simulation.",
713                      xbt_cfgelm_boolean, &default_value, 1, 1, NULL,
714                      NULL);
715     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", default_value);
716
717     default_value = (char*)"yes";
718     xbt_cfg_register(&_sg_cfg_set, "smpi/use_shared_malloc",
719                      "Boolean indicating whether we should use shared memory when using SMPI_SHARED_MALLOC. Allows user to disable it for debug purposes.",
720                      xbt_cfgelm_boolean, &default_value, 1, 1, NULL,
721                      NULL);
722     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/use_shared_malloc", default_value);
723     
724     double default_threshold = 1e-6;
725     xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold",
726                      "Minimal computation time (in seconds) not discarded.",
727                      xbt_cfgelm_double, &default_threshold, 1, 1, NULL,
728                      NULL);
729
730     int default_small_messages_threshold = 0;
731     xbt_cfg_register(&_sg_cfg_set, "smpi/async_small_thres",
732                      "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
733                      xbt_cfgelm_int, &default_small_messages_threshold, 1, 1, NULL,
734                      NULL);
735
736     int default_send_is_detached_threshold = 65536;
737     xbt_cfg_register(&_sg_cfg_set, "smpi/send_is_detached_thres",
738                      "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend",
739                      xbt_cfgelm_int, &default_send_is_detached_threshold, 1, 1, NULL,
740                      NULL);
741
742     //For smpi/bw_factor and smpi/lat_factor
743     //Default value have to be "threshold0:value0;threshold1:value1;...;thresholdN:valueN"
744     //test is if( size >= thresholdN ) return valueN;
745     //Values can be modified with command line --cfg=smpi/bw_factor:"threshold0:value0;threshold1:value1;...;thresholdN:valueN"
746     //  or with tag config put line <prop id="smpi/bw_factor" value="threshold0:value0;threshold1:value1;...;thresholdN:valueN"></prop>
747     xbt_cfg_register(&_sg_cfg_set, "smpi/bw_factor",
748                      "Bandwidth factors for smpi.",
749                      xbt_cfgelm_string, NULL, 1, 1, NULL,
750                      NULL);
751     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");
752
753     xbt_cfg_register(&_sg_cfg_set, "smpi/lat_factor",
754                      "Latency factors for smpi.",
755                      xbt_cfgelm_string, NULL, 1, 1, NULL,
756                      NULL);
757     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");
758
759     xbt_cfg_register(&_sg_cfg_set, "smpi/os",
760                      "Small messages timings (MPI_Send minimum time for small messages)",
761                      xbt_cfgelm_string, NULL, 1, 1, NULL,
762                      NULL);
763     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/os", "1:0:0:0:0");
764
765     xbt_cfg_register(&_sg_cfg_set, "smpi/ois",
766                      "Small messages timings (MPI_Isend minimum time for small messages)",
767                      xbt_cfgelm_string, NULL, 1, 1, NULL,
768                      NULL);
769     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/ois", "1:0:0:0:0");
770
771     xbt_cfg_register(&_sg_cfg_set, "smpi/or",
772                      "Small messages timings (MPI_Recv minimum time for small messages)",
773                      xbt_cfgelm_string, NULL, 1, 1, NULL,
774                      NULL);
775     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
776     double default_iprobe_time = 1e-4;
777     xbt_cfg_register(&_sg_cfg_set, "smpi/iprobe",
778                      "Minimum time to inject inside a call to MPI_Iprobe",
779                      xbt_cfgelm_double, &default_iprobe_time, 1, 1, NULL,
780                      NULL);
781     default_value = xbt_strdup("default");
782     xbt_cfg_register(&_sg_cfg_set, "smpi/coll_selector",
783                      "Which collective selector to use",
784                      xbt_cfgelm_string, &default_value, 1, 1, NULL,
785                      NULL);
786                      
787                 xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
788                      "Which collective to use for gather",
789                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_gather,
790                      NULL);
791                      
792     xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
793                      "Which collective to use for allgather",
794                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_allgather,
795                      NULL);
796
797     xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
798                      "Which collective to use for barrier",
799                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_barrier,
800                      NULL);
801
802     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
803                      "Which collective to use for reduce_scatter",
804                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_reduce_scatter,
805                      NULL);
806
807     xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
808                      "Which collective to use for scatter",
809                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_scatter,
810                      NULL);
811
812     xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
813                      "Which collective to use for allgatherv",
814                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_allgatherv,
815                      NULL);
816
817     xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
818                      "Which collective to use for allreduce",
819                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_allreduce,
820                      NULL);
821
822     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
823                      "Which collective to use for alltoall",
824                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_alltoall,
825                      NULL);
826
827     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
828                      "Which collective to use for alltoallv",
829                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_alltoallv,
830                      NULL);
831
832     xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
833                      "Which collective to use for bcast",
834                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_bcast,
835                      NULL);
836
837     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
838                      "Which collective to use for reduce",
839                      xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_reduce,
840                      NULL);
841 #endif // HAVE_SMPI
842
843     default_value = (char*)"yes";
844     xbt_cfg_register(&_sg_cfg_set, "clean_atexit",
845                      "\"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.",
846                      xbt_cfgelm_boolean, &default_value, 1, 1,
847                      _sg_cfg_cb_clean_atexit, NULL);
848     xbt_cfg_setdefault_boolean(_sg_cfg_set, "clean_atexit", default_value);
849
850     if (!surf_path) {
851       /* retrieves the current directory of the        current process */
852       const char *initial_path = __surf_get_initial_path();
853       xbt_assert((initial_path),
854                   "__surf_get_initial_path() failed! Can't resolves current Windows directory");
855
856       surf_path = xbt_dynar_new(sizeof(char *), NULL);
857       xbt_cfg_setdefault_string(_sg_cfg_set, "path", initial_path);
858     }
859
860     _sg_init_status = 1;
861
862     sg_config_cmd_line(argc, argv);
863
864     xbt_mallocator_initialization_is_done(SIMIX_context_is_parallel());
865
866   } else {
867     XBT_WARN("Call to sg_config_init() after initialization ignored");
868   }
869 }
870
871 void sg_config_finalize(void)
872 {
873   if (!_sg_init_status)
874     return;                     /* Not initialized yet. Nothing to do */
875
876   xbt_cfg_free(&_sg_cfg_set);
877   _sg_init_status = 0;
878 }
879
880 /* Pick the right models for CPU, net and workstation, and call their model_init_preparse */
881 void surf_config_models_setup()
882 {
883   char *workstation_model_name;
884   int workstation_id = -1;
885   char *network_model_name = NULL;
886   char *cpu_model_name = NULL;
887   int storage_id = -1;
888   char *storage_model_name = NULL;
889
890   workstation_model_name =
891       xbt_cfg_get_string(_sg_cfg_set, "workstation/model");
892   network_model_name = xbt_cfg_get_string(_sg_cfg_set, "network/model");
893   cpu_model_name = xbt_cfg_get_string(_sg_cfg_set, "cpu/model");
894   storage_model_name = xbt_cfg_get_string(_sg_cfg_set, "storage/model");
895
896   /* Check whether we use a net/cpu model differing from the default ones, in which case
897    * we should switch to the "compound" workstation model to correctly dispatch stuff to
898    * the right net/cpu models.
899    */
900
901   if((!xbt_cfg_is_default_value(_sg_cfg_set, "network/model") ||
902     !xbt_cfg_is_default_value(_sg_cfg_set, "cpu/model")) &&
903     xbt_cfg_is_default_value(_sg_cfg_set, "workstation/model"))
904   {
905       const char *val = "compound";
906       XBT_INFO
907           ("Switching workstation model to compound since you changed the network and/or cpu model(s)");
908       xbt_cfg_set_string(_sg_cfg_set, "workstation/model", val);
909       workstation_model_name = (char *) "compound";
910   }
911
912   XBT_DEBUG("Workstation model: %s", workstation_model_name);
913   workstation_id =
914       find_model_description(surf_workstation_model_description,
915                              workstation_model_name);
916   if (!strcmp(workstation_model_name, "compound")) {
917     int network_id = -1;
918     int cpu_id = -1;
919
920     xbt_assert(cpu_model_name,
921                 "Set a cpu model to use with the 'compound' workstation model");
922
923     xbt_assert(network_model_name,
924                 "Set a network model to use with the 'compound' workstation model");
925
926     network_id =
927         find_model_description(surf_network_model_description,
928                                network_model_name);
929     cpu_id =
930         find_model_description(surf_cpu_model_description, cpu_model_name);
931
932     surf_cpu_model_description[cpu_id].model_init_preparse();
933     surf_network_model_description[network_id].model_init_preparse();
934   }
935
936   XBT_DEBUG("Call workstation_model_init");
937   surf_workstation_model_description[workstation_id].model_init_preparse();
938
939   XBT_DEBUG("Call storage_model_init");
940   storage_id = find_model_description(surf_storage_model_description, storage_model_name);
941   surf_storage_model_description[storage_id].model_init_preparse();
942
943   /* ********************************************************************* */
944   /* TUTORIAL: New model                                                   */
945   int new_model_id = -1;
946   char *new_model_name = NULL;
947   new_model_name = xbt_cfg_get_string(_sg_cfg_set, "new_model/model");
948   XBT_DEBUG("Call new model_init");
949   new_model_id = find_model_description(surf_new_model_description, new_model_name);
950   surf_new_model_description[new_model_id].model_init_preparse();
951   /* ********************************************************************* */
952 }
953
954 int sg_cfg_get_int(const char* name)
955 {
956         return xbt_cfg_get_int(_sg_cfg_set,name);
957 }
958 double sg_cfg_get_double(const char* name)
959 {
960         return xbt_cfg_get_double(_sg_cfg_set,name);
961 }
962 char* sg_cfg_get_string(const char* name)
963 {
964         return xbt_cfg_get_string(_sg_cfg_set,name);
965 }
966 int sg_cfg_get_boolean(const char* name)
967 {
968         return xbt_cfg_get_boolean(_sg_cfg_set,name);
969 }
970 void sg_cfg_get_peer(const char *name, char **peer, int *port)
971 {
972         xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
973 }
974 xbt_dynar_t sg_cfg_get_dynar(const char* name)
975 {
976         return xbt_cfg_get_dynar(_sg_cfg_set,name);
977 }