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 "Curent default workstation model (may change with versions of SimGrid). Currently Cas01 and LV08 (with full duplex support) as CPU and Network",
160 surf_workstation_model_init_current_default},
162 "Default workstation model, using Cas01 and CM02 as CPU and Network",
163 surf_workstation_model_init_CLM03},
165 "Workstation model that is automatically chosen if you change the network and CPU models",
166 surf_workstation_model_init_compound},
167 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
168 surf_workstation_model_init_ptask_L07},
169 {NULL, NULL, NULL} /* this array must be NULL terminated */
172 s_surf_model_description_t surf_optimization_mode_description[] = {
174 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
177 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
180 "Full update of remaining and variables. Slow but may be useful when debugging.",
182 {NULL, NULL, NULL} /* this array must be NULL terminated */
185 /** Displays the long description of all registered models, and quit */
186 void model_help(const char *category, s_surf_model_description_t * table)
189 printf("Long description of the %s models accepted by this simulator:\n",
191 for (i = 0; table[i].name; i++)
192 printf(" %s: %s\n", table[i].name, table[i].description);
195 int find_model_description(s_surf_model_description_t * table,
199 char *name_list = NULL;
201 for (i = 0; table[i].name; i++)
202 if (!strcmp(name, table[i].name)) {
205 name_list = strdup(table[0].name);
206 for (i = 1; table[i].name; i++) {
208 xbt_realloc(name_list,
209 strlen(name_list) + strlen(table[i].name) + 3);
210 strcat(name_list, ", ");
211 strcat(name_list, table[i].name);
213 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
217 double generic_maxmin_share_resources(xbt_swag_t running_actions,
220 void (*solve) (lmm_system_t))
222 surf_action_t action = NULL;
225 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + (offset))))
229 xbt_swag_foreach(action, running_actions) {
230 value = lmm_variable_getvalue(VARIABLE(action));
231 if ((value > 0) || (action->max_duration >= 0))
239 if (action->remains > 0)
240 min = action->remains / value;
243 if ((action->max_duration >= 0) && (action->max_duration < min))
244 min = action->max_duration;
246 min = action->max_duration;
249 for (action = xbt_swag_getNext(action, running_actions->offset);
251 action = xbt_swag_getNext(action, running_actions->offset)) {
252 value = lmm_variable_getvalue(VARIABLE(action));
254 if (action->remains > 0)
255 value = action->remains / value;
260 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
263 if ((action->max_duration >= 0) && (action->max_duration < min)) {
264 min = action->max_duration;
265 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
268 XBT_DEBUG("min value : %f", min);
274 XBT_LOG_EXTERNAL_CATEGORY(surf_cpu);
275 XBT_LOG_EXTERNAL_CATEGORY(surf_kernel);
276 XBT_LOG_EXTERNAL_CATEGORY(surf_lagrange);
277 XBT_LOG_EXTERNAL_CATEGORY(surf_lagrange_dichotomy);
278 XBT_LOG_EXTERNAL_CATEGORY(surf_maxmin);
279 XBT_LOG_EXTERNAL_CATEGORY(surf_network);
280 XBT_LOG_EXTERNAL_CATEGORY(surf_trace);
281 XBT_LOG_EXTERNAL_CATEGORY(surf_parse);
282 XBT_LOG_EXTERNAL_CATEGORY(surf_timer);
283 XBT_LOG_EXTERNAL_CATEGORY(surf_workstation);
284 XBT_LOG_EXTERNAL_CATEGORY(surf_config);
285 XBT_LOG_EXTERNAL_CATEGORY(surf_route);
288 XBT_LOG_EXTERNAL_CATEGORY(surf_network_gtnets);
291 void surf_init(int *argc, char **argv)
293 XBT_DEBUG("Create all Libs");
294 host_lib = xbt_lib_new();
295 link_lib = xbt_lib_new();
296 as_router_lib = xbt_lib_new();
298 XBT_DEBUG("ADD ROUTING LEVEL");
299 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_free);
300 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,xbt_free);
302 XBT_DEBUG("ADD SURF LEVELS");
303 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_resource_free);
304 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_resource_free);
305 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_resource_free);
307 /* Connect our log channels: that must be done manually under windows */
308 XBT_LOG_CONNECT(surf_cpu, surf);
309 XBT_LOG_CONNECT(surf_kernel, surf);
310 XBT_LOG_CONNECT(surf_lagrange, surf);
311 XBT_LOG_CONNECT(surf_lagrange_dichotomy, surf_lagrange);
312 XBT_LOG_CONNECT(surf_maxmin, surf);
313 XBT_LOG_CONNECT(surf_network, surf);
314 XBT_LOG_CONNECT(surf_trace, surf);
315 XBT_LOG_CONNECT(surf_parse, surf);
316 XBT_LOG_CONNECT(surf_timer, surf);
317 XBT_LOG_CONNECT(surf_workstation, surf);
318 XBT_LOG_CONNECT(surf_config, surf);
319 XBT_LOG_CONNECT(surf_route, surf);
322 XBT_LOG_CONNECT(surf_network_gtnets, surf);
325 xbt_init(argc, argv);
327 model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
329 history = tmgr_history_new();
331 surf_config_init(argc, argv);
338 # define FILE_DELIM "\\"
340 # define FILE_DELIM "/" /* FIXME: move to better location */
343 FILE *surf_fopen(const char *name, const char *mode)
346 char *path_elm = NULL;
352 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
353 return fopen(name, mode);
355 /* search relative files in the path */
356 xbt_dynar_foreach(surf_path, cpt, path_elm) {
357 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
358 file = fopen(buff, mode);
370 surf_model_t model = NULL;
372 surf_config_finalize();
374 xbt_dynar_foreach(model_list, iter, model)
375 model->model_private->finalize();
376 xbt_dynar_free(&model_list);
380 lmm_system_free(maxmin_system);
381 maxmin_system = NULL;
384 tmgr_history_free(history);
389 xbt_dynar_free(&surf_path);
391 xbt_lib_free(&host_lib);
392 xbt_lib_free(&link_lib);
393 xbt_lib_free(&as_router_lib);
397 surf_parse_lex_destroy();
398 surf_parse_free_callbacks();
400 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
403 void surf_presolve(void)
405 double next_event_date = -1.0;
406 tmgr_trace_event_t event = NULL;
408 surf_resource_t resource = NULL;
409 surf_model_t model = NULL;
413 ("First Run! Let's \"purge\" events and put models in the right state");
414 while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
415 if (next_event_date > NOW)
418 tmgr_history_get_next_event_leq(history, next_event_date,
420 (void **) &resource))) {
421 resource->model->model_private->update_resource_state(resource,
426 xbt_dynar_foreach(model_list, iter, model)
427 model->model_private->update_actions_state(NOW, 0.0);
430 double surf_solve(double max_date)
432 double min = -1.0; /* duration */
433 double next_event_date = -1.0;
434 double model_next_action_end = -1.0;
436 surf_resource_t resource = NULL;
437 surf_model_t model = NULL;
438 tmgr_trace_event_t event = NULL;
441 if (max_date != -1.0 && max_date != NOW) {
442 min = max_date - NOW;
445 XBT_DEBUG("Looking for next action end for all models except NS3");
446 xbt_dynar_foreach(model_list, iter, model) {
447 if(strcmp(model->name,"network NS3") ){
448 XBT_DEBUG("Running for Resource [%s]", model->name);
449 model_next_action_end = model->model_private->share_resources(NOW);
450 XBT_DEBUG("Resource [%s] : next action end = %f",
451 model->name, model_next_action_end);
452 if (((min < 0.0) || (model_next_action_end < min))
453 && (model_next_action_end >= 0.0))
454 min = model_next_action_end;
458 XBT_DEBUG("Min for resources (except NS3) : %f", min);
460 XBT_DEBUG("Looking for next trace event");
463 XBT_DEBUG("Next TRACE event : %f", next_event_date);
465 next_event_date = tmgr_history_next_date(history);
467 if(surf_network_model->name && !strcmp(surf_network_model->name,"network NS3")){
468 if(next_event_date!=-1.0 && min!=-1.0) {
469 min = MIN(next_event_date - NOW, min);
471 min = MAX(next_event_date - NOW, min);
474 XBT_DEBUG("Run for NS3 at most %f", min);
475 // run until min or next flow
476 model_next_action_end = surf_network_model->model_private->share_resources(min);
478 XBT_DEBUG("Min for NS3 : %f", model_next_action_end);
479 if(model_next_action_end>=0.0)
480 min = model_next_action_end;
483 if (next_event_date == -1.0) break;
485 if ((min != -1.0) && (next_event_date > NOW + min)) break;
487 XBT_DEBUG("Updating models");
489 tmgr_history_get_next_event_leq(history, next_event_date,
491 (void **) &resource))) {
492 if (resource->model->model_private->resource_used(resource)) {
493 min = next_event_date - NOW;
495 ("This event will modify model state. Next event set to %f",
498 /* update state of model_obj according to new value. Does not touch lmm.
499 It will be modified if needed when updating actions */
500 XBT_DEBUG("Calling update_resource_state for resource %s with min %lf",
501 resource->model->name, min);
502 resource->model->model_private->update_resource_state(resource,
508 /* FIXME: Moved this test to here to avoid stoping simulation if there are actions running on cpus and all cpus are with availability = 0.
509 * This may cause an infinite loop if one cpu has a trace with periodicity = 0 and the other a trace with periodicity > 0.
510 * The options are: all traces with same periodicity(0 or >0) or we need to change the way how the events are managed */
514 XBT_DEBUG("Duration set to %f", min);
518 xbt_dynar_foreach(model_list, iter, model)
519 model->model_private->update_actions_state(NOW, min);
522 TRACE_paje_dump_buffer (0);
528 XBT_INLINE double surf_get_clock(void)