3 /* Copyright (c) 2004 Arnaud Legrand. All rights reserved. */
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. */
10 #include "gras_config.h"
11 #include "workstation_private.h"
12 #include "cpu_private.h"
13 #include "network_private.h"
15 surf_workstation_model_t surf_workstation_model = NULL;
16 xbt_dict_t workstation_set = NULL;
17 static xbt_dict_t parallel_task_network_link_set = NULL;
19 static workstation_CLM03_t workstation_new(const char *name,
20 void *cpu, void *card)
22 workstation_CLM03_t workstation = xbt_new0(s_workstation_CLM03_t, 1);
24 workstation->model = (surf_model_t) surf_workstation_model;
25 workstation->name = xbt_strdup(name);
26 workstation->cpu = cpu;
27 workstation->network_card = card;
32 static void workstation_free(void *workstation)
34 free(((workstation_CLM03_t) workstation)->name);
38 static void create_workstations(void)
40 xbt_dict_cursor_t cursor = NULL;
45 xbt_dict_foreach(cpu_set, cursor, name, cpu) {
46 nw_card = xbt_dict_get_or_null(network_card_set, name);
47 xbt_assert1(nw_card, "No corresponding card found for %s", name);
49 xbt_dict_set(workstation_set, name,
50 workstation_new(name, cpu, nw_card), workstation_free);
54 static void *name_service(const char *name)
56 return xbt_dict_get_or_null(workstation_set, name);
59 static const char *get_model_name(void *model_id)
61 return ((workstation_CLM03_t) model_id)->name;
64 static int model_used(void *model_id)
67 "Workstation is a virtual model. I should not be there!");
71 static int parallel_action_free(surf_action_t action)
75 xbt_swag_remove(action, action->state_set);
76 if (((surf_action_parallel_task_CSL05_t) action)->variable)
77 lmm_variable_free(maxmin_system,
78 ((surf_action_parallel_task_CSL05_t) action)->
86 static void parallel_action_use(surf_action_t action)
91 static int action_free(surf_action_t action)
93 if (action->model_type == (surf_model_t) surf_network_model)
94 return surf_network_model->common_public->action_free(action);
95 else if (action->model_type == (surf_model_t) surf_cpu_model)
96 return surf_cpu_model->common_public->action_free(action);
97 else if (action->model_type ==
98 (surf_model_t) surf_workstation_model)
99 return parallel_action_free(action);
105 static void action_use(surf_action_t action)
107 if (action->model_type == (surf_model_t) surf_network_model)
108 surf_network_model->common_public->action_use(action);
109 else if (action->model_type == (surf_model_t) surf_cpu_model)
110 surf_cpu_model->common_public->action_use(action);
111 else if (action->model_type ==
112 (surf_model_t) surf_workstation_model)
113 parallel_action_use(action);
119 static void action_cancel(surf_action_t action)
121 if (action->model_type == (surf_model_t) surf_network_model)
122 surf_network_model->common_public->action_cancel(action);
123 else if (action->model_type == (surf_model_t) surf_cpu_model)
124 surf_cpu_model->common_public->action_cancel(action);
125 else if (action->model_type ==
126 (surf_model_t) surf_workstation_model)
127 parallel_action_use(action);
133 static void action_recycle(surf_action_t action)
139 static void action_change_state(surf_action_t action,
140 e_surf_action_state_t state)
142 if (action->model_type == (surf_model_t) surf_network_model)
143 surf_network_model->common_public->action_change_state(action,
145 else if (action->model_type == (surf_model_t) surf_cpu_model)
146 surf_cpu_model->common_public->action_change_state(action, state);
147 else if (action->model_type ==
148 (surf_model_t) surf_workstation_model)
149 surf_action_change_state(action, state);
155 static double share_models(double now)
157 s_surf_action_parallel_task_CSL05_t action;
158 return generic_maxmin_share_models(surf_workstation_model->
159 common_public->states.
161 xbt_swag_offset(action, variable));
164 static void update_actions_state(double now, double delta)
166 surf_action_parallel_task_CSL05_t action = NULL;
167 surf_action_parallel_task_CSL05_t next_action = NULL;
168 xbt_swag_t running_actions =
169 surf_workstation_model->common_public->states.running_action_set;
171 xbt_swag_t failed_actions =
172 surf_workstation_model->common_public->states.failed_action_set;
175 xbt_swag_foreach_safe(action, next_action, running_actions) {
176 double_update(&(action->generic_action.remains),
177 lmm_variable_getvalue(action->variable) * delta);
178 if (action->generic_action.max_duration != NO_MAX_DURATION)
179 double_update(&(action->generic_action.max_duration), delta);
180 if ((action->generic_action.remains <= 0) &&
181 (lmm_get_variable_weight(action->variable) > 0)) {
182 action->generic_action.finish = surf_get_clock();
183 action_change_state((surf_action_t) action, SURF_ACTION_DONE);
184 } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
185 (action->generic_action.max_duration <= 0)) {
186 action->generic_action.finish = surf_get_clock();
187 action_change_state((surf_action_t) action, SURF_ACTION_DONE);
188 } else { /* Need to check that none of the model has failed */
189 lmm_constraint_t cnst = NULL;
191 surf_model_t model = NULL;
194 lmm_get_cnst_from_var(maxmin_system, action->variable,
196 model = (surf_model_t) lmm_constraint_id(cnst);
197 if (model == (surf_model_t) surf_cpu_model) {
198 cpu_Cas01_t cpu = lmm_constraint_id(cnst);
199 if (cpu->state_current == SURF_CPU_OFF) {
200 action->generic_action.finish = surf_get_clock();
201 action_change_state((surf_action_t) action,
205 } else if (model == (surf_model_t) surf_network_model) {
206 network_link_CM02_t nw_link = lmm_constraint_id(cnst);
208 if (nw_link->state_current == SURF_NETWORK_LINK_OFF) {
209 action->generic_action.finish = surf_get_clock();
210 action_change_state((surf_action_t) action,
222 static void update_model_state(void *id,
223 tmgr_trace_event_t event_type,
229 static surf_action_t execute(void *workstation, double size)
231 return surf_cpu_model->extension_public->
232 execute(((workstation_CLM03_t) workstation)->cpu, size);
235 static surf_action_t action_sleep(void *workstation, double duration)
237 return surf_cpu_model->extension_public->
238 sleep(((workstation_CLM03_t) workstation)->cpu, duration);
241 static void action_suspend(surf_action_t action)
243 if (action->model_type == (surf_model_t) surf_network_model)
244 surf_network_model->common_public->suspend(action);
245 else if (action->model_type == (surf_model_t) surf_cpu_model)
246 surf_cpu_model->common_public->suspend(action);
251 static void action_resume(surf_action_t action)
253 if (action->model_type == (surf_model_t) surf_network_model)
254 surf_network_model->common_public->resume(action);
255 else if (action->model_type == (surf_model_t) surf_cpu_model)
256 surf_cpu_model->common_public->resume(action);
261 static int action_is_suspended(surf_action_t action)
263 if (action->model_type == (surf_model_t) surf_network_model)
264 return surf_network_model->common_public->is_suspended(action);
265 if (action->model_type == (surf_model_t) surf_cpu_model)
266 return surf_cpu_model->common_public->is_suspended(action);
270 static void action_set_max_duration(surf_action_t action, double duration)
272 if (action->model_type == (surf_model_t) surf_network_model)
273 surf_network_model->common_public->set_max_duration(action,
275 else if (action->model_type == (surf_model_t) surf_cpu_model)
276 surf_cpu_model->common_public->set_max_duration(action, duration);
281 static void action_set_priority(surf_action_t action, double priority)
283 if (action->model_type == (surf_model_t) surf_network_model)
284 surf_network_model->common_public->set_priority(action, priority);
285 else if (action->model_type == (surf_model_t) surf_cpu_model)
286 surf_cpu_model->common_public->set_priority(action, priority);
291 static surf_action_t communicate(void *workstation_src,
292 void *workstation_dst, double size,
295 return surf_network_model->extension_public->
296 communicate(((workstation_CLM03_t) workstation_src)->network_card,
297 ((workstation_CLM03_t) workstation_dst)->network_card,
301 static e_surf_cpu_state_t get_state(void *workstation)
303 return surf_cpu_model->extension_public->
304 get_state(((workstation_CLM03_t) workstation)->cpu);
307 static double get_speed(void *workstation, double load)
309 return surf_cpu_model->extension_public->
310 get_speed(((workstation_CLM03_t) workstation)->cpu, load);
313 static double get_available_speed(void *workstation)
315 return surf_cpu_model->extension_public->
316 get_available_speed(((workstation_CLM03_t) workstation)->cpu);
319 static surf_action_t execute_parallel_task_bogus(int workstation_nb,
320 void **workstation_list,
324 *communication_amount,
328 xbt_assert0(0, "This model does not implement parallel tasks");
331 static surf_action_t execute_parallel_task(int workstation_nb,
332 void **workstation_list,
333 double *computation_amount,
334 double *communication_amount,
335 double amount, double rate)
337 surf_action_parallel_task_CSL05_t action = NULL;
342 if (parallel_task_network_link_set == NULL) {
343 parallel_task_network_link_set =
344 xbt_dict_new_ext(workstation_nb * workstation_nb * 10);
347 /* Compute the number of affected models... */
348 for (i = 0; i < workstation_nb; i++) {
349 for (j = 0; j < workstation_nb; j++) {
350 network_card_CM02_t card_src =
351 ((workstation_CLM03_t *) workstation_list)[i]->network_card;
352 network_card_CM02_t card_dst =
353 ((workstation_CLM03_t *) workstation_list)[j]->network_card;
354 int route_size = ROUTE_SIZE(card_src->id, card_dst->id);
355 network_link_CM02_t *route = ROUTE(card_src->id, card_dst->id);
357 if (communication_amount[i * workstation_nb + j] > 0)
358 for (k = 0; k < route_size; k++) {
359 xbt_dict_set(parallel_task_network_link_set, route[k]->name,
365 nb_link = xbt_dict_length(parallel_task_network_link_set);
366 xbt_dict_reset(parallel_task_network_link_set);
368 for (i = 0; i < workstation_nb; i++)
369 if (computation_amount[i] > 0)
372 if (nb_link + workstation_nb == 0)
375 action = xbt_new0(s_surf_action_parallel_task_CSL05_t, 1);
376 action->generic_action.using = 1;
377 action->generic_action.cost = amount;
378 action->generic_action.remains = amount;
379 action->generic_action.max_duration = NO_MAX_DURATION;
380 action->generic_action.start = surf_get_clock();
381 action->generic_action.finish = -1.0;
382 action->generic_action.model_type =
383 (surf_model_t) surf_workstation_model;
384 action->suspended = 0; /* Should be useless because of the
385 calloc but it seems to help valgrind... */
386 action->generic_action.state_set =
387 surf_workstation_model->common_public->states.running_action_set;
389 xbt_swag_insert(action, action->generic_action.state_set);
392 if (action->rate > 0)
393 action->variable = lmm_variable_new(maxmin_system, action, 1.0, -1.0,
397 lmm_variable_new(maxmin_system, action, 1.0, action->rate,
400 for (i = 0; i < workstation_nb; i++)
401 if (computation_amount[i] > 0)
402 lmm_expand(maxmin_system,
404 ((workstation_CLM03_t) workstation_list[i])->cpu)->
405 constraint, action->variable, computation_amount[i]);
407 for (i = 0; i < workstation_nb; i++) {
408 for (j = 0; j < workstation_nb; j++) {
409 network_card_CM02_t card_src =
410 ((workstation_CLM03_t *) workstation_list)[i]->network_card;
411 network_card_CM02_t card_dst =
412 ((workstation_CLM03_t *) workstation_list)[j]->network_card;
413 int route_size = ROUTE_SIZE(card_src->id, card_dst->id);
414 network_link_CM02_t *route = ROUTE(card_src->id, card_dst->id);
416 for (k = 0; k < route_size; k++) {
417 if (communication_amount[i * workstation_nb + j] > 0) {
418 lmm_expand_add(maxmin_system, route[k]->constraint,
420 communication_amount[i * workstation_nb + j]);
426 return (surf_action_t) action;
429 /* returns an array of network_link_CM02_t */
430 static const void **get_route(void *src, void *dst)
432 workstation_CLM03_t workstation_src = (workstation_CLM03_t) src;
433 workstation_CLM03_t workstation_dst = (workstation_CLM03_t) dst;
434 return surf_network_model->extension_public->
435 get_route(workstation_src->network_card,
436 workstation_dst->network_card);
439 static int get_route_size(void *src, void *dst)
441 workstation_CLM03_t workstation_src = (workstation_CLM03_t) src;
442 workstation_CLM03_t workstation_dst = (workstation_CLM03_t) dst;
443 return surf_network_model->extension_public->
444 get_route_size(workstation_src->network_card,
445 workstation_dst->network_card);
448 static const char *get_link_name(const void *link)
450 return surf_network_model->extension_public->get_link_name(link);
453 static double get_link_bandwidth(const void *link)
455 return surf_network_model->extension_public->get_link_bandwidth(link);
458 static double get_link_latency(const void *link)
460 return surf_network_model->extension_public->get_link_latency(link);
463 static void finalize(void)
465 xbt_dict_free(&workstation_set);
466 xbt_swag_free(surf_workstation_model->common_public->states.
468 xbt_swag_free(surf_workstation_model->common_public->states.
470 xbt_swag_free(surf_workstation_model->common_public->states.
472 xbt_swag_free(surf_workstation_model->common_public->states.
475 free(surf_workstation_model->common_public);
476 free(surf_workstation_model->common_private);
477 free(surf_workstation_model->extension_public);
479 free(surf_workstation_model);
480 surf_workstation_model = NULL;
483 static void surf_workstation_model_init_internal(void)
485 s_surf_action_t action;
487 surf_workstation_model = xbt_new0(s_surf_workstation_model_t, 1);
489 surf_workstation_model->common_private =
490 xbt_new0(s_surf_model_private_t, 1);
491 surf_workstation_model->common_public =
492 xbt_new0(s_surf_model_public_t, 1);
493 /* surf_workstation_model->extension_private = xbt_new0(s_surf_workstation_model_extension_private_t,1); */
494 surf_workstation_model->extension_public =
495 xbt_new0(s_surf_workstation_model_extension_public_t, 1);
497 surf_workstation_model->common_public->states.ready_action_set =
498 xbt_swag_new(xbt_swag_offset(action, state_hookup));
499 surf_workstation_model->common_public->states.running_action_set =
500 xbt_swag_new(xbt_swag_offset(action, state_hookup));
501 surf_workstation_model->common_public->states.failed_action_set =
502 xbt_swag_new(xbt_swag_offset(action, state_hookup));
503 surf_workstation_model->common_public->states.done_action_set =
504 xbt_swag_new(xbt_swag_offset(action, state_hookup));
506 surf_workstation_model->common_public->name_service = name_service;
507 surf_workstation_model->common_public->get_model_name =
509 surf_workstation_model->common_public->action_get_state =
510 surf_action_get_state;
511 surf_workstation_model->common_public->action_get_start_time =
512 surf_action_get_start_time;
513 surf_workstation_model->common_public->action_get_finish_time =
514 surf_action_get_finish_time;
515 surf_workstation_model->common_public->action_free = action_free;
516 surf_workstation_model->common_public->action_use = action_use;
517 surf_workstation_model->common_public->action_cancel = action_cancel;
518 surf_workstation_model->common_public->action_recycle =
520 surf_workstation_model->common_public->action_change_state =
522 surf_workstation_model->common_public->action_set_data =
523 surf_action_set_data;
524 surf_workstation_model->common_public->name = "Workstation";
526 surf_workstation_model->common_private->model_used = model_used;
527 surf_workstation_model->common_private->share_models =
529 surf_workstation_model->common_private->update_actions_state =
530 update_actions_state;
531 surf_workstation_model->common_private->update_model_state =
533 surf_workstation_model->common_private->finalize = finalize;
535 surf_workstation_model->common_public->suspend = action_suspend;
536 surf_workstation_model->common_public->resume = action_resume;
537 surf_workstation_model->common_public->is_suspended =
539 surf_workstation_model->common_public->set_max_duration =
540 action_set_max_duration;
541 surf_workstation_model->common_public->set_priority =
544 surf_workstation_model->extension_public->execute = execute;
545 surf_workstation_model->extension_public->sleep = action_sleep;
546 surf_workstation_model->extension_public->get_state = get_state;
547 surf_workstation_model->extension_public->get_speed = get_speed;
548 surf_workstation_model->extension_public->get_available_speed =
550 surf_workstation_model->extension_public->communicate = communicate;
551 surf_workstation_model->extension_public->execute_parallel_task =
552 execute_parallel_task_bogus;
553 surf_workstation_model->extension_public->get_route = get_route;
554 surf_workstation_model->extension_public->get_route_size =
556 surf_workstation_model->extension_public->get_link_name =
558 surf_workstation_model->extension_public->get_link_bandwidth =
560 surf_workstation_model->extension_public->get_link_latency =
562 workstation_set = xbt_dict_new();
564 xbt_assert0(maxmin_system, "surf_init has to be called first!");
567 /********************************************************************/
568 /* The model used in MSG and presented at CCGrid03 */
569 /********************************************************************/
570 /* @InProceedings{Casanova.CLM_03, */
571 /* author = {Henri Casanova and Arnaud Legrand and Loris Marchal}, */
572 /* title = {Scheduling Distributed Applications: the SimGrid Simulation Framework}, */
573 /* booktitle = {Proceedings of the third IEEE International Symposium on Cluster Computing and the Grid (CCGrid'03)}, */
574 /* publisher = {"IEEE Computer Society Press"}, */
578 void surf_workstation_model_init_CLM03(const char *filename)
580 surf_workstation_model_init_internal();
581 surf_cpu_model_init_Cas01(filename);
582 surf_network_model_init_CM02(filename);
583 create_workstations();
584 update_model_description(surf_workstation_model_description,
585 surf_workstation_model_description_size,
587 (surf_model_t) surf_workstation_model);
588 xbt_dynar_push(model_list, &surf_workstation_model);
591 void surf_workstation_model_init_compound(const char *filename)
594 xbt_assert0(surf_cpu_model, "No CPU model defined yet!");
595 xbt_assert0(surf_network_model, "No network model defined yet!");
596 surf_workstation_model_init_internal();
597 create_workstations();
599 update_model_description(surf_workstation_model_description,
600 surf_workstation_model_description_size,
602 (surf_model_t) surf_workstation_model);
604 xbt_dynar_push(model_list, &surf_workstation_model);