Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
add the definition of VM state to the surf layer
[simgrid.git] / src / surf / workstation.c
1 /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
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. */
6
7 #include "xbt/ex.h"
8 #include "xbt/dict.h"
9 #include "portable.h"
10 #include "surf_private.h"
11 #include "storage_private.h"
12 #include "surf/surf_resource.h"
13 #include "simgrid/sg_config.h"
14 #include "workstation_private.h"
15
16 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf,
17                                 "Logging specific to the SURF workstation module");
18
19 surf_model_t surf_workstation_model = NULL;
20
21
22 void __init_workstation_CLM03(workstation_CLM03_t ws, const char *id, surf_model_t workstation_model)
23 {
24   ws->generic_resource.model = workstation_model;
25   ws->generic_resource.name = xbt_strdup(id);
26   ws->storage = xbt_lib_get_or_null(storage_lib,id,ROUTING_STORAGE_HOST_LEVEL);
27   ws->net_elm = xbt_lib_get_or_null(host_lib,id,ROUTING_HOST_LEVEL);
28
29   XBT_DEBUG("Create ws %s with %ld mounted disks",id,xbt_dynar_length(ws->storage));
30   xbt_lib_set(host_lib, id, SURF_WKS_LEVEL, ws);
31 }
32
33 static void workstation_new(sg_platf_host_cbarg_t host)
34 {
35   workstation_CLM03_t workstation = xbt_new0(s_workstation_CLM03_t, 1);
36
37   __init_workstation_CLM03(workstation, host->id, surf_workstation_model);
38 }
39
40 static int ws_resource_used(void *resource_id)
41 {
42   THROW_IMPOSSIBLE;             /* This model does not implement parallel tasks */
43   return -1;
44 }
45
46 static void ws_parallel_action_cancel(surf_action_t action)
47 {
48   THROW_UNIMPLEMENTED;          /* This model does not implement parallel tasks */
49 }
50
51 static int ws_parallel_action_free(surf_action_t action)
52 {
53   THROW_UNIMPLEMENTED;          /* This model does not implement parallel tasks */
54   return -1;
55 }
56
57 static int ws_action_unref(surf_action_t action)
58 {
59   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
60     return surf_network_model->action_unref(action);
61   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
62     return action->model_obj->action_unref(action);
63       // previously was: Adrien/Arnaud 6 feb
64           // surf_cpu_model->action_unref(action);
65   else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
66     return ws_parallel_action_free(action);
67   else
68     DIE_IMPOSSIBLE;
69   return 0;
70 }
71
72 static void ws_action_cancel(surf_action_t action)
73 {
74   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
75     surf_network_model->action_cancel(action);
76   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
77     action->model_obj->action_cancel(action);
78   else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
79     ws_parallel_action_cancel(action);
80   else
81     DIE_IMPOSSIBLE;
82   return;
83 }
84
85 static void ws_action_state_set(surf_action_t action,
86                                 e_surf_action_state_t state)
87 {
88   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
89     surf_network_model->action_state_set(action, state);
90   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
91     action->model_obj->action_state_set(action, state);
92   else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
93     surf_action_state_set(action, state);
94   else
95     DIE_IMPOSSIBLE;
96   return;
97 }
98
99 static double ws_share_resources(surf_model_t workstation_model, double now)
100 {
101 // invoke share_resources on CPU and network (layer 0)
102   return -1.0;
103 }
104
105 static void ws_update_actions_state(surf_model_t workstation_model, double now, double delta)
106 {
107   return;
108 }
109
110 static void ws_update_resource_state(void *id,
111                                      tmgr_trace_event_t event_type,
112                                      double value, double date)
113 {
114   THROW_IMPOSSIBLE;             /* This model does not implement parallel tasks */
115 }
116
117 static surf_action_t ws_execute(void *workstation, double size)
118 {
119   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
120   return cpu->model->extension.cpu.execute(workstation, size);
121 }
122
123 static surf_action_t ws_action_sleep(void *workstation, double duration)
124 {
125   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
126   return cpu->model->extension.cpu.sleep(workstation, duration);
127 }
128
129 static void ws_action_suspend(surf_action_t action)
130 {
131   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
132     surf_network_model->suspend(action);
133   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
134     action->model_obj->suspend(action);
135   else
136     DIE_IMPOSSIBLE;
137 }
138
139 static void ws_action_resume(surf_action_t action)
140 {
141   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
142     surf_network_model->resume(action);
143   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
144     action->model_obj->resume(action);
145   else
146     DIE_IMPOSSIBLE;
147 }
148
149 static int ws_action_is_suspended(surf_action_t action)
150 {
151   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
152     return surf_network_model->is_suspended(action);
153   if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
154     return action->model_obj->is_suspended(action);
155   DIE_IMPOSSIBLE;
156   return -1;
157 }
158
159 static void ws_action_set_max_duration(surf_action_t action,
160                                        double duration)
161 {
162   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
163     surf_network_model->set_max_duration(action, duration);
164   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
165     action->model_obj->set_max_duration(action, duration);
166   else
167     DIE_IMPOSSIBLE;
168 }
169
170 static void ws_action_set_priority(surf_action_t action, double priority)
171 {
172   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
173     surf_network_model->set_priority(action, priority);
174   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
175     action->model_obj->set_priority(action, priority);
176   else
177     DIE_IMPOSSIBLE;
178 }
179
180 #ifdef HAVE_TRACING
181 static void ws_action_set_category(surf_action_t action, const char *category)
182 {
183   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
184     surf_network_model->set_category(action, category);
185   else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
186     action->model_obj->set_category(action, category);
187   else
188     DIE_IMPOSSIBLE;
189 }
190 #endif
191
192 #ifdef HAVE_LATENCY_BOUND_TRACKING
193 static int ws_get_latency_limited(surf_action_t action)
194 {
195   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
196     return surf_network_model->get_latency_limited(action);
197   else
198     return 0;
199 }
200 #endif
201
202 static double ws_action_get_remains(surf_action_t action)
203 {
204   if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
205     return surf_network_model->get_remains(action);
206   if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
207     return action->model_obj->get_remains(action);
208   DIE_IMPOSSIBLE;
209   return -1.0;
210 }
211
212 static surf_action_t ws_communicate(void *workstation_src,
213                                     void *workstation_dst, double size,
214                                     double rate)
215 {
216   workstation_CLM03_t src = surf_workstation_resource_priv(workstation_src);
217   workstation_CLM03_t dst = surf_workstation_resource_priv(workstation_dst);
218   return surf_network_model->extension.network.
219       communicate(src->net_elm,
220                   dst->net_elm, size, rate);
221 }
222
223 static e_surf_resource_state_t ws_get_state(void *workstation)
224 {
225   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
226   return cpu->model->extension.cpu.get_state(workstation);
227 }
228
229 static double ws_get_speed(void *workstation, double load)
230 {
231   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
232   return cpu->model->extension.cpu.get_speed(workstation, load);
233 }
234
235 static double ws_get_available_speed(void *workstation)
236 {
237   surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
238   return cpu->model->extension.cpu.get_available_speed(workstation);
239 }
240
241 static surf_action_t ws_execute_parallel_task(int workstation_nb,
242                                               void **workstation_list,
243                                               double *computation_amount,
244                                               double *communication_amount,
245                                               double rate)
246 {
247 #define cost_or_zero(array,pos) ((array)?(array)[pos]:0.0)
248   if ((workstation_nb == 1)
249       && (cost_or_zero(communication_amount, 0) == 0.0))
250     return ws_execute(workstation_list[0], computation_amount[0]);
251   else if ((workstation_nb == 1)
252            && (cost_or_zero(computation_amount, 0) == 0.0))
253     return ws_communicate(workstation_list[0], workstation_list[0],communication_amount[0], rate);
254   else if ((workstation_nb == 2)
255              && (cost_or_zero(computation_amount, 0) == 0.0)
256              && (cost_or_zero(computation_amount, 1) == 0.0)) {
257     int i,nb = 0;
258     double value = 0.0;
259
260     for (i = 0; i < workstation_nb * workstation_nb; i++) {
261       if (cost_or_zero(communication_amount, i) > 0.0) {
262         nb++;
263         value = cost_or_zero(communication_amount, i);
264       }
265     }
266     if (nb == 1)
267       return ws_communicate(workstation_list[0], workstation_list[1],value, rate);
268   }
269 #undef cost_or_zero
270
271   THROW_UNIMPLEMENTED;          /* This model does not implement parallel tasks */
272   return NULL;
273 }
274
275
276 /* returns an array of network_link_CM02_t */
277 static xbt_dynar_t ws_get_route(void *workstation_src, void *workstation_dst)
278 {
279   XBT_DEBUG("ws_get_route");
280   workstation_CLM03_t src = surf_workstation_resource_priv(workstation_src);
281   workstation_CLM03_t dst = surf_workstation_resource_priv(workstation_dst);
282   return surf_network_model->extension.
283       network.get_route(src->net_elm,
284                   dst->net_elm);
285 }
286
287 static double ws_get_link_bandwidth(const void *link)
288 {
289   return surf_network_model->extension.network.get_link_bandwidth(link);
290 }
291
292 static double ws_get_link_latency(const void *link)
293 {
294   return surf_network_model->extension.network.get_link_latency(link);
295 }
296
297 static int ws_link_shared(const void *link)
298 {
299   return surf_network_model->extension.network.link_shared(link);
300 }
301
302 static void ws_finalize(surf_model_t workstation_model)
303 {
304   surf_model_exit(workstation_model);
305   workstation_model = NULL;
306 }
307
308 static xbt_dict_t ws_get_properties(const void *ws)
309 {
310   return surf_resource_properties(surf_cpu_resource_priv(ws));
311 }
312
313 static storage_t find_storage_on_mount_list(void *workstation,const char* storage)
314 {
315   storage_t st = NULL;
316   s_mount_t mnt;
317   unsigned int cursor;
318   workstation_CLM03_t ws = (workstation_CLM03_t) surf_workstation_resource_priv(workstation);
319   xbt_dynar_t storage_list = ws->storage;
320
321   XBT_DEBUG("Search for storage name '%s' on '%s'",storage,ws->generic_resource.name);
322   xbt_dynar_foreach(storage_list,cursor,mnt)
323   {
324     XBT_DEBUG("See '%s'",mnt.name);
325     if(!strcmp(storage,mnt.name)){
326       st = mnt.id;
327       break;
328     }
329   }
330   if(!st) xbt_die("Can't find mount '%s' for '%s'",storage,ws->generic_resource.name);
331   return st;
332 }
333
334 static surf_action_t ws_action_open(void *workstation, const char* mount, const char* path, const char* mode)
335 {
336   storage_t st = find_storage_on_mount_list(workstation, mount);
337   XBT_DEBUG("OPEN on disk '%s'",st->generic_resource.name);
338   surf_model_t model = st->generic_resource.model;
339   return model->extension.storage.open(st, mount, path, mode);
340 }
341
342 static surf_action_t ws_action_close(void *workstation, surf_file_t fp)
343 {
344   storage_t st = find_storage_on_mount_list(workstation, fp->storage);
345   XBT_DEBUG("CLOSE on disk '%s'",st->generic_resource.name);
346   surf_model_t model = st->generic_resource.model;
347   return model->extension.storage.close(st, fp);
348 }
349
350 static surf_action_t ws_action_read(void *workstation, void* ptr, size_t size, size_t nmemb, surf_file_t stream)
351 {
352   storage_t st = find_storage_on_mount_list(workstation, stream->storage);
353   XBT_DEBUG("READ on disk '%s'",st->generic_resource.name);
354   surf_model_t model = st->generic_resource.model;
355   return model->extension.storage.read(st, ptr, (double)size, nmemb, stream);
356 }
357
358 static surf_action_t ws_action_write(void *workstation, const void* ptr, size_t size, size_t nmemb, surf_file_t stream)
359 {
360   storage_t st = find_storage_on_mount_list(workstation, stream->storage);
361   XBT_DEBUG("WRITE on disk '%s'",st->generic_resource.name);
362   surf_model_t model = st->generic_resource.model;
363   return model->extension.storage.write(st,  ptr, size, nmemb, stream);
364 }
365
366 static surf_action_t ws_action_stat(void *workstation, surf_file_t stream)
367 {
368   storage_t st = find_storage_on_mount_list(workstation, stream->storage);
369   XBT_DEBUG("STAT on disk '%s'",st->generic_resource.name);
370   surf_model_t model = st->generic_resource.model;
371   return model->extension.storage.stat(st,  stream);
372 }
373
374 static surf_action_t ws_action_unlink(void *workstation, surf_file_t stream)
375 {
376   storage_t st = find_storage_on_mount_list(workstation, stream->storage);
377   XBT_DEBUG("UNLINK on disk '%s'",st->generic_resource.name);
378   surf_model_t model = st->generic_resource.model;
379   return model->extension.storage.unlink(st,  stream);
380 }
381
382 static surf_action_t ws_action_ls(void *workstation, const char* mount, const char *path)
383 {
384   XBT_DEBUG("LS on mount '%s' and file '%s'",mount, path);
385   storage_t st = find_storage_on_mount_list(workstation, mount);
386   surf_model_t model = st->generic_resource.model;
387   return model->extension.storage.ls(st, path);
388 }
389
390 static void surf_workstation_model_init_internal(void)
391 {
392   surf_workstation_model = surf_model_init();
393
394   surf_workstation_model->name = "Workstation";
395   surf_workstation_model->type = SURF_MODEL_TYPE_WORKSTATION;
396   surf_workstation_model->action_unref = ws_action_unref;
397   surf_workstation_model->action_cancel = ws_action_cancel;
398   surf_workstation_model->action_state_set = ws_action_state_set;
399
400   surf_workstation_model->model_private->resource_used = ws_resource_used;
401   surf_workstation_model->model_private->share_resources =
402       ws_share_resources;
403   surf_workstation_model->model_private->update_actions_state =
404       ws_update_actions_state;
405   surf_workstation_model->model_private->update_resource_state =
406       ws_update_resource_state;
407   surf_workstation_model->model_private->finalize = ws_finalize;
408
409   surf_workstation_model->suspend = ws_action_suspend;
410   surf_workstation_model->resume = ws_action_resume;
411   surf_workstation_model->is_suspended = ws_action_is_suspended;
412   surf_workstation_model->set_max_duration = ws_action_set_max_duration;
413   surf_workstation_model->set_priority = ws_action_set_priority;
414 #ifdef HAVE_TRACING
415   surf_workstation_model->set_category = ws_action_set_category;
416 #endif
417   surf_workstation_model->get_remains = ws_action_get_remains;
418 #ifdef HAVE_LATENCY_BOUND_TRACKING
419   surf_workstation_model->get_latency_limited = ws_get_latency_limited;
420 #endif
421
422   /* For VM support, we have a surf cpu model object for each workstation model
423    * object. The physical workstation model object has the cpu model object of
424    * the physical machine layer. */
425   surf_workstation_model->extension.workstation.cpu_model = surf_cpu_model_pm;
426
427   surf_workstation_model->extension.workstation.execute = ws_execute;
428   surf_workstation_model->extension.workstation.sleep = ws_action_sleep;
429   surf_workstation_model->extension.workstation.get_state = ws_get_state;
430   surf_workstation_model->extension.workstation.get_speed = ws_get_speed;
431   surf_workstation_model->extension.workstation.get_available_speed =
432       ws_get_available_speed;
433
434   surf_workstation_model->extension.workstation.communicate =
435       ws_communicate;
436   surf_workstation_model->extension.workstation.get_route = ws_get_route;
437   surf_workstation_model->extension.workstation.execute_parallel_task =
438       ws_execute_parallel_task;
439   surf_workstation_model->extension.workstation.get_link_bandwidth =
440       ws_get_link_bandwidth;
441   surf_workstation_model->extension.workstation.get_link_latency =
442       ws_get_link_latency;
443   surf_workstation_model->extension.workstation.link_shared =
444       ws_link_shared;
445   surf_workstation_model->extension.workstation.get_properties =
446       ws_get_properties;
447
448   surf_workstation_model->extension.workstation.open = ws_action_open;
449   surf_workstation_model->extension.workstation.close = ws_action_close;
450   surf_workstation_model->extension.workstation.read = ws_action_read;
451   surf_workstation_model->extension.workstation.write = ws_action_write;
452   surf_workstation_model->extension.workstation.stat = ws_action_stat;
453   surf_workstation_model->extension.workstation.unlink = ws_action_unlink;
454   surf_workstation_model->extension.workstation.ls = ws_action_ls;
455 }
456
457 void surf_workstation_model_init_current_default(void)
458 {
459
460   surf_workstation_model_init_internal();
461
462   xbt_cfg_setdefault_int(_sg_cfg_set, "network/crosstraffic", 1);
463   surf_network_model_init_LegrandVelho();
464
465   xbt_dynar_push(model_list, &surf_workstation_model);
466   xbt_dynar_push(model_list_invoke, &surf_workstation_model);
467   sg_platf_host_add_cb(workstation_new);
468 //  sg_platf_postparse_add_cb(create_workstations);
469 }
470
471 void surf_workstation_model_init_compound()
472 {
473
474   xbt_assert(surf_cpu_model_pm, "No CPU model defined yet!");
475   xbt_assert(surf_network_model, "No network model defined yet!");
476   surf_workstation_model_init_internal();
477   xbt_dynar_push(model_list, &surf_workstation_model);
478   xbt_dynar_push(model_list_invoke, &surf_workstation_model);
479   sg_platf_host_add_cb(workstation_new);
480 //  sg_platf_postparse_add_cb(create_workstations);
481 }