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 "src/portable.h"
8 #include "surf_private.h"
9 #include "surf_interface.hpp"
10 #include "network_interface.hpp"
11 #include "cpu_interface.hpp"
12 #include "src/surf/HostImpl.hpp"
13 #include "src/simix/smx_host_private.h"
14 #include "surf_routing.hpp"
15 #include "simgrid/sg_config.h"
17 #include "virtual_machine.hpp"
18 #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 surf_storage_free(void *r)
271 delete static_cast<simgrid::surf::Storage*>(r);
274 void sg_version_check(int lib_version_major,int lib_version_minor,int lib_version_patch) {
275 if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) {
277 "FATAL ERROR: Your program was compiled with SimGrid version %d.%d.%d, "
278 "and then linked against SimGrid %d.%d.%d. Please fix this.\n",
279 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
280 lib_version_major,lib_version_minor,lib_version_patch);
283 if (lib_version_patch != SIMGRID_VERSION_PATCH) {
285 "Warning: Your program was compiled with SimGrid version %d.%d.%d, "
286 "and then linked against SimGrid %d.%d.%d. Proceeding anyway.\n",
287 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
288 lib_version_major,lib_version_minor,lib_version_patch);
292 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
293 *ver_major = SIMGRID_VERSION_MAJOR;
294 *ver_minor = SIMGRID_VERSION_MINOR;
295 *ver_patch = SIMGRID_VERSION_PATCH;
298 void surf_init(int *argc, char **argv)
300 XBT_DEBUG("Create all Libs");
301 host_list = xbt_dict_new_homogeneous([](void*p) {
302 simgrid::s4u::Host* host = static_cast<simgrid::s4u::Host*>(p);
303 simgrid::s4u::Host::onDestruction(*host);
306 USER_HOST_LEVEL = simgrid::s4u::Host::extension_create(NULL);
308 as_router_lib = xbt_lib_new();
309 storage_lib = xbt_lib_new();
310 storage_type_lib = xbt_lib_new();
311 file_lib = xbt_lib_new();
312 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
315 XBT_DEBUG("Add routing levels");
316 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib, NULL);
318 XBT_DEBUG("Add SURF levels");
319 simgrid::surf::HostImpl::classInit();
320 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
322 xbt_init(argc, argv);
323 if (!all_existing_models)
324 all_existing_models = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
325 if (!model_list_invoke)
326 model_list_invoke = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
328 future_evt_set = new simgrid::trace_mgr::future_evt_set();
330 TRACE_add_start_function(TRACE_surf_alloc);
331 TRACE_add_end_function(TRACE_surf_release);
333 sg_config_init(argc, argv);
342 simgrid::surf::Model *model = NULL;
344 TRACE_end(); /* Just in case it was not called by the upper
345 * layer (or there is no upper layer) */
347 sg_config_finalize();
349 xbt_dynar_free(&host_that_restart);
350 xbt_dynar_free(&surf_path);
352 xbt_dict_free(&host_list);
353 xbt_lib_free(&as_router_lib);
354 xbt_lib_free(&storage_lib);
356 xbt_lib_free(&storage_type_lib);
357 xbt_lib_free(&file_lib);
358 xbt_dict_free(&watched_hosts_lib);
360 xbt_dynar_foreach(all_existing_models, iter, model)
362 xbt_dynar_free(&all_existing_models);
363 xbt_dynar_free(&model_list_invoke);
366 simgrid::surf::surfExitCallbacks();
368 if (future_evt_set) {
369 delete future_evt_set;
370 future_evt_set = nullptr;
373 #ifdef HAVE_THREAD_CONTEXTS
374 xbt_parmap_destroy(surf_parmap);
380 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
391 : p_maxminSystem(NULL)
393 p_readyActionSet = new ActionList();
394 p_runningActionSet = new ActionList();
395 p_failedActionSet = new ActionList();
396 p_doneActionSet = new ActionList();
398 p_modifiedSet = NULL;
400 p_updateMechanism = UM_UNDEFINED;
401 m_selectiveUpdate = 0;
405 delete p_readyActionSet;
406 delete p_runningActionSet;
407 delete p_failedActionSet;
408 delete p_doneActionSet;
411 double Model::next_occuring_event(double now)
413 //FIXME: set the good function once and for all
414 if (p_updateMechanism == UM_LAZY)
415 return next_occuring_event_lazy(now);
416 else if (p_updateMechanism == UM_FULL)
417 return next_occuring_event_full(now);
419 xbt_die("Invalid cpu update mechanism!");
422 double Model::next_occuring_event_lazy(double now)
424 Action *action = NULL;
429 ("Before share resources, the size of modified actions set is %zd",
430 p_modifiedSet->size());
432 lmm_solve(p_maxminSystem);
435 ("After share resources, The size of modified actions set is %zd",
436 p_modifiedSet->size());
438 while(!p_modifiedSet->empty()) {
439 action = &(p_modifiedSet->front());
440 p_modifiedSet->pop_front();
441 int max_dur_flag = 0;
443 if (action->getStateSet() != p_runningActionSet)
446 /* bogus priority, skip it */
447 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
450 action->updateRemainingLazy(now);
453 share = lmm_variable_getvalue(action->getVariable());
456 double time_to_completion;
457 if (action->getRemains() > 0) {
458 time_to_completion = action->getRemainsNoUpdate() / share;
460 time_to_completion = 0.0;
462 min = now + time_to_completion; // when the task will complete if nothing changes
465 if ((action->getMaxDuration() != NO_MAX_DURATION)
467 || action->getStartTime() +
468 action->getMaxDuration() < min)) {
469 min = action->getStartTime() +
470 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
475 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
477 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
478 action->getStartTime(), min, share,
479 action->getMaxDuration());
482 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
483 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
485 } else DIE_IMPOSSIBLE;
488 //hereafter must have already the min value for this resource model
489 if (xbt_heap_size(p_actionHeap) > 0)
490 min = xbt_heap_maxkey(p_actionHeap) - now;
494 XBT_DEBUG("The minimum with the HEAP %f", min);
499 double Model::next_occuring_event_full(double /*now*/) {
503 double Model::shareResourcesMaxMin(ActionList *running_actions,
505 void (*solve) (lmm_system_t))
507 Action *action = NULL;
513 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
514 for(; it != itend ; ++it) {
516 value = lmm_variable_getvalue(action->getVariable());
517 if ((value > 0) || (action->getMaxDuration() >= 0))
525 if (action->getRemains() > 0)
526 min = action->getRemainsNoUpdate() / value;
529 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
530 min = action->getMaxDuration();
532 min = action->getMaxDuration();
535 for (++it; it != itend; ++it) {
537 value = lmm_variable_getvalue(action->getVariable());
539 if (action->getRemains() > 0)
540 value = action->getRemainsNoUpdate() / value;
545 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
548 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
549 min = action->getMaxDuration();
550 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
553 XBT_DEBUG("min value : %f", min);
558 void Model::updateActionsState(double now, double delta)
560 if (p_updateMechanism == UM_FULL)
561 updateActionsStateFull(now, delta);
562 else if (p_updateMechanism == UM_LAZY)
563 updateActionsStateLazy(now, delta);
565 xbt_die("Invalid cpu update mechanism!");
568 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
573 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
588 Resource::Resource(Model *model, const char *name)
589 : Resource(model, name, 1/*ON*/)
592 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint)
593 : Resource(model, name, constraint, 1/*ON*/)
596 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint, int initiallyOn)
597 : p_name(xbt_strdup(name))
599 , m_isOn(initiallyOn)
600 , p_constraint(constraint)
603 Resource::Resource(Model *model, const char *name, int initiallyOn)
604 : p_name(xbt_strdup(name))
606 , m_isOn(initiallyOn)
610 Resource::~Resource() {
611 xbt_free((void*)p_name);
614 bool Resource::isOn() {
617 bool Resource::isOff() {
621 void Resource::turnOn()
628 void Resource::turnOff()
635 Model *Resource::getModel() {
639 const char *Resource::getName() {
643 lmm_constraint_t Resource::getConstraint() {
654 const char *surf_action_state_names[6] = {
656 "SURF_ACTION_RUNNING",
657 "SURF_ACTION_FAILED",
659 "SURF_ACTION_TO_FREE",
660 "SURF_ACTION_NOT_IN_THE_SYSTEM"
663 /* added to manage the communication action's heap */
664 void surf_action_lmm_update_index_heap(void *action, int i) {
665 static_cast<simgrid::surf::Action*>(action)->updateIndexHeap(i);
671 void Action::initialize(simgrid::surf::Model *model, double cost, bool failed,
675 m_start = surf_get_clock();
680 p_stateSet = getModel()->getFailedActionSet();
682 p_stateSet = getModel()->getRunningActionSet();
684 p_stateSet->push_back(*this);
687 Action::Action(simgrid::surf::Model *model, double cost, bool failed)
689 initialize(model, cost, failed);
692 Action::Action(simgrid::surf::Model *model, double cost, bool failed, lmm_variable_t var)
694 initialize(model, cost, failed, var);
698 xbt_free(p_category);
701 void Action::finish() {
702 m_finish = surf_get_clock();
705 e_surf_action_state_t Action::getState()
707 if (p_stateSet == getModel()->getReadyActionSet())
708 return SURF_ACTION_READY;
709 if (p_stateSet == getModel()->getRunningActionSet())
710 return SURF_ACTION_RUNNING;
711 if (p_stateSet == getModel()->getFailedActionSet())
712 return SURF_ACTION_FAILED;
713 if (p_stateSet == getModel()->getDoneActionSet())
714 return SURF_ACTION_DONE;
715 return SURF_ACTION_NOT_IN_THE_SYSTEM;
718 void Action::setState(e_surf_action_state_t state)
720 //surf_action_state_t action_state = &(action->model_type->states);
721 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
722 p_stateSet->erase(p_stateSet->iterator_to(*this));
723 if (state == SURF_ACTION_READY)
724 p_stateSet = getModel()->getReadyActionSet();
725 else if (state == SURF_ACTION_RUNNING)
726 p_stateSet = getModel()->getRunningActionSet();
727 else if (state == SURF_ACTION_FAILED)
728 p_stateSet = getModel()->getFailedActionSet();
729 else if (state == SURF_ACTION_DONE)
730 p_stateSet = getModel()->getDoneActionSet();
735 p_stateSet->push_back(*this);
739 double Action::getBound()
741 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
744 void Action::setBound(double bound)
746 XBT_IN("(%p,%g)", this, bound);
748 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
750 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
751 heapRemove(getModel()->getActionHeap());
755 double Action::getStartTime()
760 double Action::getFinishTime()
762 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
763 return m_remains == 0 ? m_finish : -1;
766 void Action::setData(void* data)
771 void Action::setCategory(const char *category)
773 XBT_IN("(%p,%s)", this, category);
774 p_category = xbt_strdup(category);
782 void Action::setMaxDuration(double duration)
784 XBT_IN("(%p,%g)", this, duration);
785 m_maxDuration = duration;
786 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
787 heapRemove(getModel()->getActionHeap());
791 void Action::gapRemove() {}
793 void Action::setPriority(double priority)
795 XBT_IN("(%p,%g)", this, priority);
796 m_priority = priority;
797 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
799 if (getModel()->getUpdateMechanism() == UM_LAZY)
800 heapRemove(getModel()->getActionHeap());
804 void Action::cancel(){
805 setState(SURF_ACTION_FAILED);
806 if (getModel()->getUpdateMechanism() == UM_LAZY) {
807 if (action_lmm_hook.is_linked())
808 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
809 heapRemove(getModel()->getActionHeap());
816 if (action_hook.is_linked())
817 p_stateSet->erase(p_stateSet->iterator_to(*this));
819 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
820 if (getModel()->getUpdateMechanism() == UM_LAZY) {
821 /* remove from heap */
822 heapRemove(getModel()->getActionHeap());
823 if (action_lmm_hook.is_linked())
824 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
832 void Action::suspend()
834 XBT_IN("(%p)", this);
835 if (m_suspended != 2) {
836 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
838 if (getModel()->getUpdateMechanism() == UM_LAZY)
839 heapRemove(getModel()->getActionHeap());
844 void Action::resume()
846 XBT_IN("(%p)", this);
847 if (m_suspended != 2) {
848 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
850 if (getModel()->getUpdateMechanism() == UM_LAZY)
851 heapRemove(getModel()->getActionHeap());
856 bool Action::isSuspended()
858 return m_suspended == 1;
860 /* insert action on heap using a given key and a hat (heap_action_type)
861 * a hat can be of three types for communications:
863 * NORMAL = this is a normal heap entry stating the date to finish transmitting
864 * LATENCY = this is a heap entry to warn us when the latency is payed
865 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
867 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
870 xbt_heap_push(heap, this, key);
873 void Action::heapRemove(xbt_heap_t heap)
876 if (m_indexHeap >= 0) {
877 xbt_heap_remove(heap, m_indexHeap);
881 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
884 if (m_indexHeap >= 0) {
885 xbt_heap_update(heap, m_indexHeap, key);
887 xbt_heap_push(heap, this, key);
891 void Action::updateIndexHeap(int i) {
895 double Action::getRemains()
897 XBT_IN("(%p)", this);
898 /* update remains before return it */
899 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
900 updateRemainingLazy(surf_get_clock());
905 double Action::getRemainsNoUpdate()
910 //FIXME split code in the right places
911 void Action::updateRemainingLazy(double now)
915 if(getModel() == surf_network_model)
917 if (m_suspended != 0)
922 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
923 "You're updating an action that is not running.");
925 /* bogus priority, skip it */
926 xbt_assert(m_priority > 0,
927 "You're updating an action that seems suspended.");
930 delta = now - m_lastUpdate;
933 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
934 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
936 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
937 simgrid::surf::Resource *cpu = static_cast<simgrid::surf::Resource*>(
938 lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
939 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
941 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
944 if(getModel() == surf_network_model)
946 if (m_maxDuration != NO_MAX_DURATION)
947 double_update(&m_maxDuration, delta, sg_surf_precision);
949 //FIXME: duplicated code
950 if ((m_remains <= 0) &&
951 (lmm_get_variable_weight(getVariable()) > 0)) {
953 setState(SURF_ACTION_DONE);
954 heapRemove(getModel()->getActionHeap());
955 } else if (((m_maxDuration != NO_MAX_DURATION)
956 && (m_maxDuration <= 0))) {
958 setState(SURF_ACTION_DONE);
959 heapRemove(getModel()->getActionHeap());
964 m_lastValue = lmm_variable_getvalue(getVariable());