1 /* Copyright (c) 2004-2015. 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 "host_interface.hpp"
12 #include "src/simix/smx_host_private.h"
13 #include "surf_routing.hpp"
14 #include "simgrid/sg_config.h"
16 #include "virtual_machine.hpp"
17 #include "src/instr/instr_private.h" // TRACE_is_enabled(). FIXME: remove by subscribing tracing to the surf signals
20 XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
21 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
22 "Logging specific to SURF (kernel)");
28 /* model_list_invoke contains only surf_host and surf_vm.
29 * The callback functions of cpu_model and network_model will be called from
30 * those of these host models. */
31 xbt_dynar_t all_existing_models = NULL; /* to destroy models correctly */
32 xbt_dynar_t model_list_invoke = NULL; /* to invoke callbacks */
34 simgrid::trace_mgr::future_evt_set *future_evt_set = nullptr;
35 xbt_dynar_t surf_path = NULL;
36 xbt_dynar_t host_that_restart = xbt_dynar_new(sizeof(char*), NULL);
37 xbt_dict_t watched_hosts_lib;
42 simgrid::xbt::signal<void(void)> surfExitCallbacks;
47 #include <simgrid/plugins/energy.h> // FIXME: this plugin should not be linked to the core
49 s_surf_model_description_t surf_plugin_description[] = {
50 {"Energy", "Cpu energy consumption.", sg_energy_plugin_init},
51 {NULL, NULL, NULL} /* this array must be NULL terminated */
54 /* Don't forget to update the option description in smx_config when you change
56 s_surf_model_description_t surf_network_model_description[] = {
58 "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). ",
59 surf_network_model_init_LegrandVelho},
61 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
62 surf_network_model_init_Constant},
64 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
65 surf_network_model_init_SMPI},
67 "Realistic network model specifically tailored for HPC settings, with Infiniband contention model",
68 surf_network_model_init_IB},
70 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
71 surf_network_model_init_CM02},
74 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
75 surf_network_model_init_NS3},
78 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
79 surf_network_model_init_Reno},
81 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
82 surf_network_model_init_Reno2},
84 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
85 surf_network_model_init_Vegas},
86 {NULL, NULL, NULL} /* this array must be NULL terminated */
89 s_surf_model_description_t surf_cpu_model_description[] = {
91 "Simplistic CPU model (time=size/power).",
92 surf_cpu_model_init_Cas01},
93 {NULL, NULL, NULL} /* this array must be NULL terminated */
96 s_surf_model_description_t surf_host_model_description[] = {
98 "Default host model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
99 surf_host_model_init_current_default},
101 "Host model that is automatically chosen if you change the network and CPU models",
102 surf_host_model_init_compound},
103 {"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks",
104 surf_host_model_init_ptask_L07},
105 {NULL, NULL, NULL} /* this array must be NULL terminated */
108 s_surf_model_description_t surf_vm_model_description[] = {
111 surf_vm_model_init_HL13},
112 {NULL, NULL, NULL} /* this array must be NULL terminated */
115 s_surf_model_description_t surf_optimization_mode_description[] = {
117 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
120 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
123 "Full update of remaining and variables. Slow but may be useful when debugging.",
125 {NULL, NULL, NULL} /* this array must be NULL terminated */
128 s_surf_model_description_t surf_storage_model_description[] = {
130 "Simplistic storage model.",
131 surf_storage_model_init_default},
132 {NULL, NULL, NULL} /* this array must be NULL terminated */
135 #ifdef HAVE_THREAD_CONTEXTS
136 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
141 double surf_get_clock(void)
147 # define FILE_DELIM "\\"
149 # define FILE_DELIM "/" /* FIXME: move to better location */
152 FILE *surf_fopen(const char *name, const char *mode)
155 char *path_elm = NULL;
161 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
162 return fopen(name, mode);
164 /* search relative files in the path */
165 xbt_dynar_foreach(surf_path, cpt, path_elm) {
166 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
167 file = fopen(buff, mode);
179 static const char *disk_drives_letter_table[MAX_DRIVE] = {
180 "A:\\","B:\\","C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\",
181 "N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"
186 * Returns the initial path. On Windows the initial path is
187 * the current directory for the current process in the other
188 * case the function returns "./" that represents the current
189 * directory on Unix/Linux platforms.
192 const char *__surf_get_initial_path(void)
197 char current_directory[MAX_PATH + 1] = { 0 };
198 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
199 char root[4] = { 0 };
204 strncpy(root, current_directory, 3);
206 for (i = 0; i < MAX_DRIVE; i++) {
207 if (toupper(root[0]) == disk_drives_letter_table[i][0])
208 return disk_drives_letter_table[i];
217 /* The __surf_is_absolute_file_path() returns 1 if
218 * file_path is a absolute file path, in the other
219 * case the function returns 0.
221 int __surf_is_absolute_file_path(const char *file_path)
224 WIN32_FIND_DATA wfd = { 0 };
225 HANDLE hFile = FindFirstFile(file_path, &wfd);
227 if (INVALID_HANDLE_VALUE == hFile)
233 return (file_path[0] == '/');
237 /** Displays the long description of all registered models, and quit */
238 void model_help(const char *category, s_surf_model_description_t * table)
241 printf("Long description of the %s models accepted by this simulator:\n",
243 for (i = 0; table[i].name; i++)
244 printf(" %s: %s\n", table[i].name, table[i].description);
247 int find_model_description(s_surf_model_description_t * table,
251 char *name_list = NULL;
253 for (i = 0; table[i].name; i++)
254 if (!strcmp(name, table[i].name)) {
258 xbt_die("No model is valid! This is a bug.");
259 name_list = xbt_strdup(table[0].name);
260 for (i = 1; table[i].name; i++) {
261 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
262 strcat(name_list, ", ");
263 strcat(name_list, table[i].name);
265 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
269 static XBT_INLINE void routing_asr_prop_free(void *p)
271 //xbt_dict_t elm = (xbt_dict_t) p;
272 //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster
275 static XBT_INLINE void surf_storage_free(void *r)
277 delete static_cast<simgrid::surf::Storage*>(r);
280 void sg_version_check(int lib_version_major,int lib_version_minor,int lib_version_patch) {
281 if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) {
283 "FATAL ERROR: Your program was compiled with SimGrid version %d.%d.%d, "
284 "and then linked against SimGrid %d.%d.%d. Please fix this.\n",
285 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
286 lib_version_major,lib_version_minor,lib_version_patch);
289 if (lib_version_patch != SIMGRID_VERSION_PATCH) {
291 "Warning: Your program was compiled with SimGrid version %d.%d.%d, "
292 "and then linked against SimGrid %d.%d.%d. Proceeding anyway.\n",
293 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
294 lib_version_major,lib_version_minor,lib_version_patch);
298 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
299 *ver_major = SIMGRID_VERSION_MAJOR;
300 *ver_minor = SIMGRID_VERSION_MINOR;
301 *ver_patch = SIMGRID_VERSION_PATCH;
304 void surf_init(int *argc, char **argv)
306 XBT_DEBUG("Create all Libs");
307 host_list = xbt_dict_new_homogeneous([](void*p) {
308 simgrid::s4u::Host* host = static_cast<simgrid::s4u::Host*>(p);
309 simgrid::s4u::Host::onDestruction(*host);
312 as_router_lib = xbt_lib_new();
313 storage_lib = xbt_lib_new();
314 storage_type_lib = xbt_lib_new();
315 file_lib = xbt_lib_new();
316 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
320 XBT_DEBUG("Add routing levels");
321 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
323 XBT_DEBUG("Add SURF levels");
324 simgrid::surf::Host::classInit();
325 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
327 xbt_init(argc, argv);
328 if (!all_existing_models)
329 all_existing_models = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
330 if (!model_list_invoke)
331 model_list_invoke = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
333 future_evt_set = new simgrid::trace_mgr::future_evt_set();
335 TRACE_add_start_function(TRACE_surf_alloc);
336 TRACE_add_end_function(TRACE_surf_release);
338 sg_config_init(argc, argv);
347 simgrid::surf::Model *model = NULL;
349 TRACE_end(); /* Just in case it was not called by the upper
350 * layer (or there is no upper layer) */
352 sg_config_finalize();
354 xbt_dynar_free(&host_that_restart);
355 xbt_dynar_free(&surf_path);
357 xbt_dict_free(&host_list);
358 xbt_lib_free(&as_router_lib);
359 xbt_lib_free(&storage_lib);
361 xbt_lib_free(&storage_type_lib);
362 xbt_lib_free(&file_lib);
363 xbt_dict_free(&watched_hosts_lib);
365 xbt_dynar_foreach(all_existing_models, iter, model)
367 xbt_dynar_free(&all_existing_models);
368 xbt_dynar_free(&model_list_invoke);
371 simgrid::surf::surfExitCallbacks();
373 if (future_evt_set) {
374 delete future_evt_set;
375 future_evt_set = nullptr;
378 #ifdef HAVE_THREAD_CONTEXTS
379 xbt_parmap_destroy(surf_parmap);
385 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
396 : p_maxminSystem(NULL)
398 p_readyActionSet = new ActionList();
399 p_runningActionSet = new ActionList();
400 p_failedActionSet = new ActionList();
401 p_doneActionSet = new ActionList();
403 p_modifiedSet = NULL;
405 p_updateMechanism = UM_UNDEFINED;
406 m_selectiveUpdate = 0;
410 delete p_readyActionSet;
411 delete p_runningActionSet;
412 delete p_failedActionSet;
413 delete p_doneActionSet;
416 double Model::next_occuring_event(double now)
418 //FIXME: set the good function once and for all
419 if (p_updateMechanism == UM_LAZY)
420 return next_occuring_event_lazy(now);
421 else if (p_updateMechanism == UM_FULL)
422 return next_occuring_event_full(now);
424 xbt_die("Invalid cpu update mechanism!");
427 double Model::next_occuring_event_lazy(double now)
429 Action *action = NULL;
434 ("Before share resources, the size of modified actions set is %zd",
435 p_modifiedSet->size());
437 lmm_solve(p_maxminSystem);
440 ("After share resources, The size of modified actions set is %zd",
441 p_modifiedSet->size());
443 while(!p_modifiedSet->empty()) {
444 action = &(p_modifiedSet->front());
445 p_modifiedSet->pop_front();
446 int max_dur_flag = 0;
448 if (action->getStateSet() != p_runningActionSet)
451 /* bogus priority, skip it */
452 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
455 action->updateRemainingLazy(now);
458 share = lmm_variable_getvalue(action->getVariable());
461 double time_to_completion;
462 if (action->getRemains() > 0) {
463 time_to_completion = action->getRemainsNoUpdate() / share;
465 time_to_completion = 0.0;
467 min = now + time_to_completion; // when the task will complete if nothing changes
470 if ((action->getMaxDuration() != NO_MAX_DURATION)
472 || action->getStartTime() +
473 action->getMaxDuration() < min)) {
474 min = action->getStartTime() +
475 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
480 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
482 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
483 action->getStartTime(), min, share,
484 action->getMaxDuration());
487 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
488 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
490 } else DIE_IMPOSSIBLE;
493 //hereafter must have already the min value for this resource model
494 if (xbt_heap_size(p_actionHeap) > 0)
495 min = xbt_heap_maxkey(p_actionHeap) - now;
499 XBT_DEBUG("The minimum with the HEAP %f", min);
504 double Model::next_occuring_event_full(double /*now*/) {
508 double Model::shareResourcesMaxMin(ActionList *running_actions,
510 void (*solve) (lmm_system_t))
512 Action *action = NULL;
518 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
519 for(; it != itend ; ++it) {
521 value = lmm_variable_getvalue(action->getVariable());
522 if ((value > 0) || (action->getMaxDuration() >= 0))
530 if (action->getRemains() > 0)
531 min = action->getRemainsNoUpdate() / value;
534 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
535 min = action->getMaxDuration();
537 min = action->getMaxDuration();
540 for (++it; it != itend; ++it) {
542 value = lmm_variable_getvalue(action->getVariable());
544 if (action->getRemains() > 0)
545 value = action->getRemainsNoUpdate() / value;
550 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
553 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
554 min = action->getMaxDuration();
555 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
558 XBT_DEBUG("min value : %f", min);
563 void Model::updateActionsState(double now, double delta)
565 if (p_updateMechanism == UM_FULL)
566 updateActionsStateFull(now, delta);
567 else if (p_updateMechanism == UM_LAZY)
568 updateActionsStateLazy(now, delta);
570 xbt_die("Invalid cpu update mechanism!");
573 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
578 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
593 Resource::Resource(Model *model, const char *name)
594 : Resource(model, name, 1/*ON*/)
597 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint)
598 : Resource(model, name, constraint, 1/*ON*/)
601 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint, int initiallyOn)
602 : p_name(xbt_strdup(name))
604 , m_isOn(initiallyOn)
605 , p_constraint(constraint)
608 Resource::Resource(Model *model, const char *name, int initiallyOn)
609 : p_name(xbt_strdup(name))
611 , m_isOn(initiallyOn)
615 Resource::~Resource() {
616 xbt_free((void*)p_name);
619 bool Resource::isOn() {
622 bool Resource::isOff() {
626 void Resource::turnOn()
633 void Resource::turnOff()
640 Model *Resource::getModel() {
644 const char *Resource::getName() {
648 lmm_constraint_t Resource::getConstraint() {
659 const char *surf_action_state_names[6] = {
661 "SURF_ACTION_RUNNING",
662 "SURF_ACTION_FAILED",
664 "SURF_ACTION_TO_FREE",
665 "SURF_ACTION_NOT_IN_THE_SYSTEM"
668 /* added to manage the communication action's heap */
669 void surf_action_lmm_update_index_heap(void *action, int i) {
670 static_cast<simgrid::surf::Action*>(action)->updateIndexHeap(i);
676 void Action::initialize(simgrid::surf::Model *model, double cost, bool failed,
680 m_start = surf_get_clock();
685 p_stateSet = getModel()->getFailedActionSet();
687 p_stateSet = getModel()->getRunningActionSet();
689 p_stateSet->push_back(*this);
692 Action::Action(simgrid::surf::Model *model, double cost, bool failed)
694 initialize(model, cost, failed);
697 Action::Action(simgrid::surf::Model *model, double cost, bool failed, lmm_variable_t var)
699 initialize(model, cost, failed, var);
703 xbt_free(p_category);
706 void Action::finish() {
707 m_finish = surf_get_clock();
710 e_surf_action_state_t Action::getState()
712 if (p_stateSet == getModel()->getReadyActionSet())
713 return SURF_ACTION_READY;
714 if (p_stateSet == getModel()->getRunningActionSet())
715 return SURF_ACTION_RUNNING;
716 if (p_stateSet == getModel()->getFailedActionSet())
717 return SURF_ACTION_FAILED;
718 if (p_stateSet == getModel()->getDoneActionSet())
719 return SURF_ACTION_DONE;
720 return SURF_ACTION_NOT_IN_THE_SYSTEM;
723 void Action::setState(e_surf_action_state_t state)
725 //surf_action_state_t action_state = &(action->model_type->states);
726 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
727 p_stateSet->erase(p_stateSet->iterator_to(*this));
728 if (state == SURF_ACTION_READY)
729 p_stateSet = getModel()->getReadyActionSet();
730 else if (state == SURF_ACTION_RUNNING)
731 p_stateSet = getModel()->getRunningActionSet();
732 else if (state == SURF_ACTION_FAILED)
733 p_stateSet = getModel()->getFailedActionSet();
734 else if (state == SURF_ACTION_DONE)
735 p_stateSet = getModel()->getDoneActionSet();
740 p_stateSet->push_back(*this);
744 double Action::getBound()
746 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
749 void Action::setBound(double bound)
751 XBT_IN("(%p,%g)", this, bound);
753 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
755 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
756 heapRemove(getModel()->getActionHeap());
760 double Action::getStartTime()
765 double Action::getFinishTime()
767 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
768 return m_remains == 0 ? m_finish : -1;
771 void Action::setData(void* data)
776 void Action::setCategory(const char *category)
778 XBT_IN("(%p,%s)", this, category);
779 p_category = xbt_strdup(category);
787 void Action::setMaxDuration(double duration)
789 XBT_IN("(%p,%g)", this, duration);
790 m_maxDuration = duration;
791 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
792 heapRemove(getModel()->getActionHeap());
796 void Action::gapRemove() {}
798 void Action::setPriority(double priority)
800 XBT_IN("(%p,%g)", this, priority);
801 m_priority = priority;
802 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
804 if (getModel()->getUpdateMechanism() == UM_LAZY)
805 heapRemove(getModel()->getActionHeap());
809 void Action::cancel(){
810 setState(SURF_ACTION_FAILED);
811 if (getModel()->getUpdateMechanism() == UM_LAZY) {
812 if (action_lmm_hook.is_linked())
813 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
814 heapRemove(getModel()->getActionHeap());
821 if (action_hook.is_linked())
822 p_stateSet->erase(p_stateSet->iterator_to(*this));
824 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
825 if (getModel()->getUpdateMechanism() == UM_LAZY) {
826 /* remove from heap */
827 heapRemove(getModel()->getActionHeap());
828 if (action_lmm_hook.is_linked())
829 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
837 void Action::suspend()
839 XBT_IN("(%p)", this);
840 if (m_suspended != 2) {
841 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
843 if (getModel()->getUpdateMechanism() == UM_LAZY)
844 heapRemove(getModel()->getActionHeap());
849 void Action::resume()
851 XBT_IN("(%p)", this);
852 if (m_suspended != 2) {
853 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
855 if (getModel()->getUpdateMechanism() == UM_LAZY)
856 heapRemove(getModel()->getActionHeap());
861 bool Action::isSuspended()
863 return m_suspended == 1;
865 /* insert action on heap using a given key and a hat (heap_action_type)
866 * a hat can be of three types for communications:
868 * NORMAL = this is a normal heap entry stating the date to finish transmitting
869 * LATENCY = this is a heap entry to warn us when the latency is payed
870 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
872 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
875 xbt_heap_push(heap, this, key);
878 void Action::heapRemove(xbt_heap_t heap)
881 if (m_indexHeap >= 0) {
882 xbt_heap_remove(heap, m_indexHeap);
886 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
889 if (m_indexHeap >= 0) {
890 xbt_heap_update(heap, m_indexHeap, key);
892 xbt_heap_push(heap, this, key);
896 void Action::updateIndexHeap(int i) {
900 double Action::getRemains()
902 XBT_IN("(%p)", this);
903 /* update remains before return it */
904 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
905 updateRemainingLazy(surf_get_clock());
910 double Action::getRemainsNoUpdate()
915 //FIXME split code in the right places
916 void Action::updateRemainingLazy(double now)
920 if(getModel() == surf_network_model)
922 if (m_suspended != 0)
927 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
928 "You're updating an action that is not running.");
930 /* bogus priority, skip it */
931 xbt_assert(m_priority > 0,
932 "You're updating an action that seems suspended.");
935 delta = now - m_lastUpdate;
938 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
939 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
941 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
942 simgrid::surf::Resource *cpu = static_cast<simgrid::surf::Resource*>(
943 lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
944 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
946 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
949 if(getModel() == surf_network_model)
951 if (m_maxDuration != NO_MAX_DURATION)
952 double_update(&m_maxDuration, delta, sg_surf_precision);
954 //FIXME: duplicated code
955 if ((m_remains <= 0) &&
956 (lmm_get_variable_weight(getVariable()) > 0)) {
958 setState(SURF_ACTION_DONE);
959 heapRemove(getModel()->getActionHeap());
960 } else if (((m_maxDuration != NO_MAX_DURATION)
961 && (m_maxDuration <= 0))) {
963 setState(SURF_ACTION_DONE);
964 heapRemove(getModel()->getActionHeap());
969 m_lastValue = lmm_variable_getvalue(getVariable());