Logo AND Algorithmique Numérique Distribuée

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