1 /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
2 * All rights reserved. */
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. */
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"
16 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf,
17 "Logging specific to the SURF workstation module");
19 surf_model_t surf_workstation_model = NULL;
22 void __init_workstation_CLM03(workstation_CLM03_t ws, const char *id, surf_model_t workstation_model)
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);
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);
33 static void workstation_new(sg_platf_host_cbarg_t host)
35 workstation_CLM03_t workstation = xbt_new0(s_workstation_CLM03_t, 1);
37 __init_workstation_CLM03(workstation, host->id, surf_workstation_model);
40 static int ws_resource_used(void *resource_id)
42 THROW_IMPOSSIBLE; /* This model does not implement parallel tasks */
46 static void ws_parallel_action_cancel(surf_action_t action)
48 THROW_UNIMPLEMENTED; /* This model does not implement parallel tasks */
51 static int ws_parallel_action_free(surf_action_t action)
53 THROW_UNIMPLEMENTED; /* This model does not implement parallel tasks */
57 static int ws_action_unref(surf_action_t action)
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);
72 static void ws_action_cancel(surf_action_t action)
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);
85 static void ws_action_state_set(surf_action_t action,
86 e_surf_action_state_t state)
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);
99 static double ws_share_resources(surf_model_t workstation_model, double now)
101 // invoke share_resources on CPU and network (layer 0)
105 static void ws_update_actions_state(surf_model_t workstation_model, double now, double delta)
110 static void ws_update_resource_state(void *id,
111 tmgr_trace_event_t event_type,
112 double value, double date)
114 THROW_IMPOSSIBLE; /* This model does not implement parallel tasks */
117 static surf_action_t ws_execute(void *workstation, double size)
119 surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
120 return cpu->model->extension.cpu.execute(workstation, size);
123 static surf_action_t ws_action_sleep(void *workstation, double duration)
125 surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
126 return cpu->model->extension.cpu.sleep(workstation, duration);
129 static void ws_action_suspend(surf_action_t action)
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);
139 static void ws_action_resume(surf_action_t action)
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);
149 static int ws_action_is_suspended(surf_action_t action)
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);
159 static void ws_action_set_max_duration(surf_action_t action,
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);
170 static void ws_action_set_priority(surf_action_t action, double priority)
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);
181 static void ws_action_set_category(surf_action_t action, const char *category)
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);
192 #ifdef HAVE_LATENCY_BOUND_TRACKING
193 static int ws_get_latency_limited(surf_action_t action)
195 if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
196 return surf_network_model->get_latency_limited(action);
202 static double ws_action_get_remains(surf_action_t action)
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);
212 static surf_action_t ws_communicate(void *workstation_src,
213 void *workstation_dst, double size,
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);
223 static e_surf_resource_state_t ws_get_state(void *workstation)
225 surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
226 return cpu->model->extension.cpu.get_state(workstation);
229 static double ws_get_speed(void *workstation, double load)
231 surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
232 return cpu->model->extension.cpu.get_speed(workstation, load);
235 static double ws_get_available_speed(void *workstation)
237 surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
238 return cpu->model->extension.cpu.get_available_speed(workstation);
241 static surf_action_t ws_execute_parallel_task(int workstation_nb,
242 void **workstation_list,
243 double *computation_amount,
244 double *communication_amount,
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)) {
260 for (i = 0; i < workstation_nb * workstation_nb; i++) {
261 if (cost_or_zero(communication_amount, i) > 0.0) {
263 value = cost_or_zero(communication_amount, i);
267 return ws_communicate(workstation_list[0], workstation_list[1],value, rate);
271 THROW_UNIMPLEMENTED; /* This model does not implement parallel tasks */
276 /* returns an array of network_link_CM02_t */
277 static xbt_dynar_t ws_get_route(void *workstation_src, void *workstation_dst)
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,
287 static double ws_get_link_bandwidth(const void *link)
289 return surf_network_model->extension.network.get_link_bandwidth(link);
292 static double ws_get_link_latency(const void *link)
294 return surf_network_model->extension.network.get_link_latency(link);
297 static int ws_link_shared(const void *link)
299 return surf_network_model->extension.network.link_shared(link);
302 static void ws_finalize(surf_model_t workstation_model)
304 surf_model_exit(workstation_model);
305 workstation_model = NULL;
308 static xbt_dict_t ws_get_properties(const void *ws)
310 return surf_resource_properties(surf_cpu_resource_priv(ws));
313 static storage_t find_storage_on_mount_list(void *workstation,const char* storage)
318 workstation_CLM03_t ws = (workstation_CLM03_t) surf_workstation_resource_priv(workstation);
319 xbt_dynar_t storage_list = ws->storage;
321 XBT_DEBUG("Search for storage name '%s' on '%s'",storage,ws->generic_resource.name);
322 xbt_dynar_foreach(storage_list,cursor,mnt)
324 XBT_DEBUG("See '%s'",mnt.name);
325 if(!strcmp(storage,mnt.name)){
330 if(!st) xbt_die("Can't find mount '%s' for '%s'",storage,ws->generic_resource.name);
334 static surf_action_t ws_action_open(void *workstation, const char* mount, const char* path, const char* mode)
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);
342 static surf_action_t ws_action_close(void *workstation, surf_file_t fp)
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);
350 static surf_action_t ws_action_read(void *workstation, void* ptr, size_t size, size_t nmemb, surf_file_t stream)
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);
358 static surf_action_t ws_action_write(void *workstation, const void* ptr, size_t size, size_t nmemb, surf_file_t stream)
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);
366 static surf_action_t ws_action_stat(void *workstation, surf_file_t stream)
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);
374 static surf_action_t ws_action_unlink(void *workstation, surf_file_t stream)
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);
382 static surf_action_t ws_action_ls(void *workstation, const char* mount, const char *path)
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);
390 static void surf_workstation_model_init_internal(void)
392 surf_workstation_model = surf_model_init();
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;
400 surf_workstation_model->model_private->resource_used = ws_resource_used;
401 surf_workstation_model->model_private->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;
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;
415 surf_workstation_model->set_category = ws_action_set_category;
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;
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;
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;
434 surf_workstation_model->extension.workstation.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 =
443 surf_workstation_model->extension.workstation.link_shared =
445 surf_workstation_model->extension.workstation.get_properties =
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;
457 void surf_workstation_model_init_current_default(void)
460 surf_workstation_model_init_internal();
462 xbt_cfg_setdefault_int(_sg_cfg_set, "network/crosstraffic", 1);
463 surf_network_model_init_LegrandVelho();
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);
471 void surf_workstation_model_init_compound()
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);