Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
a56360898758f94166b8bf0d2d025f36b98efa5f
[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 static xbt_heap_float_t NOW=0;
12
13 xbt_dynar_t resource_list = NULL;
14 tmgr_history_t history = NULL;
15 lmm_system_t maxmin_system = NULL;
16
17 xbt_heap_float_t generic_maxmin_share_resources(xbt_swag_t running_actions,
18                                                 size_t offset)
19 {
20   surf_action_t action = NULL;
21   xbt_maxmin_float_t min = -1;
22   xbt_maxmin_float_t value = -1;
23 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + (offset))))
24
25  lmm_solve(maxmin_system);
26
27   xbt_swag_foreach(action, running_actions) {
28     value = lmm_variable_getvalue(VARIABLE(action));
29     if((value>0) || (action->max_duration>=0)) break;
30   }
31   
32   if (!action)
33     return -1.0;
34
35   if(value>0) {
36     min = value = action->remains / value;
37     if((action->max_duration>=0) && 
38        (action->max_duration<min))
39       min = action->max_duration;
40   }  else min = action->max_duration;
41
42   
43   for(action=xbt_swag_getNext(action,running_actions->offset);
44       action;
45       action=xbt_swag_getNext(action,running_actions->offset)) {
46     value = lmm_variable_getvalue(VARIABLE(action));
47     if(value>0) {
48       value = action->remains / value;
49       if (value < min) min = value;
50     }
51     if((action->max_duration>=0) && 
52        (action->max_duration<min))
53       min = action->max_duration;
54   }
55 #undef VARIABLE
56   return min;
57 }
58
59 e_surf_action_state_t surf_action_get_state(surf_action_t action)
60 {
61   surf_action_state_t action_state = &(action->resource_type->common_public->states); 
62   
63   if(action->state_set == action_state->ready_action_set)
64     return SURF_ACTION_READY;
65   if(action->state_set == action_state->running_action_set)
66     return SURF_ACTION_RUNNING;
67   if(action->state_set == action_state->failed_action_set)
68     return SURF_ACTION_FAILED;
69   if(action->state_set == action_state->done_action_set)
70     return SURF_ACTION_DONE;
71   return SURF_ACTION_NOT_IN_THE_SYSTEM;
72 }
73
74 void surf_action_free(surf_action_t * action)
75 {
76   (*action)->resource_type->common_public->action_cancel(*action);
77   xbt_free(*action);
78   *action=NULL;
79 }
80
81 void surf_action_change_state(surf_action_t action, e_surf_action_state_t state)
82 {
83   surf_action_state_t action_state = &(action->resource_type->common_public->states); 
84
85   xbt_swag_remove(action, action->state_set);
86
87   if(state == SURF_ACTION_READY) 
88     action->state_set = action_state->ready_action_set;
89   else if(state == SURF_ACTION_RUNNING)
90     action->state_set = action_state->running_action_set;
91   else if(state == SURF_ACTION_FAILED)
92     action->state_set = action_state->failed_action_set;
93   else if(state == SURF_ACTION_DONE)
94     action->state_set = action_state->done_action_set;
95   else action->state_set = NULL;
96
97   if(action->state_set) xbt_swag_insert(action, action->state_set);
98 }
99
100 void surf_init(int *argc, char **argv)
101 {
102   xbt_init(argc, argv);
103   if(!resource_list) resource_list = xbt_dynar_new(sizeof(surf_resource_private_t), NULL);
104   if(!history) history = tmgr_history_new();
105   if(!maxmin_system) maxmin_system = lmm_system_new();
106 }
107
108 void surf_finalize(void)
109
110   int i;
111   surf_resource_t resource = NULL;
112
113   xbt_dynar_foreach (resource_list,i,resource) {
114     resource->common_private->finalize();
115   }
116
117   if(maxmin_system) {
118     lmm_system_free(maxmin_system);
119     maxmin_system = NULL;
120   }
121   if(history) {
122     tmgr_history_free(history);
123     history = NULL;
124   }
125   if(resource_list) xbt_dynar_free(&resource_list);
126
127   tmgr_finalize();
128 }
129
130 xbt_heap_float_t surf_solve(void)
131 {
132   static int first_run = 1;
133
134   xbt_heap_float_t min = -1.0;
135   xbt_heap_float_t next_event_date = -1.0;
136   xbt_heap_float_t resource_next_action_end = -1.0;
137   xbt_maxmin_float_t value = -1.0;
138   surf_resource_object_t resource_obj = NULL;
139   surf_resource_t resource = NULL;
140   tmgr_trace_event_t event = NULL;
141   int i;
142
143   if(first_run) {
144     while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
145       if(next_event_date > NOW) break;
146       while ((event = tmgr_history_get_next_event_leq(history, next_event_date,
147                                                       &value, (void **) &resource_obj))) {
148         resource_obj->resource->common_private->update_resource_state(resource_obj,
149                                                                       event, value);
150       }
151     }
152     xbt_dynar_foreach (resource_list,i,resource) {
153       resource->common_private->update_actions_state(NOW, 0.0);
154     }
155     first_run = 0;
156     return 0.0;
157   }
158
159   min = -1.0;
160
161   xbt_dynar_foreach (resource_list,i,resource) {
162     resource_next_action_end = resource->common_private->share_resources(NOW);
163     if(((min<0.0) || (resource_next_action_end<min)) && (resource_next_action_end>=0.0))
164       min = resource_next_action_end;
165   }
166
167   if(min<0.0) return 0.0;
168
169   while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
170     if(next_event_date > NOW+min) break;
171     while ((event=tmgr_history_get_next_event_leq(history, next_event_date,
172                                                   &value, (void **) &resource_obj))) {
173       if(resource_obj->resource->common_private->resource_used(resource_obj)) {
174         min = next_event_date-NOW;
175       }
176       /* update state of resource_obj according to new value. Does not touch lmm.
177          It will be modified if needed when updating actions */
178       resource_obj->resource->common_private->update_resource_state(resource_obj,
179                                                                     event, value);
180     }
181   }
182
183
184   xbt_dynar_foreach (resource_list,i,resource) {
185     resource->common_private->update_actions_state(NOW, min);
186   }
187
188   NOW=NOW+min;
189
190   return min;
191 }
192
193 xbt_heap_float_t surf_get_clock(void)
194 {
195   return NOW;
196 }