1 /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011. The SimGrid Team.
2 * All rights reserved. */
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. */
9 #include "surf_private.h"
10 #include "xbt/module.h"
12 #include "surf/surf_resource.h"
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
15 "Logging specific to SURF (kernel)");
17 /* Additional declarations for Windows potability. */
25 static const char *disk_drives_letter_table[MAX_DRIVE] = {
53 #endif /* #ifdef _XBT_WIN32 */
56 * Returns the initial path. On Windows the initial path is
57 * the current directory for the current process in the other
58 * case the function returns "./" that represents the current
59 * directory on Unix/Linux platforms.
62 const char *__surf_get_initial_path(void)
67 char current_directory[MAX_PATH + 1] = { 0 };
68 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
74 strncpy(root, current_directory, 3);
76 for (i = 0; i < MAX_DRIVE; i++) {
77 if (toupper(root[0]) == disk_drives_letter_table[i][0])
78 return disk_drives_letter_table[i];
87 /* The __surf_is_absolute_file_path() returns 1 if
88 * file_path is a absolute file path, in the other
89 * case the function returns 0.
91 int __surf_is_absolute_file_path(const char *file_path)
94 WIN32_FIND_DATA wfd = { 0 };
95 HANDLE hFile = FindFirstFile(file_path, &wfd);
97 if (INVALID_HANDLE_VALUE == hFile)
103 return (file_path[0] == '/');
109 xbt_dynar_t model_list = NULL;
110 tmgr_history_t history = NULL;
111 lmm_system_t maxmin_system = NULL;
112 xbt_dynar_t surf_path = NULL;
114 /* Don't forget to update the option description in smx_config when you change this */
115 s_surf_model_description_t surf_network_model_description[] = {
117 "Realistic network analytic model (slow-start modeled by multiplying latency by 10.4, bandwidth by .92; bottleneck sharing uses a payload of S=8775 for evaluating RTT). ",
118 surf_network_model_init_LegrandVelho},
120 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
121 surf_network_model_init_Constant},
123 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
124 surf_network_model_init_SMPI},
126 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
127 surf_network_model_init_CM02},
130 "Network pseudo-model using the GTNets simulator instead of an analytic model",
131 surf_network_model_init_GTNETS},
135 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
136 surf_network_model_init_NS3},
139 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
140 surf_network_model_init_Reno},
142 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
143 surf_network_model_init_Reno2},
145 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
146 surf_network_model_init_Vegas},
147 {NULL, NULL, NULL} /* this array must be NULL terminated */
150 s_surf_model_description_t surf_cpu_model_description[] = {
152 "Simplistic CPU model (time=size/power).",
153 surf_cpu_model_init_Cas01},
154 {NULL, NULL, NULL} /* this array must be NULL terminated */
157 s_surf_model_description_t surf_workstation_model_description[] = {
159 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
160 surf_workstation_model_init_current_default},
162 "Workstation model that is automatically chosen if you change the network and CPU models",
163 surf_workstation_model_init_compound},
164 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
165 surf_workstation_model_init_ptask_L07},
166 {NULL, NULL, NULL} /* this array must be NULL terminated */
169 s_surf_model_description_t surf_optimization_mode_description[] = {
171 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
174 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
177 "Full update of remaining and variables. Slow but may be useful when debugging.",
179 {NULL, NULL, NULL} /* this array must be NULL terminated */
182 /** Displays the long description of all registered models, and quit */
183 void model_help(const char *category, s_surf_model_description_t * table)
186 printf("Long description of the %s models accepted by this simulator:\n",
188 for (i = 0; table[i].name; i++)
189 printf(" %s: %s\n", table[i].name, table[i].description);
192 int find_model_description(s_surf_model_description_t * table,
196 char *name_list = NULL;
198 for (i = 0; table[i].name; i++)
199 if (!strcmp(name, table[i].name)) {
202 name_list = strdup(table[0].name);
203 for (i = 1; table[i].name; i++) {
205 xbt_realloc(name_list,
206 strlen(name_list) + strlen(table[i].name) + 3);
207 strcat(name_list, ", ");
208 strcat(name_list, table[i].name);
210 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
214 double generic_maxmin_share_resources(xbt_swag_t running_actions,
217 void (*solve) (lmm_system_t))
219 surf_action_t action = NULL;
222 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + (offset))))
226 xbt_swag_foreach(action, running_actions) {
227 value = lmm_variable_getvalue(VARIABLE(action));
228 if ((value > 0) || (action->max_duration >= 0))
236 if (action->remains > 0)
237 min = action->remains / value;
240 if ((action->max_duration >= 0) && (action->max_duration < min))
241 min = action->max_duration;
243 min = action->max_duration;
246 for (action = xbt_swag_getNext(action, running_actions->offset);
248 action = xbt_swag_getNext(action, running_actions->offset)) {
249 value = lmm_variable_getvalue(VARIABLE(action));
251 if (action->remains > 0)
252 value = action->remains / value;
257 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
260 if ((action->max_duration >= 0) && (action->max_duration < min)) {
261 min = action->max_duration;
262 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
265 XBT_DEBUG("min value : %f", min);
271 XBT_LOG_EXTERNAL_CATEGORY(surf_cpu);
272 XBT_LOG_EXTERNAL_CATEGORY(surf_kernel);
273 XBT_LOG_EXTERNAL_CATEGORY(surf_lagrange);
274 XBT_LOG_EXTERNAL_CATEGORY(surf_lagrange_dichotomy);
275 XBT_LOG_EXTERNAL_CATEGORY(surf_maxmin);
276 XBT_LOG_EXTERNAL_CATEGORY(surf_network);
277 XBT_LOG_EXTERNAL_CATEGORY(surf_trace);
278 XBT_LOG_EXTERNAL_CATEGORY(surf_parse);
279 XBT_LOG_EXTERNAL_CATEGORY(surf_timer);
280 XBT_LOG_EXTERNAL_CATEGORY(surf_workstation);
281 XBT_LOG_EXTERNAL_CATEGORY(surf_config);
282 XBT_LOG_EXTERNAL_CATEGORY(surf_route);
285 XBT_LOG_EXTERNAL_CATEGORY(surf_network_gtnets);
288 void surf_init(int *argc, char **argv)
290 XBT_DEBUG("Create all Libs");
291 host_lib = xbt_lib_new();
292 link_lib = xbt_lib_new();
293 as_router_lib = xbt_lib_new();
295 XBT_DEBUG("ADD ROUTING LEVEL");
296 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_free);
297 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,xbt_free);
299 XBT_DEBUG("ADD SURF LEVELS");
300 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_resource_free);
301 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_resource_free);
302 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_resource_free);
304 /* Connect our log channels: that must be done manually under windows */
305 XBT_LOG_CONNECT(surf_cpu, surf);
306 XBT_LOG_CONNECT(surf_kernel, surf);
307 XBT_LOG_CONNECT(surf_lagrange, surf);
308 XBT_LOG_CONNECT(surf_lagrange_dichotomy, surf_lagrange);
309 XBT_LOG_CONNECT(surf_maxmin, surf);
310 XBT_LOG_CONNECT(surf_network, surf);
311 XBT_LOG_CONNECT(surf_trace, surf);
312 XBT_LOG_CONNECT(surf_parse, surf);
313 XBT_LOG_CONNECT(surf_timer, surf);
314 XBT_LOG_CONNECT(surf_workstation, surf);
315 XBT_LOG_CONNECT(surf_config, surf);
316 XBT_LOG_CONNECT(surf_route, surf);
319 XBT_LOG_CONNECT(surf_network_gtnets, surf);
322 xbt_init(argc, argv);
324 model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
326 history = tmgr_history_new();
328 surf_config_init(argc, argv);
335 # define FILE_DELIM "\\"
337 # define FILE_DELIM "/" /* FIXME: move to better location */
340 FILE *surf_fopen(const char *name, const char *mode)
343 char *path_elm = NULL;
349 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
350 return fopen(name, mode);
352 /* search relative files in the path */
353 xbt_dynar_foreach(surf_path, cpt, path_elm) {
354 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
355 file = fopen(buff, mode);
367 surf_model_t model = NULL;
369 surf_config_finalize();
371 xbt_dynar_foreach(model_list, iter, model)
372 model->model_private->finalize();
373 xbt_dynar_free(&model_list);
377 lmm_system_free(maxmin_system);
378 maxmin_system = NULL;
381 tmgr_history_free(history);
386 xbt_dynar_free(&surf_path);
388 xbt_lib_free(&host_lib);
389 xbt_lib_free(&link_lib);
390 xbt_lib_free(&as_router_lib);
394 surf_parse_lex_destroy();
395 surf_parse_free_callbacks();
397 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
400 void surf_presolve(void)
402 double next_event_date = -1.0;
403 tmgr_trace_event_t event = NULL;
405 surf_resource_t resource = NULL;
406 surf_model_t model = NULL;
410 ("First Run! Let's \"purge\" events and put models in the right state");
411 while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
412 if (next_event_date > NOW)
415 tmgr_history_get_next_event_leq(history, next_event_date,
417 (void **) &resource))) {
418 resource->model->model_private->update_resource_state(resource,
423 xbt_dynar_foreach(model_list, iter, model)
424 model->model_private->update_actions_state(NOW, 0.0);
427 double surf_solve(double max_date)
429 double min = -1.0; /* duration */
430 double next_event_date = -1.0;
431 double model_next_action_end = -1.0;
433 surf_resource_t resource = NULL;
434 surf_model_t model = NULL;
435 tmgr_trace_event_t event = NULL;
438 if (max_date != -1.0 && max_date != NOW) {
439 min = max_date - NOW;
442 XBT_DEBUG("Looking for next action end for all models except NS3");
443 xbt_dynar_foreach(model_list, iter, model) {
444 if(strcmp(model->name,"network NS3") ){
445 XBT_DEBUG("Running for Resource [%s]", model->name);
446 model_next_action_end = model->model_private->share_resources(NOW);
447 XBT_DEBUG("Resource [%s] : next action end = %f",
448 model->name, model_next_action_end);
449 if (((min < 0.0) || (model_next_action_end < min))
450 && (model_next_action_end >= 0.0))
451 min = model_next_action_end;
455 XBT_DEBUG("Min for resources (except NS3) : %f", min);
457 XBT_DEBUG("Looking for next trace event");
460 XBT_DEBUG("Next TRACE event : %f", next_event_date);
462 next_event_date = tmgr_history_next_date(history);
464 if(surf_network_model->name && !strcmp(surf_network_model->name,"network NS3")){
465 if(next_event_date!=-1.0 && min!=-1.0) {
466 min = MIN(next_event_date - NOW, min);
468 min = MAX(next_event_date - NOW, min);
471 XBT_DEBUG("Run for NS3 at most %f", min);
472 // run until min or next flow
473 model_next_action_end = surf_network_model->model_private->share_resources(min);
475 XBT_DEBUG("Min for NS3 : %f", model_next_action_end);
476 if(model_next_action_end>=0.0)
477 min = model_next_action_end;
480 if (next_event_date == -1.0) break;
482 if ((min != -1.0) && (next_event_date > NOW + min)) break;
484 XBT_DEBUG("Updating models");
486 tmgr_history_get_next_event_leq(history, next_event_date,
488 (void **) &resource))) {
489 if (resource->model->model_private->resource_used(resource)) {
490 min = next_event_date - NOW;
492 ("This event will modify model state. Next event set to %f",
495 /* update state of model_obj according to new value. Does not touch lmm.
496 It will be modified if needed when updating actions */
497 XBT_DEBUG("Calling update_resource_state for resource %s with min %lf",
498 resource->model->name, min);
499 resource->model->model_private->update_resource_state(resource,
505 /* FIXME: Moved this test to here to avoid stoping simulation if there are actions running on cpus and all cpus are with availability = 0.
506 * This may cause an infinite loop if one cpu has a trace with periodicity = 0 and the other a trace with periodicity > 0.
507 * The options are: all traces with same periodicity(0 or >0) or we need to change the way how the events are managed */
511 XBT_DEBUG("Duration set to %f", min);
515 xbt_dynar_foreach(model_list, iter, model)
516 model->model_private->update_actions_state(NOW, min);
519 TRACE_paje_dump_buffer (0);
525 XBT_INLINE double surf_get_clock(void)