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"
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 /* model_list_invoke contains only surf_host and surf_vm.
27 * The callback functions of cpu_model and network_model will be called from
28 * those of these host models. */
29 xbt_dynar_t all_existing_models = NULL; /* to destroy models correctly */
30 xbt_dynar_t model_list_invoke = NULL; /* to invoke callbacks */
32 simgrid::trace_mgr::future_evt_set *future_evt_set = nullptr;
33 xbt_dynar_t surf_path = NULL;
34 xbt_dynar_t host_that_restart = xbt_dynar_new(sizeof(char*), NULL);
35 xbt_dict_t watched_hosts_lib;
40 simgrid::xbt::signal<void(void)> surfExitCallbacks;
45 #include <simgrid/plugins/energy.h> // FIXME: this plugin should not be linked to the core
47 s_surf_model_description_t surf_plugin_description[] = {
48 {"Energy", "Cpu energy consumption.", sg_energy_plugin_init},
49 {NULL, NULL, NULL} /* this array must be NULL terminated */
52 /* Don't forget to update the option description in smx_config when you change
54 s_surf_model_description_t surf_network_model_description[] = {
56 "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). ",
57 surf_network_model_init_LegrandVelho},
59 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
60 surf_network_model_init_Constant},
62 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
63 surf_network_model_init_SMPI},
65 "Realistic network model specifically tailored for HPC settings, with Infiniband contention model",
66 surf_network_model_init_IB},
68 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
69 surf_network_model_init_CM02},
72 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
73 surf_network_model_init_NS3},
76 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
77 surf_network_model_init_Reno},
79 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
80 surf_network_model_init_Reno2},
82 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
83 surf_network_model_init_Vegas},
84 {NULL, NULL, NULL} /* this array must be NULL terminated */
87 s_surf_model_description_t surf_cpu_model_description[] = {
89 "Simplistic CPU model (time=size/power).",
90 surf_cpu_model_init_Cas01},
91 {NULL, NULL, NULL} /* this array must be NULL terminated */
94 s_surf_model_description_t surf_host_model_description[] = {
96 "Default host model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
97 surf_host_model_init_current_default},
99 "Host model that is automatically chosen if you change the network and CPU models",
100 surf_host_model_init_compound},
101 {"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks",
102 surf_host_model_init_ptask_L07},
103 {NULL, NULL, NULL} /* this array must be NULL terminated */
106 s_surf_model_description_t surf_vm_model_description[] = {
109 surf_vm_model_init_HL13},
110 {NULL, NULL, NULL} /* this array must be NULL terminated */
113 s_surf_model_description_t surf_optimization_mode_description[] = {
115 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
118 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
121 "Full update of remaining and variables. Slow but may be useful when debugging.",
123 {NULL, NULL, NULL} /* this array must be NULL terminated */
126 s_surf_model_description_t surf_storage_model_description[] = {
128 "Simplistic storage model.",
129 surf_storage_model_init_default},
130 {NULL, NULL, NULL} /* this array must be NULL terminated */
133 #ifdef HAVE_THREAD_CONTEXTS
134 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
139 double surf_get_clock(void)
145 # define FILE_DELIM "\\"
147 # define FILE_DELIM "/" /* FIXME: move to better location */
150 FILE *surf_fopen(const char *name, const char *mode)
153 char *path_elm = NULL;
159 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
160 return fopen(name, mode);
162 /* search relative files in the path */
163 xbt_dynar_foreach(surf_path, cpt, path_elm) {
164 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
165 file = fopen(buff, mode);
177 static const char *disk_drives_letter_table[MAX_DRIVE] = {
178 "A:\\","B:\\","C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\",
179 "N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"
184 * Returns the initial path. On Windows the initial path is
185 * the current directory for the current process in the other
186 * case the function returns "./" that represents the current
187 * directory on Unix/Linux platforms.
190 const char *__surf_get_initial_path(void)
195 char current_directory[MAX_PATH + 1] = { 0 };
196 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
197 char root[4] = { 0 };
202 strncpy(root, current_directory, 3);
204 for (i = 0; i < MAX_DRIVE; i++) {
205 if (toupper(root[0]) == disk_drives_letter_table[i][0])
206 return disk_drives_letter_table[i];
215 /* The __surf_is_absolute_file_path() returns 1 if
216 * file_path is a absolute file path, in the other
217 * case the function returns 0.
219 int __surf_is_absolute_file_path(const char *file_path)
222 WIN32_FIND_DATA wfd = { 0 };
223 HANDLE hFile = FindFirstFile(file_path, &wfd);
225 if (INVALID_HANDLE_VALUE == hFile)
231 return (file_path[0] == '/');
235 /** Displays the long description of all registered models, and quit */
236 void model_help(const char *category, s_surf_model_description_t * table)
239 printf("Long description of the %s models accepted by this simulator:\n",
241 for (i = 0; table[i].name; i++)
242 printf(" %s: %s\n", table[i].name, table[i].description);
245 int find_model_description(s_surf_model_description_t * table,
249 char *name_list = NULL;
251 for (i = 0; table[i].name; i++)
252 if (!strcmp(name, table[i].name)) {
256 xbt_die("No model is valid! This is a bug.");
257 name_list = xbt_strdup(table[0].name);
258 for (i = 1; table[i].name; i++) {
259 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
260 strcat(name_list, ", ");
261 strcat(name_list, table[i].name);
263 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
267 static XBT_INLINE void routing_asr_prop_free(void *p)
269 //xbt_dict_t elm = (xbt_dict_t) p;
270 //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster
273 static XBT_INLINE void surf_storage_free(void *r)
275 delete static_cast<simgrid::surf::Storage*>(r);
278 void sg_version_check(int lib_version_major,int lib_version_minor,int lib_version_patch) {
279 if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) {
281 "FATAL ERROR: Your program was compiled with SimGrid version %d.%d.%d, "
282 "and then linked against SimGrid %d.%d.%d. Please fix this.\n",
283 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
284 lib_version_major,lib_version_minor,lib_version_patch);
287 if (lib_version_patch != SIMGRID_VERSION_PATCH) {
289 "Warning: Your program was compiled with SimGrid version %d.%d.%d, "
290 "and then linked against SimGrid %d.%d.%d. Proceeding anyway.\n",
291 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
292 lib_version_major,lib_version_minor,lib_version_patch);
296 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
297 *ver_major = SIMGRID_VERSION_MAJOR;
298 *ver_minor = SIMGRID_VERSION_MINOR;
299 *ver_patch = SIMGRID_VERSION_PATCH;
302 void surf_init(int *argc, char **argv)
304 XBT_DEBUG("Create all Libs");
305 host_list = xbt_dict_new_homogeneous([](void*p) {
306 simgrid::s4u::Host* host = static_cast<simgrid::s4u::Host*>(p);
307 simgrid::s4u::Host::onDestruction(*host);
310 as_router_lib = xbt_lib_new();
311 storage_lib = xbt_lib_new();
312 storage_type_lib = xbt_lib_new();
313 file_lib = xbt_lib_new();
314 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
318 XBT_DEBUG("Add routing levels");
319 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
321 XBT_DEBUG("Add SURF levels");
322 simgrid::surf::Host::classInit();
323 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
325 xbt_init(argc, argv);
326 if (!all_existing_models)
327 all_existing_models = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
328 if (!model_list_invoke)
329 model_list_invoke = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
331 future_evt_set = new simgrid::trace_mgr::future_evt_set();
333 TRACE_add_start_function(TRACE_surf_alloc);
334 TRACE_add_end_function(TRACE_surf_release);
336 sg_config_init(argc, argv);
345 simgrid::surf::Model *model = NULL;
347 TRACE_end(); /* Just in case it was not called by the upper
348 * layer (or there is no upper layer) */
350 sg_config_finalize();
352 xbt_dynar_free(&host_that_restart);
353 xbt_dynar_free(&surf_path);
355 xbt_dict_free(&host_list);
356 xbt_lib_free(&as_router_lib);
357 xbt_lib_free(&storage_lib);
359 xbt_lib_free(&storage_type_lib);
360 xbt_lib_free(&file_lib);
361 xbt_dict_free(&watched_hosts_lib);
363 xbt_dynar_foreach(all_existing_models, iter, model)
365 xbt_dynar_free(&all_existing_models);
366 xbt_dynar_free(&model_list_invoke);
369 simgrid::surf::surfExitCallbacks();
371 if (future_evt_set) {
372 delete future_evt_set;
373 future_evt_set = nullptr;
376 #ifdef HAVE_THREAD_CONTEXTS
377 xbt_parmap_destroy(surf_parmap);
383 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
394 : p_maxminSystem(NULL)
396 p_readyActionSet = new ActionList();
397 p_runningActionSet = new ActionList();
398 p_failedActionSet = new ActionList();
399 p_doneActionSet = new ActionList();
401 p_modifiedSet = NULL;
403 p_updateMechanism = UM_UNDEFINED;
404 m_selectiveUpdate = 0;
408 delete p_readyActionSet;
409 delete p_runningActionSet;
410 delete p_failedActionSet;
411 delete p_doneActionSet;
414 double Model::next_occuring_event(double now)
416 //FIXME: set the good function once and for all
417 if (p_updateMechanism == UM_LAZY)
418 return next_occuring_event_lazy(now);
419 else if (p_updateMechanism == UM_FULL)
420 return next_occuring_event_full(now);
422 xbt_die("Invalid cpu update mechanism!");
425 double Model::next_occuring_event_lazy(double now)
427 Action *action = NULL;
432 ("Before share resources, the size of modified actions set is %zd",
433 p_modifiedSet->size());
435 lmm_solve(p_maxminSystem);
438 ("After share resources, The size of modified actions set is %zd",
439 p_modifiedSet->size());
441 while(!p_modifiedSet->empty()) {
442 action = &(p_modifiedSet->front());
443 p_modifiedSet->pop_front();
444 int max_dur_flag = 0;
446 if (action->getStateSet() != p_runningActionSet)
449 /* bogus priority, skip it */
450 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
453 action->updateRemainingLazy(now);
456 share = lmm_variable_getvalue(action->getVariable());
459 double time_to_completion;
460 if (action->getRemains() > 0) {
461 time_to_completion = action->getRemainsNoUpdate() / share;
463 time_to_completion = 0.0;
465 min = now + time_to_completion; // when the task will complete if nothing changes
468 if ((action->getMaxDuration() != NO_MAX_DURATION)
470 || action->getStartTime() +
471 action->getMaxDuration() < min)) {
472 min = action->getStartTime() +
473 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
478 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
480 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
481 action->getStartTime(), min, share,
482 action->getMaxDuration());
485 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
486 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
488 } else DIE_IMPOSSIBLE;
491 //hereafter must have already the min value for this resource model
492 if (xbt_heap_size(p_actionHeap) > 0)
493 min = xbt_heap_maxkey(p_actionHeap) - now;
497 XBT_DEBUG("The minimum with the HEAP %f", min);
502 double Model::next_occuring_event_full(double /*now*/) {
506 double Model::shareResourcesMaxMin(ActionList *running_actions,
508 void (*solve) (lmm_system_t))
510 Action *action = NULL;
516 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
517 for(; it != itend ; ++it) {
519 value = lmm_variable_getvalue(action->getVariable());
520 if ((value > 0) || (action->getMaxDuration() >= 0))
528 if (action->getRemains() > 0)
529 min = action->getRemainsNoUpdate() / value;
532 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
533 min = action->getMaxDuration();
535 min = action->getMaxDuration();
538 for (++it; it != itend; ++it) {
540 value = lmm_variable_getvalue(action->getVariable());
542 if (action->getRemains() > 0)
543 value = action->getRemainsNoUpdate() / value;
548 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
551 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
552 min = action->getMaxDuration();
553 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
556 XBT_DEBUG("min value : %f", min);
561 void Model::updateActionsState(double now, double delta)
563 if (p_updateMechanism == UM_FULL)
564 updateActionsStateFull(now, delta);
565 else if (p_updateMechanism == UM_LAZY)
566 updateActionsStateLazy(now, delta);
568 xbt_die("Invalid cpu update mechanism!");
571 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
576 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
591 Resource::Resource(Model *model, const char *name)
592 : Resource(model, name, 1/*ON*/)
595 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint)
596 : Resource(model, name, constraint, 1/*ON*/)
599 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint, int initiallyOn)
600 : p_name(xbt_strdup(name))
602 , m_isOn(initiallyOn)
603 , p_constraint(constraint)
606 Resource::Resource(Model *model, const char *name, int initiallyOn)
607 : p_name(xbt_strdup(name))
609 , m_isOn(initiallyOn)
613 Resource::~Resource() {
614 xbt_free((void*)p_name);
617 bool Resource::isOn() {
620 bool Resource::isOff() {
624 void Resource::turnOn()
631 void Resource::turnOff()
638 Model *Resource::getModel() {
642 const char *Resource::getName() {
646 lmm_constraint_t Resource::getConstraint() {
657 const char *surf_action_state_names[6] = {
659 "SURF_ACTION_RUNNING",
660 "SURF_ACTION_FAILED",
662 "SURF_ACTION_TO_FREE",
663 "SURF_ACTION_NOT_IN_THE_SYSTEM"
666 /* added to manage the communication action's heap */
667 void surf_action_lmm_update_index_heap(void *action, int i) {
668 static_cast<simgrid::surf::Action*>(action)->updateIndexHeap(i);
674 void Action::initialize(simgrid::surf::Model *model, double cost, bool failed,
678 m_start = surf_get_clock();
683 p_stateSet = getModel()->getFailedActionSet();
685 p_stateSet = getModel()->getRunningActionSet();
687 p_stateSet->push_back(*this);
690 Action::Action(simgrid::surf::Model *model, double cost, bool failed)
692 initialize(model, cost, failed);
695 Action::Action(simgrid::surf::Model *model, double cost, bool failed, lmm_variable_t var)
697 initialize(model, cost, failed, var);
701 xbt_free(p_category);
704 void Action::finish() {
705 m_finish = surf_get_clock();
708 e_surf_action_state_t Action::getState()
710 if (p_stateSet == getModel()->getReadyActionSet())
711 return SURF_ACTION_READY;
712 if (p_stateSet == getModel()->getRunningActionSet())
713 return SURF_ACTION_RUNNING;
714 if (p_stateSet == getModel()->getFailedActionSet())
715 return SURF_ACTION_FAILED;
716 if (p_stateSet == getModel()->getDoneActionSet())
717 return SURF_ACTION_DONE;
718 return SURF_ACTION_NOT_IN_THE_SYSTEM;
721 void Action::setState(e_surf_action_state_t state)
723 //surf_action_state_t action_state = &(action->model_type->states);
724 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
725 p_stateSet->erase(p_stateSet->iterator_to(*this));
726 if (state == SURF_ACTION_READY)
727 p_stateSet = getModel()->getReadyActionSet();
728 else if (state == SURF_ACTION_RUNNING)
729 p_stateSet = getModel()->getRunningActionSet();
730 else if (state == SURF_ACTION_FAILED)
731 p_stateSet = getModel()->getFailedActionSet();
732 else if (state == SURF_ACTION_DONE)
733 p_stateSet = getModel()->getDoneActionSet();
738 p_stateSet->push_back(*this);
742 double Action::getBound()
744 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
747 void Action::setBound(double bound)
749 XBT_IN("(%p,%g)", this, bound);
751 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
753 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
754 heapRemove(getModel()->getActionHeap());
758 double Action::getStartTime()
763 double Action::getFinishTime()
765 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
766 return m_remains == 0 ? m_finish : -1;
769 void Action::setData(void* data)
774 void Action::setCategory(const char *category)
776 XBT_IN("(%p,%s)", this, category);
777 p_category = xbt_strdup(category);
785 void Action::setMaxDuration(double duration)
787 XBT_IN("(%p,%g)", this, duration);
788 m_maxDuration = duration;
789 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
790 heapRemove(getModel()->getActionHeap());
794 void Action::gapRemove() {}
796 void Action::setPriority(double priority)
798 XBT_IN("(%p,%g)", this, priority);
799 m_priority = priority;
800 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
802 if (getModel()->getUpdateMechanism() == UM_LAZY)
803 heapRemove(getModel()->getActionHeap());
807 void Action::cancel(){
808 setState(SURF_ACTION_FAILED);
809 if (getModel()->getUpdateMechanism() == UM_LAZY) {
810 if (action_lmm_hook.is_linked())
811 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
812 heapRemove(getModel()->getActionHeap());
819 if (action_hook.is_linked())
820 p_stateSet->erase(p_stateSet->iterator_to(*this));
822 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
823 if (getModel()->getUpdateMechanism() == UM_LAZY) {
824 /* remove from heap */
825 heapRemove(getModel()->getActionHeap());
826 if (action_lmm_hook.is_linked())
827 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
835 void Action::suspend()
837 XBT_IN("(%p)", this);
838 if (m_suspended != 2) {
839 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
841 if (getModel()->getUpdateMechanism() == UM_LAZY)
842 heapRemove(getModel()->getActionHeap());
847 void Action::resume()
849 XBT_IN("(%p)", this);
850 if (m_suspended != 2) {
851 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
853 if (getModel()->getUpdateMechanism() == UM_LAZY)
854 heapRemove(getModel()->getActionHeap());
859 bool Action::isSuspended()
861 return m_suspended == 1;
863 /* insert action on heap using a given key and a hat (heap_action_type)
864 * a hat can be of three types for communications:
866 * NORMAL = this is a normal heap entry stating the date to finish transmitting
867 * LATENCY = this is a heap entry to warn us when the latency is payed
868 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
870 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
873 xbt_heap_push(heap, this, key);
876 void Action::heapRemove(xbt_heap_t heap)
879 if (m_indexHeap >= 0) {
880 xbt_heap_remove(heap, m_indexHeap);
884 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
887 if (m_indexHeap >= 0) {
888 xbt_heap_update(heap, m_indexHeap, key);
890 xbt_heap_push(heap, this, key);
894 void Action::updateIndexHeap(int i) {
898 double Action::getRemains()
900 XBT_IN("(%p)", this);
901 /* update remains before return it */
902 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
903 updateRemainingLazy(surf_get_clock());
908 double Action::getRemainsNoUpdate()
913 //FIXME split code in the right places
914 void Action::updateRemainingLazy(double now)
918 if(getModel() == surf_network_model)
920 if (m_suspended != 0)
925 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
926 "You're updating an action that is not running.");
928 /* bogus priority, skip it */
929 xbt_assert(m_priority > 0,
930 "You're updating an action that seems suspended.");
933 delta = now - m_lastUpdate;
936 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
937 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
939 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
940 simgrid::surf::Resource *cpu = static_cast<simgrid::surf::Resource*>(
941 lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
942 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
944 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
947 if(getModel() == surf_network_model)
949 if (m_maxDuration != NO_MAX_DURATION)
950 double_update(&m_maxDuration, delta, sg_surf_precision);
952 //FIXME: duplicated code
953 if ((m_remains <= 0) &&
954 (lmm_get_variable_weight(getVariable()) > 0)) {
956 setState(SURF_ACTION_DONE);
957 heapRemove(getModel()->getActionHeap());
958 } else if (((m_maxDuration != NO_MAX_DURATION)
959 && (m_maxDuration <= 0))) {
961 setState(SURF_ACTION_DONE);
962 heapRemove(getModel()->getActionHeap());
967 m_lastValue = lmm_variable_getvalue(getVariable());