+ } else { /* search relative files in the path */
+
+ if (!path_name) {
+ path_name_len = strlen(name);
+ path_name = xbt_new0(char, path_name_len + 1);
+ }
+
+ xbt_dynar_foreach(surf_path, iter, path) {
+ if (path_name_len < strlen(path) + strlen(name) + 1) {
+ path_name_len = strlen(path) + strlen(name) + 1; /* plus '/' */
+ path_name = xbt_realloc(path_name, path_name_len + 1);
+ }
+ #ifdef WIN32
+ sprintf(path_name, "%s\\%s", path, name);
+ #else
+ sprintf(path_name, "%s/%s", path, name);
+ #endif
+ file = fopen(path_name, mode);
+ if (file)
+ return file;
+ }
+ }
+ return file;
+}
+
+void surf_exit(void)
+{
+ unsigned int iter;
+ surf_model_t model = NULL;
+
+ xbt_dynar_foreach(model_list, iter, model) {
+ model->common_private->finalize();
+ }
+
+ if (maxmin_system) {
+ lmm_system_free(maxmin_system);
+ maxmin_system = NULL;
+ }
+ if (history) {
+ tmgr_history_free(history);
+ history = NULL;
+ }
+ if (model_list)
+ xbt_dynar_free(&model_list);
+
+ if (surf_path)
+ xbt_dynar_free(&surf_path);
+
+ tmgr_finalize();
+ surf_parse_lex_destroy();
+ if (path_name) {
+ free(path_name);
+ path_name = NULL;
+ }
+ surf_parse_free_callbacks();
+ xbt_dict_free(&route_table);
+ NOW=0; /* Just in case the user plans to restart the simulation afterward */
+ xbt_exit();
+}
+
+void surf_presolve(void) {
+ double next_event_date = -1.0;
+ tmgr_trace_event_t event = NULL;
+ double value = -1.0;
+ surf_model_object_t model_obj = NULL;
+ surf_model_t model = NULL;
+ unsigned int iter;
+
+ DEBUG0
+ ("First Run! Let's \"purge\" events and put models in the right state");
+ while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
+ if (next_event_date > NOW)
+ break;
+ while ((event =
+ tmgr_history_get_next_event_leq(history, next_event_date,
+ &value,
+ (void **) &model_obj))) {
+ model_obj->model->common_private->
+ update_resource_state(model_obj, event, value,NOW);
+ }
+ }
+ xbt_dynar_foreach(model_list, iter, model) {
+ model->common_private->update_actions_state(NOW, 0.0);
+ }
+}
+
+double surf_solve(void)
+{
+ double min = -1.0;
+ double next_event_date = -1.0;
+ double model_next_action_end = -1.0;
+ double value = -1.0;
+ surf_model_object_t model_obj = NULL;
+ surf_model_t model = NULL;
+ tmgr_trace_event_t event = NULL;
+ unsigned int iter;
+
+ min = -1.0;
+
+ DEBUG0("Looking for next action end");
+ xbt_dynar_foreach(model_list, iter, model) {
+ DEBUG1("Running for Resource [%s]", model->common_public->name);
+ model_next_action_end =
+ model->common_private->share_resources(NOW);
+ DEBUG2("Resource [%s] : next action end = %f",
+ model->common_public->name, model_next_action_end);
+ if (((min < 0.0) || (model_next_action_end < min))
+ && (model_next_action_end >= 0.0))
+ min = model_next_action_end;
+ }
+ DEBUG1("Next action end : %f", min);
+
+ if (min < 0.0)
+ return -1.0;
+
+ DEBUG0("Looking for next event");
+ while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
+ DEBUG1("Next event : %f", next_event_date);
+ if (next_event_date > NOW + min)
+ break;
+ DEBUG0("Updating models");
+ while ((event =
+ tmgr_history_get_next_event_leq(history, next_event_date,
+ &value,
+ (void **) &model_obj))) {
+ if (model_obj->model->common_private->
+ resource_used(model_obj)) {
+ min = next_event_date - NOW;
+ DEBUG1
+ ("This event will modify model state. Next event set to %f",
+ min);
+ }
+ /* update state of model_obj according to new value. Does not touch lmm.
+ It will be modified if needed when updating actions */
+ model_obj->model->common_private->
+ update_resource_state(model_obj, event, value,NOW+min);
+ }
+ }
+
+ DEBUG1("Duration set to %f", min);
+
+ NOW = NOW + min;
+
+ xbt_dynar_foreach(model_list, iter, model) {
+ model->common_private->update_actions_state(NOW, min);
+ }
+
+ return min;
+}
+
+double surf_get_clock(void)
+{
+ return NOW;
+}