Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
171b66a48a00d4fad6447f6d39c2aa76f15991cd
[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 FILE *surf_fopen(const char *name, const char *mode)
152 {
153   int i; 
154   char* path = NULL;
155   FILE *file = NULL;
156   static char* path_name = 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   tmgr_finalize();
194   surf_parse_lex_destroy();
195 }
196
197 double surf_solve(void)
198 {
199   static int first_run = 1;
200
201   double min = -1.0;
202   double next_event_date = -1.0;
203   double resource_next_action_end = -1.0;
204   double value = -1.0;
205   surf_resource_object_t resource_obj = NULL;
206   surf_resource_t resource = NULL;
207   tmgr_trace_event_t event = NULL;
208   int i;
209
210   if (first_run) {
211     while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
212       if (next_event_date > NOW)
213         break;
214       while ((event =
215               tmgr_history_get_next_event_leq(history, next_event_date,
216                                               &value,
217                                               (void **) &resource_obj))) {
218         resource_obj->resource->common_private->
219             update_resource_state(resource_obj, event, value);
220       }
221     }
222     xbt_dynar_foreach(resource_list, i, resource) {
223       resource->common_private->update_actions_state(NOW, 0.0);
224     }
225     first_run = 0;
226     return 0.0;
227   }
228
229   min = -1.0;
230
231   xbt_dynar_foreach(resource_list, i, resource) {
232     resource_next_action_end =
233         resource->common_private->share_resources(NOW);
234     if (((min < 0.0) || (resource_next_action_end < min))
235         && (resource_next_action_end >= 0.0))
236       min = resource_next_action_end;
237   }
238
239   if (min < 0.0)
240     return -1.0;
241
242   while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
243     if (next_event_date > NOW + min)
244       break;
245     while ((event =
246             tmgr_history_get_next_event_leq(history, next_event_date,
247                                             &value,
248                                             (void **) &resource_obj))) {
249       if (resource_obj->resource->common_private->
250           resource_used(resource_obj)) {
251         min = next_event_date - NOW;
252       }
253       /* update state of resource_obj according to new value. Does not touch lmm.
254          It will be modified if needed when updating actions */
255       resource_obj->resource->common_private->
256           update_resource_state(resource_obj, event, value);
257     }
258   }
259
260
261   xbt_dynar_foreach(resource_list, i, resource) {
262     resource->common_private->update_actions_state(NOW, min);
263   }
264
265   NOW = NOW + min;
266
267   return min;
268 }
269
270 double surf_get_clock(void)
271 {
272   return NOW;
273 }