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; /* for invoking callbacks */
32 tmgr_history_t history = NULL;
33 lmm_system_t maxmin_system = NULL;
34 xbt_dynar_t surf_path = NULL;
35 xbt_dynar_t host_that_restart = NULL;
36 xbt_dict_t watched_hosts_lib;
41 simgrid::surf::signal<void(void)> surfExitCallbacks;
46 #include <simgrid/plugins/energy.h> // FIXME: this plugin should not be linked to the core
48 s_surf_model_description_t surf_plugin_description[] = {
49 {"Energy", "Cpu energy consumption.", sg_energy_plugin_init},
50 {NULL, NULL, NULL} /* this array must be NULL terminated */
53 /* Don't forget to update the option description in smx_config when you change
55 s_surf_model_description_t surf_network_model_description[] = {
57 "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). ",
58 surf_network_model_init_LegrandVelho},
60 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
61 surf_network_model_init_Constant},
63 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
64 surf_network_model_init_SMPI},
66 "Realistic network model specifically tailored for HPC settings, with Infiniband contention model",
67 surf_network_model_init_IB},
69 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
70 surf_network_model_init_CM02},
73 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
74 surf_network_model_init_NS3},
77 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
78 surf_network_model_init_Reno},
80 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
81 surf_network_model_init_Reno2},
83 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
84 surf_network_model_init_Vegas},
85 {NULL, NULL, NULL} /* this array must be NULL terminated */
88 s_surf_model_description_t surf_cpu_model_description[] = {
90 "Simplistic CPU model (time=size/power).",
91 surf_cpu_model_init_Cas01},
92 {NULL, NULL, NULL} /* this array must be NULL terminated */
95 s_surf_model_description_t surf_host_model_description[] = {
97 "Default host model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
98 surf_host_model_init_current_default},
100 "Host model that is automatically chosen if you change the network and CPU models",
101 surf_host_model_init_compound},
102 {"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks",
103 surf_host_model_init_ptask_L07},
104 {NULL, NULL, NULL} /* this array must be NULL terminated */
107 s_surf_model_description_t surf_vm_model_description[] = {
110 surf_vm_model_init_HL13},
111 {NULL, NULL, NULL} /* this array must be NULL terminated */
114 s_surf_model_description_t surf_optimization_mode_description[] = {
116 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
119 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
122 "Full update of remaining and variables. Slow but may be useful when debugging.",
124 {NULL, NULL, NULL} /* this array must be NULL terminated */
127 s_surf_model_description_t surf_storage_model_description[] = {
129 "Simplistic storage model.",
130 surf_storage_model_init_default},
131 {NULL, NULL, NULL} /* this array must be NULL terminated */
134 #ifdef CONTEXT_THREADS
135 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
140 double surf_get_clock(void)
146 # define FILE_DELIM "\\"
148 # define FILE_DELIM "/" /* FIXME: move to better location */
151 FILE *surf_fopen(const char *name, const char *mode)
154 char *path_elm = NULL;
160 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
161 return fopen(name, mode);
163 /* search relative files in the path */
164 xbt_dynar_foreach(surf_path, cpt, path_elm) {
165 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
166 file = fopen(buff, mode);
178 static const char *disk_drives_letter_table[MAX_DRIVE] = {
179 "A:\\","B:\\","C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\",
180 "N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"
185 * Returns the initial path. On Windows the initial path is
186 * the current directory for the current process in the other
187 * case the function returns "./" that represents the current
188 * directory on Unix/Linux platforms.
191 const char *__surf_get_initial_path(void)
196 char current_directory[MAX_PATH + 1] = { 0 };
197 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
198 char root[4] = { 0 };
203 strncpy(root, current_directory, 3);
205 for (i = 0; i < MAX_DRIVE; i++) {
206 if (toupper(root[0]) == disk_drives_letter_table[i][0])
207 return disk_drives_letter_table[i];
216 /* The __surf_is_absolute_file_path() returns 1 if
217 * file_path is a absolute file path, in the other
218 * case the function returns 0.
220 int __surf_is_absolute_file_path(const char *file_path)
223 WIN32_FIND_DATA wfd = { 0 };
224 HANDLE hFile = FindFirstFile(file_path, &wfd);
226 if (INVALID_HANDLE_VALUE == hFile)
232 return (file_path[0] == '/');
236 /** Displays the long description of all registered models, and quit */
237 void model_help(const char *category, s_surf_model_description_t * table)
240 printf("Long description of the %s models accepted by this simulator:\n",
242 for (i = 0; table[i].name; i++)
243 printf(" %s: %s\n", table[i].name, table[i].description);
246 int find_model_description(s_surf_model_description_t * table,
250 char *name_list = NULL;
252 for (i = 0; table[i].name; i++)
253 if (!strcmp(name, table[i].name)) {
257 xbt_die("No model is valid! This is a bug.");
258 name_list = xbt_strdup(table[0].name);
259 for (i = 1; table[i].name; i++) {
260 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
261 strcat(name_list, ", ");
262 strcat(name_list, table[i].name);
264 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
268 static XBT_INLINE void routing_asr_prop_free(void *p)
270 //xbt_dict_t elm = (xbt_dict_t) p;
271 //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster
274 static XBT_INLINE void surf_storage_free(void *r)
276 delete static_cast<simgrid::surf::Storage*>(r);
279 void sg_version_check(int lib_version_major,int lib_version_minor,int lib_version_patch) {
280 if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) {
282 "FATAL ERROR: Your program was compiled with SimGrid version %d.%d.%d, "
283 "and then linked against SimGrid %d.%d.%d. Please fix this.\n",
284 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
285 lib_version_major,lib_version_minor,lib_version_patch);
288 if (lib_version_patch != SIMGRID_VERSION_PATCH) {
290 "Warning: Your program was compiled with SimGrid version %d.%d.%d, "
291 "and then linked against SimGrid %d.%d.%d. Proceeding anyway.\n",
292 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
293 lib_version_major,lib_version_minor,lib_version_patch);
297 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
298 *ver_major = SIMGRID_VERSION_MAJOR;
299 *ver_minor = SIMGRID_VERSION_MINOR;
300 *ver_patch = SIMGRID_VERSION_PATCH;
303 void surf_init(int *argc, char **argv)
305 XBT_DEBUG("Create all Libs");
306 host_list = xbt_dict_new_homogeneous([](void*p) {
307 delete static_cast<simgrid::Host*>(p);
309 as_router_lib = xbt_lib_new();
310 storage_lib = xbt_lib_new();
311 storage_type_lib = xbt_lib_new();
312 file_lib = xbt_lib_new();
313 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
317 XBT_DEBUG("Add routing levels");
318 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
320 XBT_DEBUG("Add SURF levels");
321 simgrid::surf::Host::classInit();
322 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
324 xbt_init(argc, argv);
325 if (!all_existing_models)
326 all_existing_models = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
327 if (!model_list_invoke)
328 model_list_invoke = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
330 history = tmgr_history_new();
332 TRACE_add_start_function(TRACE_surf_alloc);
333 TRACE_add_end_function(TRACE_surf_release);
335 sg_config_init(argc, argv);
344 simgrid::surf::Model *model = NULL;
346 TRACE_end(); /* Just in case it was not called by the upper
347 * layer (or there is no upper layer) */
349 sg_config_finalize();
351 xbt_dynar_free(&host_that_restart);
352 xbt_dynar_free(&surf_path);
354 xbt_dict_free(&host_list);
355 xbt_lib_free(&as_router_lib);
356 xbt_lib_free(&storage_lib);
358 xbt_lib_free(&storage_type_lib);
359 xbt_lib_free(&file_lib);
360 xbt_dict_free(&watched_hosts_lib);
362 xbt_dynar_foreach(all_existing_models, iter, model)
364 xbt_dynar_free(&all_existing_models);
365 xbt_dynar_free(&model_list_invoke);
368 simgrid::surf::surfExitCallbacks();
371 lmm_system_free(maxmin_system);
372 maxmin_system = NULL;
375 tmgr_history_free(history);
379 #ifdef CONTEXT_THREADS
380 xbt_parmap_destroy(surf_parmap);
384 surf_parse_lex_destroy();
385 surf_parse_free_callbacks();
387 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
398 : p_maxminSystem(NULL)
400 p_readyActionSet = new ActionList();
401 p_runningActionSet = new ActionList();
402 p_failedActionSet = new ActionList();
403 p_doneActionSet = new ActionList();
405 p_modifiedSet = NULL;
407 p_updateMechanism = UM_UNDEFINED;
408 m_selectiveUpdate = 0;
412 delete p_readyActionSet;
413 delete p_runningActionSet;
414 delete p_failedActionSet;
415 delete p_doneActionSet;
418 double Model::shareResources(double now)
420 //FIXME: set the good function once and for all
421 if (p_updateMechanism == UM_LAZY)
422 return shareResourcesLazy(now);
423 else if (p_updateMechanism == UM_FULL)
424 return shareResourcesFull(now);
426 xbt_die("Invalid cpu update mechanism!");
429 double Model::shareResourcesLazy(double now)
431 Action *action = NULL;
436 ("Before share resources, the size of modified actions set is %zd",
437 p_modifiedSet->size());
439 lmm_solve(p_maxminSystem);
442 ("After share resources, The size of modified actions set is %zd",
443 p_modifiedSet->size());
445 while(!p_modifiedSet->empty()) {
446 action = &(p_modifiedSet->front());
447 p_modifiedSet->pop_front();
448 int max_dur_flag = 0;
450 if (action->getStateSet() != p_runningActionSet)
453 /* bogus priority, skip it */
454 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
457 action->updateRemainingLazy(now);
460 share = lmm_variable_getvalue(action->getVariable());
463 double time_to_completion;
464 if (action->getRemains() > 0) {
465 time_to_completion = action->getRemainsNoUpdate() / share;
467 time_to_completion = 0.0;
469 min = now + time_to_completion; // when the task will complete if nothing changes
472 if ((action->getMaxDuration() != NO_MAX_DURATION)
474 || action->getStartTime() +
475 action->getMaxDuration() < min)) {
476 min = action->getStartTime() +
477 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
482 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
484 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
485 action->getStartTime(), min, share,
486 action->getMaxDuration());
489 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
490 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
492 } else DIE_IMPOSSIBLE;
495 //hereafter must have already the min value for this resource model
496 if (xbt_heap_size(p_actionHeap) > 0)
497 min = xbt_heap_maxkey(p_actionHeap) - now;
501 XBT_DEBUG("The minimum with the HEAP %f", min);
506 double Model::shareResourcesFull(double /*now*/) {
510 double Model::shareResourcesMaxMin(ActionList *running_actions,
512 void (*solve) (lmm_system_t))
514 Action *action = NULL;
520 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
521 for(; it != itend ; ++it) {
523 value = lmm_variable_getvalue(action->getVariable());
524 if ((value > 0) || (action->getMaxDuration() >= 0))
532 if (action->getRemains() > 0)
533 min = action->getRemainsNoUpdate() / value;
536 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
537 min = action->getMaxDuration();
539 min = action->getMaxDuration();
542 for (++it; it != itend; ++it) {
544 value = lmm_variable_getvalue(action->getVariable());
546 if (action->getRemains() > 0)
547 value = action->getRemainsNoUpdate() / value;
552 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
555 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
556 min = action->getMaxDuration();
557 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
560 XBT_DEBUG("min value : %f", min);
565 void Model::updateActionsState(double now, double delta)
567 if (p_updateMechanism == UM_FULL)
568 updateActionsStateFull(now, delta);
569 else if (p_updateMechanism == UM_LAZY)
570 updateActionsStateLazy(now, delta);
572 xbt_die("Invalid cpu update mechanism!");
575 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
580 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
595 Resource::Resource(Model *model, const char *name)
596 : Resource(model, name, 1/*ON*/)
599 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint)
600 : Resource(model, name, constraint, 1/*ON*/)
603 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint, int initiallyOn)
604 : p_name(xbt_strdup(name))
606 , m_isOn(initiallyOn)
607 , p_constraint(constraint)
610 Resource::Resource(Model *model, const char *name, int initiallyOn)
611 : p_name(xbt_strdup(name))
613 , m_isOn(initiallyOn)
617 Resource::~Resource() {
618 xbt_free((void*)p_name);
621 bool Resource::isOn() {
624 bool Resource::isOff() {
628 void Resource::turnOn()
635 void Resource::turnOff()
642 Model *Resource::getModel() {
646 const char *Resource::getName() {
650 lmm_constraint_t Resource::getConstraint() {
661 const char *surf_action_state_names[6] = {
663 "SURF_ACTION_RUNNING",
664 "SURF_ACTION_FAILED",
666 "SURF_ACTION_TO_FREE",
667 "SURF_ACTION_NOT_IN_THE_SYSTEM"
670 /* added to manage the communication action's heap */
671 void surf_action_lmm_update_index_heap(void *action, int i) {
672 static_cast<simgrid::surf::Action*>(action)->updateIndexHeap(i);
678 void Action::initialize(simgrid::surf::Model *model, double cost, bool failed,
682 m_start = surf_get_clock();
687 p_stateSet = getModel()->getFailedActionSet();
689 p_stateSet = getModel()->getRunningActionSet();
691 p_stateSet->push_back(*this);
694 Action::Action(simgrid::surf::Model *model, double cost, bool failed)
696 initialize(model, cost, failed);
699 Action::Action(simgrid::surf::Model *model, double cost, bool failed, lmm_variable_t var)
701 initialize(model, cost, failed, var);
705 xbt_free(p_category);
708 void Action::finish() {
709 m_finish = surf_get_clock();
712 e_surf_action_state_t Action::getState()
714 if (p_stateSet == getModel()->getReadyActionSet())
715 return SURF_ACTION_READY;
716 if (p_stateSet == getModel()->getRunningActionSet())
717 return SURF_ACTION_RUNNING;
718 if (p_stateSet == getModel()->getFailedActionSet())
719 return SURF_ACTION_FAILED;
720 if (p_stateSet == getModel()->getDoneActionSet())
721 return SURF_ACTION_DONE;
722 return SURF_ACTION_NOT_IN_THE_SYSTEM;
725 void Action::setState(e_surf_action_state_t state)
727 //surf_action_state_t action_state = &(action->model_type->states);
728 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
729 p_stateSet->erase(p_stateSet->iterator_to(*this));
730 if (state == SURF_ACTION_READY)
731 p_stateSet = getModel()->getReadyActionSet();
732 else if (state == SURF_ACTION_RUNNING)
733 p_stateSet = getModel()->getRunningActionSet();
734 else if (state == SURF_ACTION_FAILED)
735 p_stateSet = getModel()->getFailedActionSet();
736 else if (state == SURF_ACTION_DONE)
737 p_stateSet = getModel()->getDoneActionSet();
742 p_stateSet->push_back(*this);
746 double Action::getBound()
748 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
751 void Action::setBound(double bound)
753 XBT_IN("(%p,%g)", this, bound);
755 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
757 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
758 heapRemove(getModel()->getActionHeap());
762 double Action::getStartTime()
767 double Action::getFinishTime()
769 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
770 return m_remains == 0 ? m_finish : -1;
773 void Action::setData(void* data)
778 void Action::setCategory(const char *category)
780 XBT_IN("(%p,%s)", this, category);
781 p_category = xbt_strdup(category);
789 void Action::setMaxDuration(double duration)
791 XBT_IN("(%p,%g)", this, duration);
792 m_maxDuration = duration;
793 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
794 heapRemove(getModel()->getActionHeap());
798 void Action::gapRemove() {}
800 void Action::setPriority(double priority)
802 XBT_IN("(%p,%g)", this, priority);
803 m_priority = priority;
804 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
806 if (getModel()->getUpdateMechanism() == UM_LAZY)
807 heapRemove(getModel()->getActionHeap());
811 void Action::cancel(){
812 setState(SURF_ACTION_FAILED);
813 if (getModel()->getUpdateMechanism() == UM_LAZY) {
814 if (action_lmm_hook.is_linked())
815 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
816 heapRemove(getModel()->getActionHeap());
823 if (action_hook.is_linked())
824 p_stateSet->erase(p_stateSet->iterator_to(*this));
826 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
827 if (getModel()->getUpdateMechanism() == UM_LAZY) {
828 /* remove from heap */
829 heapRemove(getModel()->getActionHeap());
830 if (action_lmm_hook.is_linked())
831 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
839 void Action::suspend()
841 XBT_IN("(%p)", this);
842 if (m_suspended != 2) {
843 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
845 if (getModel()->getUpdateMechanism() == UM_LAZY)
846 heapRemove(getModel()->getActionHeap());
851 void Action::resume()
853 XBT_IN("(%p)", this);
854 if (m_suspended != 2) {
855 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
857 if (getModel()->getUpdateMechanism() == UM_LAZY)
858 heapRemove(getModel()->getActionHeap());
863 bool Action::isSuspended()
865 return m_suspended == 1;
867 /* insert action on heap using a given key and a hat (heap_action_type)
868 * a hat can be of three types for communications:
870 * NORMAL = this is a normal heap entry stating the date to finish transmitting
871 * LATENCY = this is a heap entry to warn us when the latency is payed
872 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
874 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
877 xbt_heap_push(heap, this, key);
880 void Action::heapRemove(xbt_heap_t heap)
883 if (m_indexHeap >= 0) {
884 xbt_heap_remove(heap, m_indexHeap);
888 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
891 if (m_indexHeap >= 0) {
892 xbt_heap_update(heap, m_indexHeap, key);
894 xbt_heap_push(heap, this, key);
898 void Action::updateIndexHeap(int i) {
902 double Action::getRemains()
904 XBT_IN("(%p)", this);
905 /* update remains before return it */
906 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
907 updateRemainingLazy(surf_get_clock());
912 double Action::getRemainsNoUpdate()
917 //FIXME split code in the right places
918 void Action::updateRemainingLazy(double now)
922 if(getModel() == surf_network_model)
924 if (m_suspended != 0)
929 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
930 "You're updating an action that is not running.");
932 /* bogus priority, skip it */
933 xbt_assert(m_priority > 0,
934 "You're updating an action that seems suspended.");
937 delta = now - m_lastUpdate;
940 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
941 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
943 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
944 simgrid::surf::Resource *cpu = static_cast<simgrid::surf::Resource*>(
945 lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
946 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
948 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
951 if(getModel() == surf_network_model)
953 if (m_maxDuration != NO_MAX_DURATION)
954 double_update(&m_maxDuration, delta, sg_surf_precision);
956 //FIXME: duplicated code
957 if ((m_remains <= 0) &&
958 (lmm_get_variable_weight(getVariable()) > 0)) {
960 setState(SURF_ACTION_DONE);
961 heapRemove(getModel()->getActionHeap());
962 } else if (((m_maxDuration != NO_MAX_DURATION)
963 && (m_maxDuration <= 0))) {
965 setState(SURF_ACTION_DONE);
966 heapRemove(getModel()->getActionHeap());
971 m_lastValue = lmm_variable_getvalue(getVariable());