Logo AND Algorithmique Numérique Distribuée

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