Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
f1206eb9ab85b331c6deb903ef7c6f8063b4ab92
[simgrid.git] / src / surf / surf.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2004 Arnaud Legrand. All rights reserved.                  */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "surf_private.h"
9 #include "xbt/module.h"
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_global, surf,
12                                 "Logging specific to the SURF global module");
13
14
15 static double NOW = 0;
16
17 xbt_dynar_t resource_list = NULL;
18 tmgr_history_t history = NULL;
19 lmm_system_t maxmin_system = NULL;
20 xbt_dynar_t surf_path = NULL;
21
22 double generic_maxmin_share_resources(xbt_swag_t running_actions,
23                                       size_t offset)
24 {
25   surf_action_t action = NULL;
26   double min = -1;
27   double value = -1;
28 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + (offset))))
29
30   lmm_solve(maxmin_system);
31
32   xbt_swag_foreach(action, running_actions) {
33     value = lmm_variable_getvalue(VARIABLE(action));
34     if ((value > 0) || (action->max_duration >= 0))
35       break;
36   }
37
38   if (!action)
39     return -1.0;
40
41   if (value > 0) {
42     min = value = action->remains / value;
43     if ((action->max_duration >= 0) && (action->max_duration < min))
44       min = action->max_duration;
45   } else
46     min = action->max_duration;
47
48
49   for (action = xbt_swag_getNext(action, running_actions->offset);
50        action;
51        action = xbt_swag_getNext(action, running_actions->offset)) {
52     value = lmm_variable_getvalue(VARIABLE(action));
53     if (value > 0) {
54       value = action->remains / value;
55       if (value < min)
56         min = value;
57     }
58     if ((action->max_duration >= 0) && (action->max_duration < min))
59       min = action->max_duration;
60   }
61 #undef VARIABLE
62   return min;
63 }
64
65 e_surf_action_state_t surf_action_get_state(surf_action_t action)
66 {
67   surf_action_state_t action_state =
68       &(action->resource_type->common_public->states);
69
70   if (action->state_set == action_state->ready_action_set)
71     return SURF_ACTION_READY;
72   if (action->state_set == action_state->running_action_set)
73     return SURF_ACTION_RUNNING;
74   if (action->state_set == action_state->failed_action_set)
75     return SURF_ACTION_FAILED;
76   if (action->state_set == action_state->done_action_set)
77     return SURF_ACTION_DONE;
78   return SURF_ACTION_NOT_IN_THE_SYSTEM;
79 }
80
81 void surf_action_free(surf_action_t * action)
82 {
83   (*action)->resource_type->common_public->action_cancel(*action);
84   xbt_free(*action);
85   *action = NULL;
86 }
87
88 void surf_action_change_state(surf_action_t action,
89                               e_surf_action_state_t state)
90 {
91   surf_action_state_t action_state =
92       &(action->resource_type->common_public->states);
93
94   xbt_swag_remove(action, action->state_set);
95
96   if (state == SURF_ACTION_READY)
97     action->state_set = action_state->ready_action_set;
98   else if (state == SURF_ACTION_RUNNING)
99     action->state_set = action_state->running_action_set;
100   else if (state == SURF_ACTION_FAILED)
101     action->state_set = action_state->failed_action_set;
102   else if (state == SURF_ACTION_DONE)
103     action->state_set = action_state->done_action_set;
104   else
105     action->state_set = NULL;
106
107   if (action->state_set)
108     xbt_swag_insert(action, action->state_set);
109 }
110
111 void surf_action_set_data(surf_action_t action,
112                           void *data)
113 {
114   action->data=data;
115 }
116
117 void surf_init(int *argc, char **argv)
118 {
119   int i,j;
120   char *opt;
121
122   xbt_init(argc, argv);
123   if (!surf_path) {
124     const char *initial_path = "./";
125     surf_path = xbt_dynar_new(sizeof(char*), NULL);
126     xbt_dynar_push(surf_path,&initial_path);
127
128     for (i=1; i<*argc; i++) {
129       if (!strncmp(argv[i],"--surf-path=",strlen("--surf-path="))) {
130         opt=strchr(argv[i],'=');
131         opt++;
132         xbt_dynar_push(surf_path,&opt);
133         /*remove this from argv*/
134         for (j=i+1; j<*argc; j++) {
135           argv[j-1] = argv[j];
136         } 
137         argv[j-1] = NULL;
138         (*argc)--;
139         i--; /* compensate effect of next loop incrementation */
140       }
141     }
142   }
143   if (!resource_list)
144     resource_list = xbt_dynar_new(sizeof(surf_resource_private_t), NULL);
145   if (!history)
146     history = tmgr_history_new();
147   if (!maxmin_system)
148     maxmin_system = lmm_system_new();
149 }
150
151 static char* path_name = NULL;
152 FILE *surf_fopen(const char *name, const char *mode)
153 {
154   int i; 
155   char* path = NULL;
156   FILE *file = NULL;
157
158   xbt_assert0(surf_path,"surf_init has to be called before using surf_fopen");
159   if(!path_name) path_name=xbt_new0(char,strlen(name)+1);
160
161   xbt_dynar_foreach(surf_path,i,path) {
162     if(strlen(path_name)<strlen(path)+strlen(name)+2) 
163       path_name=xbt_realloc(path_name,strlen(path)+strlen(name)+2);
164     strcpy(path_name, path);
165     strcat(path_name,"/");
166     strcat(path_name,name);
167     file = fopen(path_name,mode);
168     if(file) return file;
169   }
170   return file;
171 }
172
173 void surf_finalize(void)
174 {
175   int i;
176   surf_resource_t resource = NULL;
177
178   xbt_dynar_foreach(resource_list, i, resource) {
179     resource->common_private->finalize();
180   }
181
182   if (maxmin_system) {
183     lmm_system_free(maxmin_system);
184     maxmin_system = NULL;
185   }
186   if (history) {
187     tmgr_history_free(history);
188     history = NULL;
189   }
190   if (resource_list)
191     xbt_dynar_free(&resource_list);
192
193   if(surf_path) 
194     xbt_dynar_free(&surf_path);
195
196   tmgr_finalize();
197   surf_parse_lex_destroy();
198   if(path_name) {
199     xbt_free(path_name);
200     path_name = NULL;
201   }
202 }
203
204 double surf_solve(void)
205 {
206   static int first_run = 1;
207
208   double min = -1.0;
209   double next_event_date = -1.0;
210   double resource_next_action_end = -1.0;
211   double value = -1.0;
212   surf_resource_object_t resource_obj = NULL;
213   surf_resource_t resource = NULL;
214   tmgr_trace_event_t event = NULL;
215   int i;
216
217   if (first_run) {
218     while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
219       if (next_event_date > NOW)
220         break;
221       while ((event =
222               tmgr_history_get_next_event_leq(history, next_event_date,
223                                               &value,
224                                               (void **) &resource_obj))) {
225         resource_obj->resource->common_private->
226             update_resource_state(resource_obj, event, value);
227       }
228     }
229     xbt_dynar_foreach(resource_list, i, resource) {
230       resource->common_private->update_actions_state(NOW, 0.0);
231     }
232     first_run = 0;
233     return 0.0;
234   }
235
236   min = -1.0;
237
238   xbt_dynar_foreach(resource_list, i, resource) {
239     resource_next_action_end =
240         resource->common_private->share_resources(NOW);
241     if (((min < 0.0) || (resource_next_action_end < min))
242         && (resource_next_action_end >= 0.0))
243       min = resource_next_action_end;
244   }
245
246   if (min < 0.0)
247     return -1.0;
248
249   while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
250     if (next_event_date > NOW + min)
251       break;
252     while ((event =
253             tmgr_history_get_next_event_leq(history, next_event_date,
254                                             &value,
255                                             (void **) &resource_obj))) {
256       if (resource_obj->resource->common_private->
257           resource_used(resource_obj)) {
258         min = next_event_date - NOW;
259       }
260       /* update state of resource_obj according to new value. Does not touch lmm.
261          It will be modified if needed when updating actions */
262       resource_obj->resource->common_private->
263           update_resource_state(resource_obj, event, value);
264     }
265   }
266
267
268   xbt_dynar_foreach(resource_list, i, resource) {
269     resource->common_private->update_actions_state(NOW, min);
270   }
271
272   NOW = NOW + min;
273
274   return min;
275 }
276
277 double surf_get_clock(void)
278 {
279   return NOW;
280 }