1 /* Copyright (c) 2004-2014. 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. */
7 #include "surf_private.h"
8 #include "surf_interface.hpp"
9 #include "network_interface.hpp"
10 #include "cpu_interface.hpp"
11 #include "workstation_interface.hpp"
12 #include "vm_workstation_interface.hpp"
13 #include "simix/smx_host_private.h"
14 #include "surf_routing.hpp"
15 #include "simgrid/sg_config.h"
18 XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
19 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
20 "Logging specific to SURF (kernel)");
26 /* This function is a pimple that we ought to fix. But it won't be easy.
28 * The surf_solve() function does properly return the set of actions that changed.
29 * Instead, each model change a global data, and then the caller of surf_solve must
30 * pick into these sets of action_failed and action_done.
32 * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
33 * We worked by putting sentinel actions on every resources we are interested in,
34 * so that surf informs us if/when the corresponding resource fails.
36 * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
37 * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
38 * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
39 * that was turned back up in the meanwhile. This is UGLY and slow.
41 * The proper solution would be to not rely on globals for the action_failed and action_done swags.
42 * They must be passed as parameter by the caller (the handling of these actions in simix may let you
43 * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
44 * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
47 * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
48 * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
49 * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
50 * sees it and react accordingly. This would kill that need for surf to call simix.
54 /*static void remove_watched_host(void *key)
56 xbt_dict_remove(watched_hosts_lib, *(char**)key);
59 /*void surf_watched_hosts(void)
63 xbt_dict_cursor_t cursor;
64 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
66 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
67 xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
69 if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
70 XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
71 SIMIX_host_autorestart((smx_host_t)host);
72 xbt_dynar_push_as(hosts, char*, key);
75 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
77 xbt_dynar_map(hosts, remove_watched_host);
78 xbt_dynar_free(&hosts);
81 /* model_list_invoke contains only surf_workstation and surf_vm_workstation.
82 * The callback functions of cpu_model and network_model will be called from
83 * those of these workstation models. */
84 xbt_dynar_t model_list = NULL; /* for destroying all models correctly */
85 xbt_dynar_t model_list_invoke = NULL; /* for invoking callbacks */
87 tmgr_history_t history = NULL;
88 lmm_system_t maxmin_system = NULL;
89 xbt_dynar_t surf_path = NULL;
90 xbt_dynar_t host_that_restart = NULL;
91 xbt_dict_t watched_hosts_lib;
93 s_surf_model_description_t surf_plugin_description[] = {
95 "Cpu energy consumption.",
96 sg_energy_plugin_init},
97 {NULL, NULL, NULL} /* this array must be NULL terminated */
100 /* Don't forget to update the option description in smx_config when you change this */
101 s_surf_model_description_t surf_network_model_description[] = {
103 "Realistic network analytic model (slow-start modeled by multiplying latency by 10.4, bandwidth by .92; bottleneck sharing uses a payload of S=8775 for evaluating RTT). ",
104 surf_network_model_init_LegrandVelho},
106 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
107 surf_network_model_init_Constant},
109 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
110 surf_network_model_init_SMPI},
112 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
113 surf_network_model_init_CM02},
116 "Network pseudo-model using the GTNets simulator instead of an analytic model",
117 surf_network_model_init_GTNETS},
121 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
122 surf_network_model_init_NS3},
125 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
126 surf_network_model_init_Reno},
128 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
129 surf_network_model_init_Reno2},
131 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
132 surf_network_model_init_Vegas},
133 {NULL, NULL, NULL} /* this array must be NULL terminated */
136 s_surf_model_description_t surf_cpu_model_description[] = {
138 "Simplistic CPU model (time=size/power).",
139 surf_cpu_model_init_Cas01},
140 {NULL, NULL, NULL} /* this array must be NULL terminated */
143 s_surf_model_description_t surf_workstation_model_description[] = {
145 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
146 surf_workstation_model_init_current_default},
148 "Workstation model that is automatically chosen if you change the network and CPU models",
149 surf_workstation_model_init_compound},
150 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
151 surf_workstation_model_init_ptask_L07},
152 {NULL, NULL, NULL} /* this array must be NULL terminated */
155 s_surf_model_description_t surf_vm_workstation_model_description[] = {
157 "Default vm workstation model.)",
158 surf_vm_workstation_model_init_current_default},
159 {NULL, NULL, NULL} /* this array must be NULL terminated */
162 s_surf_model_description_t surf_optimization_mode_description[] = {
164 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
167 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
170 "Full update of remaining and variables. Slow but may be useful when debugging.",
172 {NULL, NULL, NULL} /* this array must be NULL terminated */
175 s_surf_model_description_t surf_storage_model_description[] = {
177 "Simplistic storage model.",
178 surf_storage_model_init_default},
179 {NULL, NULL, NULL} /* this array must be NULL terminated */
182 #ifdef CONTEXT_THREADS
183 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
187 double *surf_mins = NULL; /* return value of share_resources for each model */
188 int surf_min_index; /* current index in surf_mins */
189 double surf_min; /* duration determined by surf_solve */
191 double surf_get_clock(void)
197 # define FILE_DELIM "\\"
199 # define FILE_DELIM "/" /* FIXME: move to better location */
202 FILE *surf_fopen(const char *name, const char *mode)
205 char *path_elm = NULL;
211 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
212 return fopen(name, mode);
214 /* search relative files in the path */
215 xbt_dynar_foreach(surf_path, cpt, path_elm) {
216 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
217 file = fopen(buff, mode);
233 static const char *disk_drives_letter_table[MAX_DRIVE] = {
264 * Returns the initial path. On Windows the initial path is
265 * the current directory for the current process in the other
266 * case the function returns "./" that represents the current
267 * directory on Unix/Linux platforms.
270 const char *__surf_get_initial_path(void)
275 char current_directory[MAX_PATH + 1] = { 0 };
276 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
277 char root[4] = { 0 };
282 strncpy(root, current_directory, 3);
284 for (i = 0; i < MAX_DRIVE; i++) {
285 if (toupper(root[0]) == disk_drives_letter_table[i][0])
286 return disk_drives_letter_table[i];
295 /* The __surf_is_absolute_file_path() returns 1 if
296 * file_path is a absolute file path, in the other
297 * case the function returns 0.
299 int __surf_is_absolute_file_path(const char *file_path)
302 WIN32_FIND_DATA wfd = { 0 };
303 HANDLE hFile = FindFirstFile(file_path, &wfd);
305 if (INVALID_HANDLE_VALUE == hFile)
311 return (file_path[0] == '/');
315 /** Displays the long description of all registered models, and quit */
316 void model_help(const char *category, s_surf_model_description_t * table)
319 printf("Long description of the %s models accepted by this simulator:\n",
321 for (i = 0; table[i].name; i++)
322 printf(" %s: %s\n", table[i].name, table[i].description);
325 int find_model_description(s_surf_model_description_t * table,
329 char *name_list = NULL;
331 for (i = 0; table[i].name; i++)
332 if (!strcmp(name, table[i].name)) {
335 name_list = strdup(table[0].name);
336 for (i = 1; table[i].name; i++) {
337 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
338 strcat(name_list, ", ");
339 strcat(name_list, table[i].name);
341 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
345 static XBT_INLINE void routing_asr_host_free(void *p)
347 delete ((RoutingEdgePtr) p);
350 static XBT_INLINE void routing_asr_prop_free(void *p)
352 xbt_dict_t elm = (xbt_dict_t) p;
356 static XBT_INLINE void surf_cpu_free(void *r)
358 delete static_cast<CpuPtr>(r);
361 static XBT_INLINE void surf_link_free(void *r)
363 delete static_cast<NetworkLinkPtr>(r);
366 static XBT_INLINE void surf_workstation_free(void *r)
368 delete static_cast<WorkstationPtr>(r);
372 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
373 *ver_major = SIMGRID_VERSION_MAJOR;
374 *ver_minor = SIMGRID_VERSION_MINOR;
375 *ver_patch = SIMGRID_VERSION_PATCH;
378 void surf_init(int *argc, char **argv)
380 XBT_DEBUG("Create all Libs");
381 host_lib = xbt_lib_new();
382 link_lib = xbt_lib_new();
383 as_router_lib = xbt_lib_new();
384 storage_lib = xbt_lib_new();
385 storage_type_lib = xbt_lib_new();
386 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
388 XBT_DEBUG("Add routing levels");
389 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
390 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
391 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
393 XBT_DEBUG("Add SURF levels");
394 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
395 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
396 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
398 xbt_init(argc, argv);
400 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
401 if (!model_list_invoke)
402 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
404 history = tmgr_history_new();
407 TRACE_add_start_function(TRACE_surf_alloc);
408 TRACE_add_end_function(TRACE_surf_release);
411 sg_config_init(argc, argv);
420 ModelPtr model = NULL;
423 TRACE_end(); /* Just in case it was not called by the upper
424 * layer (or there is no upper layer) */
427 sg_config_finalize();
429 xbt_dynar_foreach(model_list, iter, model)
431 xbt_dynar_free(&model_list);
432 xbt_dynar_free(&model_list_invoke);
436 lmm_system_free(maxmin_system);
437 maxmin_system = NULL;
440 tmgr_history_free(history);
444 #ifdef CONTEXT_THREADS
445 xbt_parmap_destroy(surf_parmap);
451 xbt_dynar_free(&host_that_restart);
452 xbt_dynar_free(&surf_path);
454 xbt_lib_free(&host_lib);
455 xbt_lib_free(&link_lib);
456 xbt_lib_free(&as_router_lib);
457 xbt_lib_free(&storage_lib);
458 xbt_lib_free(&storage_type_lib);
460 xbt_dict_free(&watched_hosts_lib);
463 surf_parse_lex_destroy();
464 surf_parse_free_callbacks();
466 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
473 Model::Model(const char *name)
474 : p_maxminSystem(NULL)
477 p_readyActionSet = new ActionList();
478 p_runningActionSet = new ActionList();
479 p_failedActionSet = new ActionList();
480 p_doneActionSet = new ActionList();
482 p_modifiedSet = NULL;
484 p_updateMechanism = UM_UNDEFINED;
485 m_selectiveUpdate = 0;
489 delete p_readyActionSet;
490 delete p_runningActionSet;
491 delete p_failedActionSet;
492 delete p_doneActionSet;
495 double Model::shareResources(double now)
497 //FIXME: set the good function once and for all
498 if (p_updateMechanism == UM_LAZY)
499 return shareResourcesLazy(now);
500 else if (p_updateMechanism == UM_FULL)
501 return shareResourcesFull(now);
503 xbt_die("Invalid cpu update mechanism!");
506 double Model::shareResourcesLazy(double now)
508 ActionPtr action = NULL;
513 ("Before share resources, the size of modified actions set is %zd",
514 p_modifiedSet->size());
516 lmm_solve(p_maxminSystem);
519 ("After share resources, The size of modified actions set is %zd",
520 p_modifiedSet->size());
522 while(!p_modifiedSet->empty()) {
523 action = &(p_modifiedSet->front());
524 p_modifiedSet->pop_front();
525 int max_dur_flag = 0;
527 if (action->getStateSet() != p_runningActionSet)
530 /* bogus priority, skip it */
531 if (action->getPriority() <= 0)
534 action->updateRemainingLazy(now);
537 value = lmm_variable_getvalue(action->getVariable());
539 if (action->getRemains() > 0) {
540 value = action->getRemains() / value;
548 if ((action->getMaxDuration() != NO_MAX_DURATION)
550 || action->getStartTime() +
551 action->getMaxDuration() < min)) {
552 min = action->getStartTime() +
553 action->getMaxDuration();
557 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
558 action->getStartTime(), now + value,
559 action->getMaxDuration());
562 action->heapRemove(p_actionHeap);
563 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
564 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
566 } else DIE_IMPOSSIBLE;
569 //hereafter must have already the min value for this resource model
570 if (xbt_heap_size(p_actionHeap) > 0)
571 min = xbt_heap_maxkey(p_actionHeap) - now;
575 XBT_DEBUG("The minimum with the HEAP %lf", min);
580 double Model::shareResourcesFull(double /*now*/) {
584 double Model::shareResourcesMaxMin(ActionListPtr running_actions,
586 void (*solve) (lmm_system_t))
588 ActionPtr action = NULL;
594 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
595 for(; it != itend ; ++it) {
597 value = lmm_variable_getvalue(action->getVariable());
598 if ((value > 0) || (action->getMaxDuration() >= 0))
606 if (action->getRemains() > 0)
607 min = action->getRemains() / value;
610 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
611 min = action->getMaxDuration();
613 min = action->getMaxDuration();
616 for (++it; it != itend; ++it) {
618 value = lmm_variable_getvalue(action->getVariable());
620 if (action->getRemains() > 0)
621 value = action->getRemains() / value;
626 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
629 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
630 min = action->getMaxDuration();
631 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
634 XBT_DEBUG("min value : %f", min);
639 void Model::updateActionsState(double now, double delta)
641 if (p_updateMechanism == UM_FULL)
642 updateActionsStateFull(now, delta);
643 else if (p_updateMechanism == UM_LAZY)
644 updateActionsStateLazy(now, delta);
646 xbt_die("Invalid cpu update mechanism!");
649 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
653 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
662 : p_name(NULL), p_properties(NULL), p_model(NULL)
665 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
666 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
667 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
670 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
671 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
672 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON), p_constraint(constraint)
675 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
676 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
677 , m_running(true), m_stateCurrent(stateInit)
680 Resource::~Resource() {
681 xbt_free((void*)p_name);
682 xbt_dict_free(&p_properties);
685 e_surf_resource_state_t Resource::getState()
687 return m_stateCurrent;
690 void Resource::setState(e_surf_resource_state_t state)
692 m_stateCurrent = state;
695 bool Resource::isOn()
700 void Resource::turnOn()
707 void Resource::turnOff()
714 ModelPtr Resource::getModel() {
718 const char *Resource::getName() {
722 xbt_dict_t Resource::getProperties() {
726 lmm_constraint_t Resource::getConstraint() {
734 const char *surf_action_state_names[6] = {
736 "SURF_ACTION_RUNNING",
737 "SURF_ACTION_FAILED",
739 "SURF_ACTION_TO_FREE",
740 "SURF_ACTION_NOT_IN_THE_SYSTEM"
747 Action::Action(ModelPtr model, double cost, bool failed)
751 , m_maxDuration(NO_MAX_DURATION)
754 , m_start(surf_get_clock())
766 p_stateHookup.prev = 0;
767 p_stateHookup.next = 0;
769 p_stateSet = getModel()->getFailedActionSet();
771 p_stateSet = getModel()->getRunningActionSet();
773 p_stateSet->push_back(*this);
776 Action::Action(ModelPtr model, double cost, bool failed, lmm_variable_t var)
780 , m_maxDuration(NO_MAX_DURATION)
783 , m_start(surf_get_clock())
795 p_stateHookup.prev = 0;
796 p_stateHookup.next = 0;
798 p_stateSet = getModel()->getFailedActionSet();
800 p_stateSet = getModel()->getRunningActionSet();
802 p_stateSet->push_back(*this);
807 xbt_free(p_category);
811 void Action::finish() {
812 m_finish = surf_get_clock();
815 e_surf_action_state_t Action::getState()
817 if (p_stateSet == getModel()->getReadyActionSet())
818 return SURF_ACTION_READY;
819 if (p_stateSet == getModel()->getRunningActionSet())
820 return SURF_ACTION_RUNNING;
821 if (p_stateSet == getModel()->getFailedActionSet())
822 return SURF_ACTION_FAILED;
823 if (p_stateSet == getModel()->getDoneActionSet())
824 return SURF_ACTION_DONE;
825 return SURF_ACTION_NOT_IN_THE_SYSTEM;
828 void Action::setState(e_surf_action_state_t state)
830 //surf_action_state_t action_state = &(action->model_type->states);
831 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
832 p_stateSet->erase(p_stateSet->iterator_to(*this));
833 if (state == SURF_ACTION_READY)
834 p_stateSet = getModel()->getReadyActionSet();
835 else if (state == SURF_ACTION_RUNNING)
836 p_stateSet = getModel()->getRunningActionSet();
837 else if (state == SURF_ACTION_FAILED)
838 p_stateSet = getModel()->getFailedActionSet();
839 else if (state == SURF_ACTION_DONE)
840 p_stateSet = getModel()->getDoneActionSet();
845 p_stateSet->push_back(*this);
849 double Action::getStartTime()
854 double Action::getFinishTime()
856 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
857 return m_remains == 0 ? m_finish : -1;
860 void Action::setData(void* data)
866 void Action::setCategory(const char *category)
868 XBT_IN("(%p,%s)", this, category);
869 p_category = xbt_strdup(category);
878 void Action::setMaxDuration(double duration)
880 XBT_IN("(%p,%g)", this, duration);
881 m_maxDuration = duration;
882 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
883 heapRemove(getModel()->getActionHeap());
887 void Action::gapRemove() {}
889 void Action::setPriority(double priority)
891 XBT_IN("(%p,%g)", this, priority);
892 m_priority = priority;
893 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
895 if (getModel()->getUpdateMechanism() == UM_LAZY)
896 heapRemove(getModel()->getActionHeap());
900 void Action::cancel(){
901 setState(SURF_ACTION_FAILED);
902 if (getModel()->getUpdateMechanism() == UM_LAZY) {
903 if (actionLmmHook::is_linked())
904 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
905 heapRemove(getModel()->getActionHeap());
912 if (actionHook::is_linked())
913 p_stateSet->erase(p_stateSet->iterator_to(*this));
915 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
916 if (getModel()->getUpdateMechanism() == UM_LAZY) {
917 /* remove from heap */
918 heapRemove(getModel()->getActionHeap());
919 if (actionLmmHook::is_linked())
920 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
928 void Action::suspend()
930 XBT_IN("(%p)", this);
931 if (m_suspended != 2) {
932 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
934 if (getModel()->getUpdateMechanism() == UM_LAZY)
935 heapRemove(getModel()->getActionHeap());
940 void Action::resume()
942 XBT_IN("(%p)", this);
943 if (m_suspended != 2) {
944 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
946 if (getModel()->getUpdateMechanism() == UM_LAZY)
947 heapRemove(getModel()->getActionHeap());
952 bool Action::isSuspended()
954 return m_suspended == 1;
956 /* insert action on heap using a given key and a hat (heap_action_type)
957 * a hat can be of three types for communications:
959 * NORMAL = this is a normal heap entry stating the date to finish transmitting
960 * LATENCY = this is a heap entry to warn us when the latency is payed
961 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
963 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
966 xbt_heap_push(heap, this, key);
969 void Action::heapRemove(xbt_heap_t heap)
972 if (m_indexHeap >= 0) {
973 xbt_heap_remove(heap, m_indexHeap);
977 /* added to manage the communication action's heap */
978 void surf_action_lmm_update_index_heap(void *action, int i) {
979 ((ActionPtr)action)->updateIndexHeap(i);
982 void Action::updateIndexHeap(int i) {
986 double Action::getRemains()
988 XBT_IN("(%p)", this);
989 /* update remains before return it */
990 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
991 updateRemainingLazy(surf_get_clock());
996 double Action::getRemainsNoUpdate()
1001 //FIXME split code in the right places
1002 void Action::updateRemainingLazy(double now)
1006 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1008 if (m_suspended != 0)
1013 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
1014 "You're updating an action that is not running.");
1016 /* bogus priority, skip it */
1017 xbt_assert(m_priority > 0,
1018 "You're updating an action that seems suspended.");
1021 delta = now - m_lastUpdate;
1023 if (m_remains > 0) {
1024 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1025 double_update(&m_remains, m_lastValue * delta);
1028 if (getModel() == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
1029 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
1030 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1033 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1036 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1038 if (m_maxDuration != NO_MAX_DURATION)
1039 double_update(&m_maxDuration, delta);
1041 //FIXME: duplicated code
1042 if ((m_remains <= 0) &&
1043 (lmm_get_variable_weight(getVariable()) > 0)) {
1045 setState(SURF_ACTION_DONE);
1046 heapRemove(getModel()->getActionHeap());
1047 } else if (((m_maxDuration != NO_MAX_DURATION)
1048 && (m_maxDuration <= 0))) {
1050 setState(SURF_ACTION_DONE);
1051 heapRemove(getModel()->getActionHeap());
1056 m_lastValue = lmm_variable_getvalue(getVariable());