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 as_router_lib = xbt_lib_new();
307 storage_lib = xbt_lib_new();
308 storage_type_lib = xbt_lib_new();
309 file_lib = xbt_lib_new();
310 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
314 XBT_DEBUG("Add routing levels");
315 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib, NULL);
317 XBT_DEBUG("Add SURF levels");
318 simgrid::surf::HostImpl::classInit();
319 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
321 xbt_init(argc, argv);
322 if (!all_existing_models)
323 all_existing_models = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
324 if (!model_list_invoke)
325 model_list_invoke = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
327 future_evt_set = new simgrid::trace_mgr::future_evt_set();
329 TRACE_add_start_function(TRACE_surf_alloc);
330 TRACE_add_end_function(TRACE_surf_release);
332 sg_config_init(argc, argv);
341 simgrid::surf::Model *model = NULL;
343 TRACE_end(); /* Just in case it was not called by the upper
344 * layer (or there is no upper layer) */
346 sg_config_finalize();
348 xbt_dynar_free(&host_that_restart);
349 xbt_dynar_free(&surf_path);
351 xbt_dict_free(&host_list);
352 xbt_lib_free(&as_router_lib);
353 xbt_lib_free(&storage_lib);
355 xbt_lib_free(&storage_type_lib);
356 xbt_lib_free(&file_lib);
357 xbt_dict_free(&watched_hosts_lib);
359 xbt_dynar_foreach(all_existing_models, iter, model)
361 xbt_dynar_free(&all_existing_models);
362 xbt_dynar_free(&model_list_invoke);
365 simgrid::surf::surfExitCallbacks();
367 if (future_evt_set) {
368 delete future_evt_set;
369 future_evt_set = nullptr;
372 #ifdef HAVE_THREAD_CONTEXTS
373 xbt_parmap_destroy(surf_parmap);
379 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
390 : p_maxminSystem(NULL)
392 p_readyActionSet = new ActionList();
393 p_runningActionSet = new ActionList();
394 p_failedActionSet = new ActionList();
395 p_doneActionSet = new ActionList();
397 p_modifiedSet = NULL;
399 p_updateMechanism = UM_UNDEFINED;
400 m_selectiveUpdate = 0;
404 delete p_readyActionSet;
405 delete p_runningActionSet;
406 delete p_failedActionSet;
407 delete p_doneActionSet;
410 double Model::next_occuring_event(double now)
412 //FIXME: set the good function once and for all
413 if (p_updateMechanism == UM_LAZY)
414 return next_occuring_event_lazy(now);
415 else if (p_updateMechanism == UM_FULL)
416 return next_occuring_event_full(now);
418 xbt_die("Invalid cpu update mechanism!");
421 double Model::next_occuring_event_lazy(double now)
423 Action *action = NULL;
428 ("Before share resources, the size of modified actions set is %zd",
429 p_modifiedSet->size());
431 lmm_solve(p_maxminSystem);
434 ("After share resources, The size of modified actions set is %zd",
435 p_modifiedSet->size());
437 while(!p_modifiedSet->empty()) {
438 action = &(p_modifiedSet->front());
439 p_modifiedSet->pop_front();
440 int max_dur_flag = 0;
442 if (action->getStateSet() != p_runningActionSet)
445 /* bogus priority, skip it */
446 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
449 action->updateRemainingLazy(now);
452 share = lmm_variable_getvalue(action->getVariable());
455 double time_to_completion;
456 if (action->getRemains() > 0) {
457 time_to_completion = action->getRemainsNoUpdate() / share;
459 time_to_completion = 0.0;
461 min = now + time_to_completion; // when the task will complete if nothing changes
464 if ((action->getMaxDuration() != NO_MAX_DURATION)
466 || action->getStartTime() +
467 action->getMaxDuration() < min)) {
468 min = action->getStartTime() +
469 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
474 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
476 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
477 action->getStartTime(), min, share,
478 action->getMaxDuration());
481 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
482 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
484 } else DIE_IMPOSSIBLE;
487 //hereafter must have already the min value for this resource model
488 if (xbt_heap_size(p_actionHeap) > 0)
489 min = xbt_heap_maxkey(p_actionHeap) - now;
493 XBT_DEBUG("The minimum with the HEAP %f", min);
498 double Model::next_occuring_event_full(double /*now*/) {
502 double Model::shareResourcesMaxMin(ActionList *running_actions,
504 void (*solve) (lmm_system_t))
506 Action *action = NULL;
512 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
513 for(; it != itend ; ++it) {
515 value = lmm_variable_getvalue(action->getVariable());
516 if ((value > 0) || (action->getMaxDuration() >= 0))
524 if (action->getRemains() > 0)
525 min = action->getRemainsNoUpdate() / value;
528 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
529 min = action->getMaxDuration();
531 min = action->getMaxDuration();
534 for (++it; it != itend; ++it) {
536 value = lmm_variable_getvalue(action->getVariable());
538 if (action->getRemains() > 0)
539 value = action->getRemainsNoUpdate() / value;
544 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
547 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
548 min = action->getMaxDuration();
549 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
552 XBT_DEBUG("min value : %f", min);
557 void Model::updateActionsState(double now, double delta)
559 if (p_updateMechanism == UM_FULL)
560 updateActionsStateFull(now, delta);
561 else if (p_updateMechanism == UM_LAZY)
562 updateActionsStateLazy(now, delta);
564 xbt_die("Invalid cpu update mechanism!");
567 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
572 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
587 Resource::Resource(Model *model, const char *name)
588 : Resource(model, name, 1/*ON*/)
591 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint)
592 : Resource(model, name, constraint, 1/*ON*/)
595 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint, int initiallyOn)
596 : p_name(xbt_strdup(name))
598 , m_isOn(initiallyOn)
599 , p_constraint(constraint)
602 Resource::Resource(Model *model, const char *name, int initiallyOn)
603 : p_name(xbt_strdup(name))
605 , m_isOn(initiallyOn)
609 Resource::~Resource() {
610 xbt_free((void*)p_name);
613 bool Resource::isOn() {
616 bool Resource::isOff() {
620 void Resource::turnOn()
627 void Resource::turnOff()
634 Model *Resource::getModel() {
638 const char *Resource::getName() {
642 lmm_constraint_t Resource::getConstraint() {
653 const char *surf_action_state_names[6] = {
655 "SURF_ACTION_RUNNING",
656 "SURF_ACTION_FAILED",
658 "SURF_ACTION_TO_FREE",
659 "SURF_ACTION_NOT_IN_THE_SYSTEM"
662 /* added to manage the communication action's heap */
663 void surf_action_lmm_update_index_heap(void *action, int i) {
664 static_cast<simgrid::surf::Action*>(action)->updateIndexHeap(i);
670 void Action::initialize(simgrid::surf::Model *model, double cost, bool failed,
674 m_start = surf_get_clock();
679 p_stateSet = getModel()->getFailedActionSet();
681 p_stateSet = getModel()->getRunningActionSet();
683 p_stateSet->push_back(*this);
686 Action::Action(simgrid::surf::Model *model, double cost, bool failed)
688 initialize(model, cost, failed);
691 Action::Action(simgrid::surf::Model *model, double cost, bool failed, lmm_variable_t var)
693 initialize(model, cost, failed, var);
697 xbt_free(p_category);
700 void Action::finish() {
701 m_finish = surf_get_clock();
704 e_surf_action_state_t Action::getState()
706 if (p_stateSet == getModel()->getReadyActionSet())
707 return SURF_ACTION_READY;
708 if (p_stateSet == getModel()->getRunningActionSet())
709 return SURF_ACTION_RUNNING;
710 if (p_stateSet == getModel()->getFailedActionSet())
711 return SURF_ACTION_FAILED;
712 if (p_stateSet == getModel()->getDoneActionSet())
713 return SURF_ACTION_DONE;
714 return SURF_ACTION_NOT_IN_THE_SYSTEM;
717 void Action::setState(e_surf_action_state_t state)
719 //surf_action_state_t action_state = &(action->model_type->states);
720 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
721 p_stateSet->erase(p_stateSet->iterator_to(*this));
722 if (state == SURF_ACTION_READY)
723 p_stateSet = getModel()->getReadyActionSet();
724 else if (state == SURF_ACTION_RUNNING)
725 p_stateSet = getModel()->getRunningActionSet();
726 else if (state == SURF_ACTION_FAILED)
727 p_stateSet = getModel()->getFailedActionSet();
728 else if (state == SURF_ACTION_DONE)
729 p_stateSet = getModel()->getDoneActionSet();
734 p_stateSet->push_back(*this);
738 double Action::getBound()
740 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
743 void Action::setBound(double bound)
745 XBT_IN("(%p,%g)", this, bound);
747 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
749 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
750 heapRemove(getModel()->getActionHeap());
754 double Action::getStartTime()
759 double Action::getFinishTime()
761 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
762 return m_remains == 0 ? m_finish : -1;
765 void Action::setData(void* data)
770 void Action::setCategory(const char *category)
772 XBT_IN("(%p,%s)", this, category);
773 p_category = xbt_strdup(category);
781 void Action::setMaxDuration(double duration)
783 XBT_IN("(%p,%g)", this, duration);
784 m_maxDuration = duration;
785 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
786 heapRemove(getModel()->getActionHeap());
790 void Action::gapRemove() {}
792 void Action::setPriority(double priority)
794 XBT_IN("(%p,%g)", this, priority);
795 m_priority = priority;
796 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
798 if (getModel()->getUpdateMechanism() == UM_LAZY)
799 heapRemove(getModel()->getActionHeap());
803 void Action::cancel(){
804 setState(SURF_ACTION_FAILED);
805 if (getModel()->getUpdateMechanism() == UM_LAZY) {
806 if (action_lmm_hook.is_linked())
807 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
808 heapRemove(getModel()->getActionHeap());
815 if (action_hook.is_linked())
816 p_stateSet->erase(p_stateSet->iterator_to(*this));
818 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
819 if (getModel()->getUpdateMechanism() == UM_LAZY) {
820 /* remove from heap */
821 heapRemove(getModel()->getActionHeap());
822 if (action_lmm_hook.is_linked())
823 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
831 void Action::suspend()
833 XBT_IN("(%p)", this);
834 if (m_suspended != 2) {
835 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
837 if (getModel()->getUpdateMechanism() == UM_LAZY)
838 heapRemove(getModel()->getActionHeap());
843 void Action::resume()
845 XBT_IN("(%p)", this);
846 if (m_suspended != 2) {
847 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
849 if (getModel()->getUpdateMechanism() == UM_LAZY)
850 heapRemove(getModel()->getActionHeap());
855 bool Action::isSuspended()
857 return m_suspended == 1;
859 /* insert action on heap using a given key and a hat (heap_action_type)
860 * a hat can be of three types for communications:
862 * NORMAL = this is a normal heap entry stating the date to finish transmitting
863 * LATENCY = this is a heap entry to warn us when the latency is payed
864 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
866 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
869 xbt_heap_push(heap, this, key);
872 void Action::heapRemove(xbt_heap_t heap)
875 if (m_indexHeap >= 0) {
876 xbt_heap_remove(heap, m_indexHeap);
880 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
883 if (m_indexHeap >= 0) {
884 xbt_heap_update(heap, m_indexHeap, key);
886 xbt_heap_push(heap, this, key);
890 void Action::updateIndexHeap(int i) {
894 double Action::getRemains()
896 XBT_IN("(%p)", this);
897 /* update remains before return it */
898 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
899 updateRemainingLazy(surf_get_clock());
904 double Action::getRemainsNoUpdate()
909 //FIXME split code in the right places
910 void Action::updateRemainingLazy(double now)
914 if(getModel() == surf_network_model)
916 if (m_suspended != 0)
921 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
922 "You're updating an action that is not running.");
924 /* bogus priority, skip it */
925 xbt_assert(m_priority > 0,
926 "You're updating an action that seems suspended.");
929 delta = now - m_lastUpdate;
932 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
933 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
935 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
936 simgrid::surf::Resource *cpu = static_cast<simgrid::surf::Resource*>(
937 lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
938 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
940 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
943 if(getModel() == surf_network_model)
945 if (m_maxDuration != NO_MAX_DURATION)
946 double_update(&m_maxDuration, delta, sg_surf_precision);
948 //FIXME: duplicated code
949 if ((m_remains <= 0) &&
950 (lmm_get_variable_weight(getVariable()) > 0)) {
952 setState(SURF_ACTION_DONE);
953 heapRemove(getModel()->getActionHeap());
954 } else if (((m_maxDuration != NO_MAX_DURATION)
955 && (m_maxDuration <= 0))) {
957 setState(SURF_ACTION_DONE);
958 heapRemove(getModel()->getActionHeap());
963 m_lastValue = lmm_variable_getvalue(getVariable());