3 /* Copyright (c) 2005 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 "surf_private.h"
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf,
13 "Logging specific to the SURF workstation module (KCCFLN05)");
16 SURF_WORKSTATION_RESOURCE_CPU,
17 SURF_WORKSTATION_RESOURCE_LINK,
18 } e_surf_workstation_model_type_t;
21 /**************************************/
22 /********* router object **************/
23 /**************************************/
24 typedef struct router_KCCFLN05 {
27 } s_router_KCCFLN05_t, *router_KCCFLN05_t;
30 /**************************************/
31 /********* cpu object *****************/
32 /**************************************/
33 typedef struct cpu_KCCFLN05 {
34 surf_model_t model; /* Do not move this field: must match model_obj_t */
35 xbt_dict_t properties; /* Do not move this field: must match link_KCCFLN05_t */
36 e_surf_workstation_model_type_t type; /* Do not move this field: must match link_KCCFLN05_t */
37 char *name; /* Do not move this field: must match link_KCCFLN05_t */
38 lmm_constraint_t constraint;
42 double interference_send;
43 double interference_recv;
44 double interference_send_recv;
45 tmgr_trace_event_t power_event;
46 e_surf_cpu_state_t state_current;
47 tmgr_trace_event_t state_event;
48 int id; /* cpu and network card are a single object... */
49 xbt_dynar_t incomming_communications;
50 xbt_dynar_t outgoing_communications;
51 } s_cpu_KCCFLN05_t, *cpu_KCCFLN05_t;
53 /**************************************/
54 /*********** network object ***********/
55 /**************************************/
57 typedef struct link_KCCFLN05 {
58 surf_model_t model; /* Do not move this field: must match model_obj_t */
59 xbt_dict_t properties; /* Do not move this field: must match cpu_KCCFLN05_t */
60 e_surf_workstation_model_type_t type; /* Do not move this field: must match cpu_KCCFLN05_t */
61 char *name; /* Do not move this field: must match cpu_KCCFLN05_t */
62 lmm_constraint_t constraint;
64 tmgr_trace_event_t lat_event;
66 tmgr_trace_event_t bw_event;
67 e_surf_link_state_t state_current;
68 tmgr_trace_event_t state_event;
69 } s_link_KCCFLN05_t, *link_KCCFLN05_t;
72 typedef struct s_route_KCCFLN05 {
75 double impact_on_src_with_other_recv;
76 double impact_on_dst_with_other_send;
77 link_KCCFLN05_t *links;
79 } s_route_KCCFLN05_t, *route_KCCFLN05_t;
81 /**************************************/
82 /*************** actions **************/
83 /**************************************/
84 typedef struct surf_action_workstation_KCCFLN05 {
85 s_surf_action_t generic_action;
88 lmm_variable_t variable;
91 cpu_KCCFLN05_t src; /* could be avoided */
92 cpu_KCCFLN05_t dst; /* could be avoided */
93 } s_surf_action_workstation_KCCFLN05_t,
94 *surf_action_workstation_KCCFLN05_t;
98 static int nb_workstation = 0;
99 static s_route_KCCFLN05_t *routing_table = NULL;
100 #define ROUTE(i,j) routing_table[(i)+(j)*nb_workstation]
101 static link_KCCFLN05_t loopback = NULL;
102 static xbt_dict_t parallel_task_link_set = NULL;
103 //added to work with GTNETS
104 static xbt_dict_t router_set = NULL;
105 static lmm_system_t maxmin_system = NULL;
108 /* convenient function */
109 static void __update_cpu_usage(cpu_KCCFLN05_t cpu)
112 surf_action_workstation_KCCFLN05_t action = NULL;
113 if ((!xbt_dynar_length(cpu->incomming_communications)) &&
114 (!xbt_dynar_length(cpu->outgoing_communications))) {
115 /* No communications */
116 lmm_update_constraint_bound(maxmin_system, cpu->constraint,
117 cpu->power_current * cpu->power_scale);
118 } else if ((!xbt_dynar_length(cpu->incomming_communications))
119 && (xbt_dynar_length(cpu->outgoing_communications))) {
121 lmm_update_constraint_bound(maxmin_system, cpu->constraint,
122 cpu->power_current * cpu->power_scale *
123 cpu->interference_send);
124 xbt_dynar_foreach(cpu->outgoing_communications, cpt, action)
125 lmm_elem_set_value(maxmin_system, cpu->constraint,
127 cpu->power_current * cpu->power_scale *
128 ROUTE(action->src->id,
129 action->dst->id).impact_on_src);
130 } else if ((xbt_dynar_length(cpu->incomming_communications))
131 && (!xbt_dynar_length(cpu->outgoing_communications))) {
133 lmm_update_constraint_bound(maxmin_system, cpu->constraint,
134 cpu->power_current * cpu->power_scale *
135 cpu->interference_recv);
136 xbt_dynar_foreach(cpu->incomming_communications, cpt, action)
137 lmm_elem_set_value(maxmin_system, cpu->constraint,
139 cpu->power_current * cpu->power_scale *
140 ROUTE(action->src->id,
141 action->dst->id).impact_on_dst);
143 /* Emission & Reception */
144 lmm_update_constraint_bound(maxmin_system, cpu->constraint,
145 cpu->power_current * cpu->power_scale *
146 cpu->interference_send_recv);
147 xbt_dynar_foreach(cpu->outgoing_communications, cpt, action)
148 lmm_elem_set_value(maxmin_system, cpu->constraint,
150 cpu->power_current * cpu->power_scale *
151 ROUTE(action->src->id,
153 impact_on_src_with_other_recv);
154 xbt_dynar_foreach(cpu->incomming_communications, cpt, action)
155 lmm_elem_set_value(maxmin_system, cpu->constraint,
157 cpu->power_current * cpu->power_scale *
158 ROUTE(action->src->id,
160 impact_on_dst_with_other_send);
164 /**************************************/
165 /******* Resource Public **********/
166 /**************************************/
168 static void *name_service(const char *name)
174 res = xbt_dict_get(workstation_set, name);
176 if (e.category != not_found_error)
178 WARN1("Host '%s' not found, verifing if it is a router", name);
186 static const char *get_resource_name(void *resource_id)
188 /* We can freely cast as a cpu_KCCFLN05_t because it has the same
189 prefix as link_KCCFLN05_t. However, only cpu_KCCFLN05_t
190 will theoretically be given as an argument here. */
191 return ((cpu_KCCFLN05_t) resource_id)->name;
194 static xbt_dict_t get_properties(void *resource)
196 /* We can freely cast as a cpu_KCCFLN05_t because it has the same
197 prefix as link_KCCFLN05_t. */
198 return ((cpu_KCCFLN05_t) resource)->properties;
201 /* action_get_state is inherited from the surf module */
203 static void action_use(surf_action_t action)
209 static int action_free(surf_action_t action)
212 surf_action_t act = NULL;
213 cpu_KCCFLN05_t src = ((surf_action_workstation_KCCFLN05_t) action)->src;
214 cpu_KCCFLN05_t dst = ((surf_action_workstation_KCCFLN05_t) action)->dst;
217 if (!action->using) {
218 xbt_swag_remove(action, action->state_set);
219 if (((surf_action_workstation_KCCFLN05_t) action)->variable)
220 lmm_variable_free(maxmin_system,
221 ((surf_action_workstation_KCCFLN05_t) action)->
224 xbt_dynar_foreach(src->outgoing_communications, cpt, act)
226 xbt_dynar_remove_at(src->outgoing_communications, cpt, &act);
231 xbt_dynar_foreach(dst->incomming_communications, cpt, act)
233 xbt_dynar_remove_at(dst->incomming_communications, cpt, &act);
237 if (src && (!xbt_dynar_length(src->outgoing_communications)))
238 __update_cpu_usage(src);
239 if (dst && (!xbt_dynar_length(dst->incomming_communications)))
240 __update_cpu_usage(dst);
248 static void action_cancel(surf_action_t action)
250 surf_action_change_state(action, SURF_ACTION_FAILED);
254 static void action_recycle(surf_action_t action)
260 /* action_change_state is inherited from the surf module */
261 /* action_set_data is inherited from the surf module */
263 static void action_suspend(surf_action_t action)
265 XBT_IN1("(%p))", action);
266 if (((surf_action_workstation_KCCFLN05_t) action)->suspended != 2) {
267 ((surf_action_workstation_KCCFLN05_t) action)->suspended = 1;
268 lmm_update_variable_weight(maxmin_system,
269 ((surf_action_workstation_KCCFLN05_t)
270 action)->variable, 0.0);
275 static void action_resume(surf_action_t action)
277 XBT_IN1("(%p)", action);
278 if (((surf_action_workstation_KCCFLN05_t) action)->suspended != 2) {
279 if (((surf_action_workstation_KCCFLN05_t) action)->lat_current == 0.0)
280 lmm_update_variable_weight(maxmin_system,
281 ((surf_action_workstation_KCCFLN05_t)
282 action)->variable, action->priority);
284 lmm_update_variable_weight(maxmin_system,
285 ((surf_action_workstation_KCCFLN05_t)
287 ((surf_action_workstation_KCCFLN05_t)
288 action)->lat_current);
290 ((surf_action_workstation_KCCFLN05_t) action)->suspended = 0;
295 static int action_is_suspended(surf_action_t action)
297 return (((surf_action_workstation_KCCFLN05_t) action)->suspended == 1);
300 static void action_set_max_duration(surf_action_t action, double duration)
301 { /* FIXME: should inherit */
302 XBT_IN2("(%p,%g)", action, duration);
303 action->max_duration = duration;
308 static void action_set_priority(surf_action_t action, double priority)
310 XBT_IN2("(%p,%g)", action, priority);
311 action->priority = priority;
312 lmm_update_variable_weight(maxmin_system, ((surf_action_workstation_KCCFLN05_t) action)->variable, priority);
317 /**************************************/
318 /******* Resource Private **********/
319 /**************************************/
321 static int resource_used(void *resource_id)
323 /* We can freely cast as a link_KCCFLN05_t because it has
324 the same prefix as cpu_KCCFLN05_t */
325 if (((cpu_KCCFLN05_t) resource_id)->type ==
326 SURF_WORKSTATION_RESOURCE_CPU)
327 return (lmm_constraint_used
328 (maxmin_system, ((cpu_KCCFLN05_t) resource_id)->constraint)
329 || ((((cpu_KCCFLN05_t) resource_id)->bus) ?
330 lmm_constraint_used(maxmin_system,
331 ((cpu_KCCFLN05_t) resource_id)->
334 return lmm_constraint_used(maxmin_system,
335 ((link_KCCFLN05_t) resource_id)->
340 static double share_resources(double now)
342 s_surf_action_workstation_KCCFLN05_t s_action;
343 surf_action_workstation_KCCFLN05_t action = NULL;
345 xbt_swag_t running_actions =
346 surf_workstation_model->common_public->states.running_action_set;
347 double min = generic_maxmin_share_resources(running_actions,
348 xbt_swag_offset(s_action,
353 xbt_swag_foreach(action, running_actions) {
354 if (action->latency > 0) {
356 min = action->latency;
357 DEBUG3("Updating min (value) with %p (start %f): %f", action,
358 action->generic_action.start, min);
359 } else if (action->latency < min) {
360 min = action->latency;
361 DEBUG3("Updating min (latency) with %p (start %f): %f", action,
362 action->generic_action.start, min);
367 DEBUG1("min value : %f", min);
372 static void update_actions_state(double now, double delta)
375 surf_action_workstation_KCCFLN05_t action = NULL;
376 surf_action_workstation_KCCFLN05_t next_action = NULL;
377 xbt_swag_t running_actions =
378 surf_workstation_model->common_public->states.running_action_set;
380 xbt_swag_foreach_safe(action, next_action, running_actions) {
382 if (action->latency > 0) {
383 if (action->latency > deltap) {
384 double_update(&(action->latency), deltap);
387 double_update(&(deltap), action->latency);
388 action->latency = 0.0;
390 if ((action->latency == 0.0) && (action->suspended == 0)) {
391 if ((action)->lat_current == 0.0)
392 lmm_update_variable_weight(maxmin_system, action->variable, 1.0);
394 lmm_update_variable_weight(maxmin_system, action->variable,
395 action->lat_current);
398 DEBUG3("Action (%p) : remains (%g) updated by %g.",
399 action, action->generic_action.remains,
400 lmm_variable_getvalue(action->variable) * deltap);
401 double_update(&(action->generic_action.remains),
402 lmm_variable_getvalue(action->variable) * deltap);
404 if (action->generic_action.max_duration != NO_MAX_DURATION)
405 double_update(&(action->generic_action.max_duration), delta);
407 if ((action->generic_action.remains <= 0) &&
408 (lmm_get_variable_weight(action->variable) > 0)) {
409 action->generic_action.finish = surf_get_clock();
410 surf_action_change_state((surf_action_t) action, SURF_ACTION_DONE);
411 } else if ((action->generic_action.max_duration != NO_MAX_DURATION) &&
412 (action->generic_action.max_duration <= 0)) {
413 action->generic_action.finish = surf_get_clock();
414 surf_action_change_state((surf_action_t) action, SURF_ACTION_DONE);
416 /* Need to check that none of the resource has failed */
417 lmm_constraint_t cnst = NULL;
419 void *constraint_id = NULL;
422 lmm_get_cnst_from_var(maxmin_system, action->variable,
424 constraint_id = lmm_constraint_id(cnst);
426 /* if(((link_KCCFLN05_t)constraint_id)->type== */
427 /* SURF_WORKSTATION_RESOURCE_LINK) { */
428 /* DEBUG2("Checking for link %s (%p)", */
429 /* ((link_KCCFLN05_t)constraint_id)->name, */
430 /* ((link_KCCFLN05_t)constraint_id)); */
432 /* if(((cpu_KCCFLN05_t)constraint_id)->type== */
433 /* SURF_WORKSTATION_RESOURCE_CPU) { */
434 /* DEBUG3("Checking for cpu %s (%p) : %s", */
435 /* ((cpu_KCCFLN05_t)constraint_id)->name, */
436 /* ((cpu_KCCFLN05_t)constraint_id), */
437 /* ((cpu_KCCFLN05_t)constraint_id)->state_current==SURF_CPU_OFF?"Off":"On"); */
440 if (((((link_KCCFLN05_t) constraint_id)->type ==
441 SURF_WORKSTATION_RESOURCE_LINK) &&
442 (((link_KCCFLN05_t) constraint_id)->state_current ==
444 ((((cpu_KCCFLN05_t) constraint_id)->type ==
445 SURF_WORKSTATION_RESOURCE_CPU) &&
446 (((cpu_KCCFLN05_t) constraint_id)->state_current ==
448 DEBUG1("Action (%p) Failed!!", action);
449 action->generic_action.finish = surf_get_clock();
450 surf_action_change_state((surf_action_t) action,
460 static void update_resource_state(void *id,
461 tmgr_trace_event_t event_type,
464 cpu_KCCFLN05_t cpu = id;
465 link_KCCFLN05_t nw_link = id;
467 if (nw_link->type == SURF_WORKSTATION_RESOURCE_LINK) {
468 DEBUG2("Updating link %s (%p)", nw_link->name, nw_link);
469 if (event_type == nw_link->bw_event) {
470 nw_link->bw_current = value;
471 lmm_update_constraint_bound(maxmin_system, nw_link->constraint,
472 nw_link->bw_current);
473 } else if (event_type == nw_link->lat_event) {
474 double delta = value - nw_link->lat_current;
475 lmm_variable_t var = NULL;
476 surf_action_workstation_KCCFLN05_t action = NULL;
478 nw_link->lat_current = value;
479 while (lmm_get_var_from_cnst
480 (maxmin_system, nw_link->constraint, &var)) {
481 action = lmm_variable_id(var);
482 action->lat_current += delta;
483 if (action->rate < 0)
484 lmm_update_variable_bound(maxmin_system, action->variable,
485 SG_TCP_CTE_GAMMA / (2.0 *
489 lmm_update_variable_bound(maxmin_system, action->variable,
491 SG_TCP_CTE_GAMMA / (2.0 *
494 if (action->suspended == 0)
495 lmm_update_variable_weight(maxmin_system, action->variable,
496 action->lat_current);
497 lmm_update_variable_latency(maxmin_system, action->variable,
502 } else if (event_type == nw_link->state_event) {
504 nw_link->state_current = SURF_LINK_ON;
506 nw_link->state_current = SURF_LINK_OFF;
508 CRITICAL0("Unknown event ! \n");
512 } else if (cpu->type == SURF_WORKSTATION_RESOURCE_CPU) {
513 DEBUG3("Updating cpu %s (%p) with value %g", cpu->name, cpu, value);
514 if (event_type == cpu->power_event) {
515 cpu->power_current = value;
516 __update_cpu_usage(cpu);
517 } else if (event_type == cpu->state_event) {
519 cpu->state_current = SURF_CPU_ON;
521 cpu->state_current = SURF_CPU_OFF;
523 CRITICAL0("Unknown event ! \n");
533 static void finalize(void)
537 xbt_dict_free(&link_set);
538 xbt_dict_free(&workstation_set);
539 xbt_dict_free(&router_set);
540 if (parallel_task_link_set != NULL) {
541 xbt_dict_free(¶llel_task_link_set);
543 xbt_swag_free(surf_workstation_model->common_public->states.
545 xbt_swag_free(surf_workstation_model->common_public->states.
547 xbt_swag_free(surf_workstation_model->common_public->states.
549 xbt_swag_free(surf_workstation_model->common_public->states.
552 free(surf_workstation_model->common_public);
553 free(surf_workstation_model->common_private);
554 free(surf_workstation_model->extension_public);
556 free(surf_workstation_model);
557 surf_workstation_model = NULL;
559 for (i = 0; i < nb_workstation; i++)
560 for (j = 0; j < nb_workstation; j++)
561 free(ROUTE(i, j).links);
563 routing_table = NULL;
567 lmm_system_free(maxmin_system);
568 maxmin_system = NULL;
572 /**************************************/
573 /******* Resource Private **********/
574 /**************************************/
576 static surf_action_t execute(void *cpu, double size)
578 surf_action_workstation_KCCFLN05_t action = NULL;
579 cpu_KCCFLN05_t CPU = cpu;
581 XBT_IN2("(%s,%g)", CPU->name, size);
582 action = xbt_new0(s_surf_action_workstation_KCCFLN05_t, 1);
584 action->generic_action.using = 1;
585 action->generic_action.cost = size;
586 action->generic_action.remains = size;
587 action->generic_action.priority = 1.0;
588 action->generic_action.max_duration = NO_MAX_DURATION;
589 action->generic_action.start = surf_get_clock();
590 action->generic_action.finish = -1.0;
591 action->generic_action.model_type =
592 (surf_model_t) surf_workstation_model;
593 action->suspended = 0;
595 if (CPU->state_current == SURF_CPU_ON)
596 action->generic_action.state_set =
597 surf_workstation_model->common_public->states.
600 action->generic_action.state_set =
601 surf_workstation_model->common_public->states.failed_action_set;
602 xbt_swag_insert(action, action->generic_action.state_set);
604 action->variable = lmm_variable_new(maxmin_system, action,
605 action->generic_action.priority,
607 lmm_expand(maxmin_system, CPU->constraint, action->variable, 1.0);
609 return (surf_action_t) action;
612 static surf_action_t action_sleep(void *cpu, double duration)
614 surf_action_workstation_KCCFLN05_t action = NULL;
616 XBT_IN2("(%s,%g)", ((cpu_KCCFLN05_t) cpu)->name, duration);
618 action = (surf_action_workstation_KCCFLN05_t) execute(cpu, 1.0);
619 action->generic_action.max_duration = duration;
620 action->suspended = 2;
621 lmm_update_variable_weight(maxmin_system, action->variable, 0.0);
624 return (surf_action_t) action;
627 static e_surf_cpu_state_t resource_get_state(void *cpu)
629 return ((cpu_KCCFLN05_t) cpu)->state_current;
632 static double get_speed(void *cpu, double load)
634 return load * (((cpu_KCCFLN05_t) cpu)->power_scale);
637 static double get_available_speed(void *cpu)
639 return ((cpu_KCCFLN05_t) cpu)->power_current;
642 static surf_action_t communicate(void *src, void *dst, double size,
645 surf_action_workstation_KCCFLN05_t action = NULL;
646 cpu_KCCFLN05_t card_src = src;
647 cpu_KCCFLN05_t card_dst = dst;
648 route_KCCFLN05_t route = &(ROUTE(card_src->id, card_dst->id));
649 int route_size = route->size;
652 XBT_IN4("(%s,%s,%g,%g)", card_src->name, card_dst->name, size, rate);
653 xbt_assert2(route_size,
654 "You're trying to send data from %s to %s but there is no connexion between these two cards.",
655 card_src->name, card_dst->name);
657 action = xbt_new0(s_surf_action_workstation_KCCFLN05_t, 1);
659 action->generic_action.using = 1;
660 action->generic_action.cost = size;
661 action->generic_action.remains = size;
662 action->generic_action.max_duration = NO_MAX_DURATION;
663 action->generic_action.start = surf_get_clock();
664 action->generic_action.finish = -1.0;
667 action->generic_action.model_type =
668 (surf_model_t) surf_workstation_model;
669 action->suspended = 0; /* Should be useless because of the
670 calloc but it seems to help valgrind... */
671 action->generic_action.state_set =
672 surf_workstation_model->common_public->states.running_action_set;
674 xbt_dynar_push(card_src->outgoing_communications, &action);
675 xbt_dynar_push(card_dst->incomming_communications, &action);
677 xbt_swag_insert(action, action->generic_action.state_set);
680 action->latency = 0.0;
681 for (i = 0; i < route_size; i++)
682 action->latency += route->links[i]->lat_current;
683 action->lat_current = action->latency;
685 if (action->latency > 0)
686 action->variable = lmm_variable_new(maxmin_system, action, 0.0, -1.0, route_size + 4); /* +1 for the src bus
689 +1 for the dst cpu */
691 action->variable = lmm_variable_new(maxmin_system, action, 1.0, -1.0,
694 if (action->rate < 0) {
695 if (action->lat_current > 0)
696 lmm_update_variable_bound(maxmin_system, action->variable,
697 SG_TCP_CTE_GAMMA / (2.0 *
698 action->lat_current));
700 lmm_update_variable_bound(maxmin_system, action->variable, -1.0);
702 if (action->lat_current > 0)
703 lmm_update_variable_bound(maxmin_system, action->variable,
705 SG_TCP_CTE_GAMMA / (2.0 *
709 lmm_update_variable_bound(maxmin_system, action->variable,
713 lmm_update_variable_latency(maxmin_system, action->variable,
714 action->latency); /* Should be useless */
716 for (i = 0; i < route_size; i++)
717 lmm_expand(maxmin_system, route->links[i]->constraint,
718 action->variable, 1.0);
720 lmm_expand(maxmin_system, card_src->bus, action->variable, 1.0);
722 lmm_expand(maxmin_system, card_dst->bus, action->variable, 1.0);
723 lmm_expand(maxmin_system, card_src->constraint, action->variable, 0.0);
724 lmm_expand(maxmin_system, card_dst->constraint, action->variable, 0.0);
727 return (surf_action_t) action;
730 static surf_action_t execute_parallel_task(int workstation_nb,
731 void **workstation_list,
732 double *computation_amount,
733 double *communication_amount,
734 double amount, double rate)
736 surf_action_workstation_KCCFLN05_t action = NULL;
741 if (parallel_task_link_set == NULL) {
742 parallel_task_link_set =
743 xbt_dict_new_ext(workstation_nb * workstation_nb * 10);
746 /* Compute the number of affected resources... */
747 for (i = 0; i < workstation_nb; i++) {
748 for (j = 0; j < workstation_nb; j++) {
749 cpu_KCCFLN05_t card_src = workstation_list[i];
750 cpu_KCCFLN05_t card_dst = workstation_list[j];
751 int route_size = ROUTE(card_src->id, card_dst->id).size;
752 link_KCCFLN05_t *route =
753 ROUTE(card_src->id, card_dst->id).links;
755 if (communication_amount[i * workstation_nb + j] > 0)
756 for (k = 0; k < route_size; k++) {
757 xbt_dict_set(parallel_task_link_set, route[k]->name,
762 nb_link = xbt_dict_length(parallel_task_link_set);
763 xbt_dict_reset(parallel_task_link_set);
766 for (i = 0; i < workstation_nb; i++)
767 if (computation_amount[i] > 0)
770 action = xbt_new0(s_surf_action_workstation_KCCFLN05_t, 1);
771 DEBUG3("Creating a parallel task (%p) with %d cpus and %d links.",
772 action, nb_host, nb_link);
773 action->generic_action.using = 1;
774 action->generic_action.cost = amount;
775 action->generic_action.remains = amount;
776 action->generic_action.max_duration = NO_MAX_DURATION;
777 action->generic_action.start = surf_get_clock();
778 action->generic_action.finish = -1.0;
779 action->generic_action.model_type =
780 (surf_model_t) surf_workstation_model;
781 action->suspended = 0; /* Should be useless because of the
782 calloc but it seems to help valgrind... */
783 action->generic_action.state_set =
784 surf_workstation_model->common_public->states.running_action_set;
786 xbt_swag_insert(action, action->generic_action.state_set);
789 if (action->rate > 0)
790 action->variable = lmm_variable_new(maxmin_system, action, 1.0, -1.0,
794 lmm_variable_new(maxmin_system, action, 1.0, action->rate,
797 for (i = 0; i < workstation_nb; i++)
798 if (computation_amount[i] > 0)
799 lmm_expand(maxmin_system,
800 ((cpu_KCCFLN05_t) workstation_list[i])->constraint,
801 action->variable, computation_amount[i]);
803 for (i = 0; i < workstation_nb; i++) {
804 for (j = 0; j < workstation_nb; j++) {
805 cpu_KCCFLN05_t card_src = workstation_list[i];
806 cpu_KCCFLN05_t card_dst = workstation_list[j];
807 int route_size = ROUTE(card_src->id, card_dst->id).size;
808 link_KCCFLN05_t *route =
809 ROUTE(card_src->id, card_dst->id).links;
811 for (k = 0; k < route_size; k++) {
812 if (communication_amount[i * workstation_nb + j] > 0) {
813 lmm_expand_add(maxmin_system, route[k]->constraint,
815 communication_amount[i * workstation_nb + j]);
821 if (nb_link + nb_host == 0) {
822 action->generic_action.cost = 1.0;
823 action->generic_action.remains = 0.0;
826 return (surf_action_t) action;
829 /* returns an array of link_KCCFLN05_t */
830 static const void **get_route(void *src, void *dst)
832 cpu_KCCFLN05_t card_src = src;
833 cpu_KCCFLN05_t card_dst = dst;
834 route_KCCFLN05_t route = &(ROUTE(card_src->id, card_dst->id));
836 return (const void **) route->links;
839 static int get_route_size(void *src, void *dst)
841 cpu_KCCFLN05_t card_src = src;
842 cpu_KCCFLN05_t card_dst = dst;
843 route_KCCFLN05_t route = &(ROUTE(card_src->id, card_dst->id));
847 static const char *get_link_name(const void *link)
849 return ((link_KCCFLN05_t) link)->name;
852 static double get_link_bandwidth(const void *link)
854 return ((link_KCCFLN05_t) link)->bw_current;
857 static double get_link_latency(const void *link)
859 return ((link_KCCFLN05_t) link)->lat_current;
862 /**************************************/
863 /*** Resource Creation & Destruction **/
864 /**************************************/
867 static void router_free(void *router)
869 free(((router_KCCFLN05_t) router)->name);
872 static void router_new(const char *name)
874 static unsigned int nb_routers = 0;
875 router_KCCFLN05_t router;
877 INFO1("Creating a router %s", name);
879 router = xbt_new0(s_router_KCCFLN05_t, 1);
881 router->name = xbt_strdup(name);
882 router->id = nb_routers++;
883 xbt_dict_set(router_set, name, router, router_free);
886 static void parse_routers(void)
888 //add a dumb router just to be GTNETS compatible
889 router_new(A_surfxml_router_id);
892 static void cpu_free(void *cpu)
894 free(((cpu_KCCFLN05_t) cpu)->name);
895 xbt_dynar_free(&(((cpu_KCCFLN05_t) cpu)->incomming_communications));
896 xbt_dynar_free(&(((cpu_KCCFLN05_t) cpu)->outgoing_communications));
900 static cpu_KCCFLN05_t cpu_new(const char *name, double power_scale,
901 double power_initial,
902 tmgr_trace_t power_trace,
903 e_surf_cpu_state_t state_initial,
904 tmgr_trace_t state_trace,
905 double interference_send,
906 double interference_recv,
907 double interference_send_recv,
908 double max_outgoing_rate,
909 xbt_dict_t cpu_properties_k)
911 cpu_KCCFLN05_t cpu = xbt_new0(s_cpu_KCCFLN05_t, 1);
913 cpu->model = (surf_model_t) surf_workstation_model;
914 cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
915 cpu->name = xbt_strdup(name);
916 cpu->id = nb_workstation++;
918 cpu->power_scale = power_scale;
919 xbt_assert0(cpu->power_scale > 0, "Power has to be >0");
921 cpu->power_current = power_initial;
924 tmgr_history_add_trace(history, power_trace, 0.0, 0, cpu);
926 cpu->state_current = state_initial;
929 tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
931 cpu->interference_send = interference_send;
932 cpu->interference_recv = interference_recv;
933 cpu->interference_send_recv = interference_send_recv;
936 lmm_constraint_new(maxmin_system, cpu,
937 cpu->power_current * cpu->power_scale);
938 if (max_outgoing_rate > 0)
939 cpu->bus = lmm_constraint_new(maxmin_system, cpu, max_outgoing_rate);
941 cpu->incomming_communications =
942 xbt_dynar_new(sizeof(surf_action_workstation_KCCFLN05_t), NULL);
943 cpu->outgoing_communications =
944 xbt_dynar_new(sizeof(surf_action_workstation_KCCFLN05_t), NULL);
946 /*add the property set*/
947 cpu->properties = current_property_set;
949 xbt_dict_set(workstation_set, name, cpu, cpu_free);
954 static void create_routing_table(void)
956 routing_table = xbt_new0(s_route_KCCFLN05_t, nb_workstation * nb_workstation);
959 static void parse_cpu_init(void)
961 double power_scale = 0.0;
962 double power_initial = 0.0;
963 tmgr_trace_t power_trace = NULL;
964 e_surf_cpu_state_t state_initial = SURF_CPU_OFF;
965 tmgr_trace_t state_trace = NULL;
966 double interference_send = 0.0;
967 double interference_recv = 0.0;
968 double interference_send_recv = 0.0;
969 double max_outgoing_rate = -1.0;
971 surf_parse_get_double(&power_scale, A_surfxml_host_power);
972 surf_parse_get_double(&power_initial, A_surfxml_host_availability);
973 surf_parse_get_trace(&power_trace, A_surfxml_host_availability_file);
975 xbt_assert0((A_surfxml_host_state == A_surfxml_host_state_ON) ||
976 (A_surfxml_host_state == A_surfxml_host_state_OFF),
978 if (A_surfxml_host_state == A_surfxml_host_state_ON)
979 state_initial = SURF_CPU_ON;
980 if (A_surfxml_host_state == A_surfxml_host_state_OFF)
981 state_initial = SURF_CPU_OFF;
982 surf_parse_get_trace(&state_trace, A_surfxml_host_state_file);
984 surf_parse_get_double(&interference_send,
985 A_surfxml_host_interference_send);
986 surf_parse_get_double(&interference_recv,
987 A_surfxml_host_interference_recv);
988 surf_parse_get_double(&interference_send_recv,
989 A_surfxml_host_interference_send_recv);
990 surf_parse_get_double(&max_outgoing_rate,
991 A_surfxml_host_max_outgoing_rate);
992 current_property_set = xbt_dict_new();
993 cpu_new(A_surfxml_host_id, power_scale, power_initial, power_trace,
994 state_initial, state_trace, interference_send, interference_recv,
995 interference_send_recv, max_outgoing_rate,current_property_set);
998 static void link_free(void *nw_link)
1000 free(((link_KCCFLN05_t) nw_link)->name);
1004 static link_KCCFLN05_t link_new(char *name,
1006 tmgr_trace_t bw_trace,
1008 tmgr_trace_t lat_trace,
1011 tmgr_trace_t state_trace,
1012 e_surf_link_sharing_policy_t
1013 policy, xbt_dict_t properties_args)
1015 link_KCCFLN05_t nw_link = xbt_new0(s_link_KCCFLN05_t, 1);
1018 nw_link->model = (surf_model_t) surf_workstation_model;
1019 nw_link->type = SURF_WORKSTATION_RESOURCE_LINK;
1020 nw_link->name = name;
1021 nw_link->bw_current = bw_initial;
1024 tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
1025 nw_link->state_current = state_initial;
1026 nw_link->lat_current = lat_initial;
1028 nw_link->lat_event =
1029 tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
1031 nw_link->state_event =
1032 tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
1034 nw_link->constraint =
1035 lmm_constraint_new(maxmin_system, nw_link, nw_link->bw_current);
1037 if (policy == SURF_LINK_FATPIPE)
1038 lmm_constraint_shared(nw_link->constraint);
1040 /*add the property set*/
1041 nw_link->properties = properties_args;
1043 xbt_dict_set(link_set, name, nw_link, link_free);
1048 static void parse_link_init(void)
1052 tmgr_trace_t bw_trace;
1054 tmgr_trace_t lat_trace;
1055 e_surf_link_state_t state_initial_link = SURF_LINK_ON;
1056 e_surf_link_sharing_policy_t policy_initial_link = SURF_LINK_SHARED;
1057 tmgr_trace_t state_trace;
1059 name_link = xbt_strdup(A_surfxml_link_id);
1060 surf_parse_get_double(&bw_initial, A_surfxml_link_bandwidth);
1061 surf_parse_get_trace(&bw_trace, A_surfxml_link_bandwidth_file);
1062 surf_parse_get_double(&lat_initial, A_surfxml_link_latency);
1063 surf_parse_get_trace(&lat_trace, A_surfxml_link_latency_file);
1065 xbt_assert0((A_surfxml_link_state ==
1066 A_surfxml_link_state_ON)
1067 || (A_surfxml_link_state ==
1068 A_surfxml_link_state_OFF), "Invalid state");
1069 if (A_surfxml_link_state == A_surfxml_link_state_ON)
1070 state_initial_link = SURF_LINK_ON;
1071 else if (A_surfxml_link_state ==
1072 A_surfxml_link_state_OFF)
1073 state_initial_link = SURF_LINK_OFF;
1075 if (A_surfxml_link_sharing_policy ==
1076 A_surfxml_link_sharing_policy_SHARED)
1077 policy_initial_link = SURF_LINK_SHARED;
1078 else if (A_surfxml_link_sharing_policy ==
1079 A_surfxml_link_sharing_policy_FATPIPE)
1080 policy_initial_link = SURF_LINK_FATPIPE;
1082 surf_parse_get_trace(&state_trace, A_surfxml_link_state_file);
1084 current_property_set = xbt_dict_new();
1085 link_new(name_link, bw_initial, bw_trace,
1086 lat_initial, lat_trace, state_initial_link, state_trace,
1087 policy_initial_link,/*add properties*/current_property_set);
1090 static void route_new(int src_id, int dst_id,
1091 link_KCCFLN05_t * link_list, int nb_link,
1092 double impact_on_src, double impact_on_dst,
1093 double impact_on_src_with_other_recv,
1094 double impact_on_dst_with_other_send)
1096 route_KCCFLN05_t route = &(ROUTE(src_id, dst_id));
1098 route->size = nb_link;
1099 route->links = link_list = xbt_realloc(link_list, sizeof(link_KCCFLN05_t) * nb_link);
1100 route->impact_on_src = impact_on_src;
1101 route->impact_on_dst = impact_on_dst;
1102 route->impact_on_src_with_other_recv = impact_on_src_with_other_recv;
1103 route->impact_on_dst_with_other_send = impact_on_dst_with_other_send;
1108 static int link_list_capacity;
1109 static link_KCCFLN05_t *link_list = NULL;
1110 static int src_id = -1;
1111 static int dst_id = -1;
1112 static double impact_on_src;
1113 static double impact_on_dst;
1114 static double impact_on_src_with_other_recv;
1115 static double impact_on_dst_with_other_send;
1116 static int is_first = 1;
1118 static void parse_route_set_endpoints(void)
1120 cpu_KCCFLN05_t cpu_tmp = NULL;
1122 if (is_first) create_routing_table();
1125 cpu_tmp = (cpu_KCCFLN05_t) name_service(A_surfxml_route_src);
1126 if (cpu_tmp != NULL) {
1127 src_id = cpu_tmp->id;
1129 xbt_assert1(xbt_dict_get_or_null(router_set, A_surfxml_route_src),
1130 "Invalid name '%s': neither a cpu nor a router!",
1131 A_surfxml_route_src);
1136 cpu_tmp = (cpu_KCCFLN05_t) name_service(A_surfxml_route_dst);
1137 if (cpu_tmp != NULL) {
1138 dst_id = cpu_tmp->id;
1140 xbt_assert1(xbt_dict_get_or_null(router_set, A_surfxml_route_dst),
1141 "Invalid name '%s': neither a cpu nor a router!",
1142 A_surfxml_route_dst);
1147 surf_parse_get_double(&impact_on_src, A_surfxml_route_impact_on_src);
1148 surf_parse_get_double(&impact_on_dst, A_surfxml_route_impact_on_dst);
1149 surf_parse_get_double(&impact_on_src_with_other_recv,
1150 A_surfxml_route_impact_on_src_with_other_recv);
1151 surf_parse_get_double(&impact_on_dst_with_other_send,
1152 A_surfxml_route_impact_on_dst_with_other_send);
1155 link_list_capacity = 1;
1156 link_list = xbt_new(link_KCCFLN05_t, link_list_capacity);
1160 static void parse_route_elem(void)
1163 if (nb_link == link_list_capacity) {
1164 link_list_capacity *= 2;
1166 xbt_realloc(link_list,
1167 (link_list_capacity) *
1168 sizeof(link_KCCFLN05_t));
1171 link_list[nb_link++] =
1172 xbt_dict_get(link_set, A_surfxml_link_c_ctn_id);
1175 RETHROW1("Link %s not found (dict raised this exception: %s)",
1176 A_surfxml_link_c_ctn_id);
1180 static void parse_route_set_route(void)
1182 if (src_id != -1 && dst_id != -1)
1183 route_new(src_id, dst_id, link_list, nb_link, impact_on_src,
1184 impact_on_dst, impact_on_src_with_other_recv,
1185 impact_on_dst_with_other_send);
1190 static void parse_file(const char *file)
1194 /* Adding callback functions */
1195 surf_parse_reset_parser();
1196 surfxml_add_callback(STag_surfxml_host_cb_list, &parse_cpu_init);
1197 surfxml_add_callback(STag_surfxml_prop_cb_list, &parse_properties);
1198 surfxml_add_callback(STag_surfxml_router_cb_list, &parse_routers);
1199 surfxml_add_callback(STag_surfxml_link_cb_list, &parse_link_init);
1200 surfxml_add_callback(STag_surfxml_route_cb_list, &parse_route_set_endpoints);
1201 surfxml_add_callback(ETag_surfxml_link_c_ctn_cb_list, &parse_route_elem);
1202 surfxml_add_callback(ETag_surfxml_route_cb_list, &parse_route_set_route);
1204 /* Parse the file */
1205 surf_parse_open(file);
1206 xbt_assert1((!surf_parse()), "Parse error in %s", file);
1209 /* Adding loopback if needed */
1210 for (i = 0; i < nb_workstation; i++)
1211 if (!ROUTE(i, i).size) {
1213 loopback = link_new(xbt_strdup("__MSG_loopback__"),
1214 498000000, NULL, 0.000015, NULL,
1216 SURF_LINK_FATPIPE, NULL);
1217 ROUTE(i, i).size = 1;
1218 ROUTE(i, i).links = xbt_new0(link_KCCFLN05_t, 1);
1219 ROUTE(i, i).links[0] = loopback;
1224 /**************************************/
1225 /********* Module creation ***********/
1226 /**************************************/
1228 static void model_init_internal(void)
1230 s_surf_action_t action;
1232 surf_workstation_model = xbt_new0(s_surf_workstation_model_t, 1);
1234 surf_workstation_model->common_private =
1235 xbt_new0(s_surf_model_private_t, 1);
1236 surf_workstation_model->common_public =
1237 xbt_new0(s_surf_model_public_t, 1);
1238 surf_workstation_model->extension_public =
1239 xbt_new0(s_surf_workstation_model_extension_public_t, 1);
1241 surf_workstation_model->common_public->states.ready_action_set =
1242 xbt_swag_new(xbt_swag_offset(action, state_hookup));
1243 surf_workstation_model->common_public->states.running_action_set =
1244 xbt_swag_new(xbt_swag_offset(action, state_hookup));
1245 surf_workstation_model->common_public->states.failed_action_set =
1246 xbt_swag_new(xbt_swag_offset(action, state_hookup));
1247 surf_workstation_model->common_public->states.done_action_set =
1248 xbt_swag_new(xbt_swag_offset(action, state_hookup));
1250 surf_workstation_model->common_public->name_service = name_service;
1251 surf_workstation_model->common_public->get_resource_name =
1253 surf_workstation_model->common_public->action_get_state =
1254 surf_action_get_state;
1255 surf_workstation_model->common_public->action_get_start_time =
1256 surf_action_get_start_time;
1257 surf_workstation_model->common_public->action_get_finish_time =
1258 surf_action_get_finish_time;
1259 surf_workstation_model->common_public->action_use = action_use;
1260 surf_workstation_model->common_public->action_free = action_free;
1261 surf_workstation_model->common_public->action_cancel = action_cancel;
1262 surf_workstation_model->common_public->action_recycle =
1264 surf_workstation_model->common_public->action_change_state =
1265 surf_action_change_state;
1266 surf_workstation_model->common_public->action_set_data =
1267 surf_action_set_data;
1268 surf_workstation_model->common_public->suspend = action_suspend;
1269 surf_workstation_model->common_public->resume = action_resume;
1270 surf_workstation_model->common_public->is_suspended =
1271 action_is_suspended;
1272 surf_workstation_model->common_public->set_max_duration =
1273 action_set_max_duration;
1274 surf_workstation_model->common_public->set_priority =
1275 action_set_priority;
1276 surf_workstation_model->common_public->name = "Workstation KCCFLN05";
1278 surf_workstation_model->common_private->resource_used = resource_used;
1279 surf_workstation_model->common_private->share_resources =
1281 surf_workstation_model->common_private->update_actions_state =
1282 update_actions_state;
1283 surf_workstation_model->common_private->update_resource_state =
1284 update_resource_state;
1285 surf_workstation_model->common_private->finalize = finalize;
1287 surf_workstation_model->extension_public->execute = execute;
1288 surf_workstation_model->extension_public->sleep = action_sleep;
1289 surf_workstation_model->extension_public->get_state =
1291 surf_workstation_model->extension_public->get_speed = get_speed;
1292 surf_workstation_model->extension_public->get_available_speed =
1293 get_available_speed;
1295 surf_workstation_model->common_public->get_properties = get_properties;
1297 surf_workstation_model->extension_public->communicate = communicate;
1298 surf_workstation_model->extension_public->execute_parallel_task =
1299 execute_parallel_task;
1300 surf_workstation_model->extension_public->get_route = get_route;
1301 surf_workstation_model->extension_public->get_route_size =
1303 surf_workstation_model->extension_public->get_link_name =
1305 surf_workstation_model->extension_public->get_link_bandwidth =
1307 surf_workstation_model->extension_public->get_link_latency =
1310 workstation_set = xbt_dict_new();
1311 router_set = xbt_dict_new();
1312 link_set = xbt_dict_new();
1314 maxmin_system = lmm_system_new();
1317 /**************************************/
1318 /*************** Generic **************/
1319 /**************************************/
1320 void surf_workstation_model_init_KCCFLN05(const char *filename)
1322 xbt_assert0(!surf_cpu_model, "CPU model type already defined");
1323 xbt_assert0(!surf_network_model,
1324 "network model type already defined");
1325 model_init_internal();
1326 parse_file(filename);
1328 xbt_dynar_push(model_list, &surf_workstation_model);