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;
38 surf_callback(void, void) surfExitCallbacks;
40 s_surf_model_description_t surf_plugin_description[] = {
41 {"Energy", "Cpu energy consumption.", sg_energy_plugin_init},
42 {NULL, NULL, NULL} /* this array must be NULL terminated */
45 /* Don't forget to update the option description in smx_config when you change
47 s_surf_model_description_t surf_network_model_description[] = {
49 "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). ",
50 surf_network_model_init_LegrandVelho},
52 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
53 surf_network_model_init_Constant},
55 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
56 surf_network_model_init_SMPI},
58 "Realistic network model specifically tailored for HPC settings, with Infiniband contention model",
59 surf_network_model_init_IB},
61 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
62 surf_network_model_init_CM02},
65 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
66 surf_network_model_init_NS3},
69 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
70 surf_network_model_init_Reno},
72 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
73 surf_network_model_init_Reno2},
75 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
76 surf_network_model_init_Vegas},
77 {NULL, NULL, NULL} /* this array must be NULL terminated */
80 s_surf_model_description_t surf_cpu_model_description[] = {
82 "Simplistic CPU model (time=size/power).",
83 surf_cpu_model_init_Cas01},
84 {NULL, NULL, NULL} /* this array must be NULL terminated */
87 s_surf_model_description_t surf_host_model_description[] = {
89 "Default host model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
90 surf_host_model_init_current_default},
92 "Host model that is automatically chosen if you change the network and CPU models",
93 surf_host_model_init_compound},
94 {"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks",
95 surf_host_model_init_ptask_L07},
96 {NULL, NULL, NULL} /* this array must be NULL terminated */
99 s_surf_model_description_t surf_vm_model_description[] = {
102 surf_vm_model_init_HL13},
103 {NULL, NULL, NULL} /* this array must be NULL terminated */
106 s_surf_model_description_t surf_optimization_mode_description[] = {
108 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
111 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
114 "Full update of remaining and variables. Slow but may be useful when debugging.",
116 {NULL, NULL, NULL} /* this array must be NULL terminated */
119 s_surf_model_description_t surf_storage_model_description[] = {
121 "Simplistic storage model.",
122 surf_storage_model_init_default},
123 {NULL, NULL, NULL} /* this array must be NULL terminated */
126 #ifdef CONTEXT_THREADS
127 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
132 double surf_get_clock(void)
138 # define FILE_DELIM "\\"
140 # define FILE_DELIM "/" /* FIXME: move to better location */
143 FILE *surf_fopen(const char *name, const char *mode)
146 char *path_elm = NULL;
152 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
153 return fopen(name, mode);
155 /* search relative files in the path */
156 xbt_dynar_foreach(surf_path, cpt, path_elm) {
157 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
158 file = fopen(buff, mode);
170 static const char *disk_drives_letter_table[MAX_DRIVE] = {
171 "A:\\","B:\\","C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\",
172 "N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"
177 * Returns the initial path. On Windows the initial path is
178 * the current directory for the current process in the other
179 * case the function returns "./" that represents the current
180 * directory on Unix/Linux platforms.
183 const char *__surf_get_initial_path(void)
188 char current_directory[MAX_PATH + 1] = { 0 };
189 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
190 char root[4] = { 0 };
195 strncpy(root, current_directory, 3);
197 for (i = 0; i < MAX_DRIVE; i++) {
198 if (toupper(root[0]) == disk_drives_letter_table[i][0])
199 return disk_drives_letter_table[i];
208 /* The __surf_is_absolute_file_path() returns 1 if
209 * file_path is a absolute file path, in the other
210 * case the function returns 0.
212 int __surf_is_absolute_file_path(const char *file_path)
215 WIN32_FIND_DATA wfd = { 0 };
216 HANDLE hFile = FindFirstFile(file_path, &wfd);
218 if (INVALID_HANDLE_VALUE == hFile)
224 return (file_path[0] == '/');
228 /** Displays the long description of all registered models, and quit */
229 void model_help(const char *category, s_surf_model_description_t * table)
232 printf("Long description of the %s models accepted by this simulator:\n",
234 for (i = 0; table[i].name; i++)
235 printf(" %s: %s\n", table[i].name, table[i].description);
238 int find_model_description(s_surf_model_description_t * table,
242 char *name_list = NULL;
244 for (i = 0; table[i].name; i++)
245 if (!strcmp(name, table[i].name)) {
249 xbt_die("No model is valid! This is a bug.");
250 name_list = xbt_strdup(table[0].name);
251 for (i = 1; table[i].name; i++) {
252 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
253 strcat(name_list, ", ");
254 strcat(name_list, table[i].name);
256 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
260 static XBT_INLINE void routing_asr_prop_free(void *p)
262 //xbt_dict_t elm = (xbt_dict_t) p;
263 //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster
266 static XBT_INLINE void surf_host_free(void *r)
268 delete static_cast<Host*>(r);
271 static XBT_INLINE void surf_storage_free(void *r)
273 delete static_cast<Storage*>(r);
276 void sg_version_check(int lib_version_major,int lib_version_minor,int lib_version_patch) {
277 if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) {
279 "FATAL ERROR: Your program was compiled with SimGrid version %d.%d.%d, "
280 "and then linked against SimGrid %d.%d.%d. Please fix this.\n",
281 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
282 lib_version_major,lib_version_minor,lib_version_patch);
285 if (lib_version_patch != SIMGRID_VERSION_PATCH) {
287 "Warning: Your program was compiled with SimGrid version %d.%d.%d, "
288 "and then linked against SimGrid %d.%d.%d. Proceeding anyway.\n",
289 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
290 lib_version_major,lib_version_minor,lib_version_patch);
294 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
295 *ver_major = SIMGRID_VERSION_MAJOR;
296 *ver_minor = SIMGRID_VERSION_MINOR;
297 *ver_patch = SIMGRID_VERSION_PATCH;
300 void surf_init(int *argc, char **argv)
302 XBT_DEBUG("Create all Libs");
303 host_lib = xbt_lib_new();
304 as_router_lib = xbt_lib_new();
305 storage_lib = xbt_lib_new();
306 storage_type_lib = xbt_lib_new();
307 file_lib = xbt_lib_new();
308 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
312 XBT_DEBUG("Add routing levels");
313 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
315 XBT_DEBUG("Add SURF levels");
316 SURF_HOST_LEVEL = xbt_lib_add_level(host_lib,surf_host_free);
317 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
319 xbt_init(argc, argv);
320 if (!all_existing_models)
321 all_existing_models = xbt_dynar_new(sizeof(Model*), NULL);
322 if (!model_list_invoke)
323 model_list_invoke = xbt_dynar_new(sizeof(Model*), NULL);
325 history = tmgr_history_new();
327 TRACE_add_start_function(TRACE_surf_alloc);
328 TRACE_add_end_function(TRACE_surf_release);
330 sg_config_init(argc, argv);
341 TRACE_end(); /* Just in case it was not called by the upper
342 * layer (or there is no upper layer) */
344 sg_config_finalize();
346 xbt_dynar_free(&host_that_restart);
347 xbt_dynar_free(&surf_path);
349 xbt_lib_free(&host_lib);
350 xbt_lib_free(&as_router_lib);
351 xbt_lib_free(&storage_lib);
353 xbt_lib_free(&storage_type_lib);
354 xbt_lib_free(&file_lib);
355 xbt_dict_free(&watched_hosts_lib);
357 xbt_dynar_foreach(all_existing_models, iter, model)
359 xbt_dynar_free(&all_existing_models);
360 xbt_dynar_free(&model_list_invoke);
363 surf_callback_emit(surfExitCallbacks);
366 lmm_system_free(maxmin_system);
367 maxmin_system = NULL;
370 tmgr_history_free(history);
374 #ifdef CONTEXT_THREADS
375 xbt_parmap_destroy(surf_parmap);
379 surf_parse_lex_destroy();
380 surf_parse_free_callbacks();
382 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::shareResources(double now)
412 //FIXME: set the good function once and for all
413 if (p_updateMechanism == UM_LAZY)
414 return shareResourcesLazy(now);
415 else if (p_updateMechanism == UM_FULL)
416 return shareResourcesFull(now);
418 xbt_die("Invalid cpu update mechanism!");
421 double Model::shareResourcesLazy(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::shareResourcesFull(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*/)
582 : p_name(NULL), p_properties(NULL), p_model(NULL)
585 Resource::Resource(Model *model, const char *name, xbt_dict_t props)
586 : Resource(model, name, props, SURF_RESOURCE_ON)
589 Resource::Resource(Model *model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
590 : Resource(model, name, props, constraint, SURF_RESOURCE_ON)
594 Model *model, const char *name, xbt_dict_t props,
595 lmm_constraint_t constraint, e_surf_resource_state_t stateInit)
596 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
597 , m_running(true), m_stateCurrent(stateInit), p_constraint(constraint)
600 Resource::Resource(Model *model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
601 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
602 , m_running(true), m_stateCurrent(stateInit)
605 Resource::~Resource() {
606 xbt_free((void*)p_name);
607 xbt_dict_free(&p_properties);
610 e_surf_resource_state_t Resource::getState()
612 return m_stateCurrent;
615 void Resource::setState(e_surf_resource_state_t state)
617 m_stateCurrent = state;
620 bool Resource::isOn()
625 void Resource::turnOn()
632 void Resource::turnOff()
639 Model *Resource::getModel() {
643 const char *Resource::getName() {
647 xbt_dict_t Resource::getProperties() {
648 if (p_properties==NULL)
649 p_properties = xbt_dict_new();
653 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 void Action::initialize(Model *model, double cost, bool failed,
676 m_maxDuration = NO_MAX_DURATION;
678 m_start = surf_get_clock();
688 p_stateHookup.prev = 0;
689 p_stateHookup.next = 0;
691 p_stateSet = getModel()->getFailedActionSet();
693 p_stateSet = getModel()->getRunningActionSet();
695 p_stateSet->push_back(*this);
698 Action::Action(Model *model, double cost, bool failed)
700 initialize(model, cost, failed);
703 Action::Action(Model *model, double cost, bool failed, lmm_variable_t var)
705 initialize(model, cost, failed, var);
709 xbt_free(p_category);
712 void Action::finish() {
713 m_finish = surf_get_clock();
716 e_surf_action_state_t Action::getState()
718 if (p_stateSet == getModel()->getReadyActionSet())
719 return SURF_ACTION_READY;
720 if (p_stateSet == getModel()->getRunningActionSet())
721 return SURF_ACTION_RUNNING;
722 if (p_stateSet == getModel()->getFailedActionSet())
723 return SURF_ACTION_FAILED;
724 if (p_stateSet == getModel()->getDoneActionSet())
725 return SURF_ACTION_DONE;
726 return SURF_ACTION_NOT_IN_THE_SYSTEM;
729 void Action::setState(e_surf_action_state_t state)
731 //surf_action_state_t action_state = &(action->model_type->states);
732 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
733 p_stateSet->erase(p_stateSet->iterator_to(*this));
734 if (state == SURF_ACTION_READY)
735 p_stateSet = getModel()->getReadyActionSet();
736 else if (state == SURF_ACTION_RUNNING)
737 p_stateSet = getModel()->getRunningActionSet();
738 else if (state == SURF_ACTION_FAILED)
739 p_stateSet = getModel()->getFailedActionSet();
740 else if (state == SURF_ACTION_DONE)
741 p_stateSet = getModel()->getDoneActionSet();
746 p_stateSet->push_back(*this);
750 double Action::getBound()
752 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
755 void Action::setBound(double bound)
757 XBT_IN("(%p,%g)", this, bound);
759 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
761 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
762 heapRemove(getModel()->getActionHeap());
766 double Action::getStartTime()
771 double Action::getFinishTime()
773 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
774 return m_remains == 0 ? m_finish : -1;
777 void Action::setData(void* data)
782 void Action::setCategory(const char *category)
784 XBT_IN("(%p,%s)", this, category);
785 p_category = xbt_strdup(category);
793 void Action::setMaxDuration(double duration)
795 XBT_IN("(%p,%g)", this, duration);
796 m_maxDuration = duration;
797 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
798 heapRemove(getModel()->getActionHeap());
802 void Action::gapRemove() {}
804 void Action::setPriority(double priority)
806 XBT_IN("(%p,%g)", this, priority);
807 m_priority = priority;
808 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
810 if (getModel()->getUpdateMechanism() == UM_LAZY)
811 heapRemove(getModel()->getActionHeap());
815 void Action::cancel(){
816 setState(SURF_ACTION_FAILED);
817 if (getModel()->getUpdateMechanism() == UM_LAZY) {
818 if (action_lmm_hook.is_linked())
819 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
820 heapRemove(getModel()->getActionHeap());
827 if (action_hook.is_linked())
828 p_stateSet->erase(p_stateSet->iterator_to(*this));
830 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
831 if (getModel()->getUpdateMechanism() == UM_LAZY) {
832 /* remove from heap */
833 heapRemove(getModel()->getActionHeap());
834 if (action_lmm_hook.is_linked())
835 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
843 void Action::suspend()
845 XBT_IN("(%p)", this);
846 if (m_suspended != 2) {
847 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
849 if (getModel()->getUpdateMechanism() == UM_LAZY)
850 heapRemove(getModel()->getActionHeap());
855 void Action::resume()
857 XBT_IN("(%p)", this);
858 if (m_suspended != 2) {
859 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
861 if (getModel()->getUpdateMechanism() == UM_LAZY)
862 heapRemove(getModel()->getActionHeap());
867 bool Action::isSuspended()
869 return m_suspended == 1;
871 /* insert action on heap using a given key and a hat (heap_action_type)
872 * a hat can be of three types for communications:
874 * NORMAL = this is a normal heap entry stating the date to finish transmitting
875 * LATENCY = this is a heap entry to warn us when the latency is payed
876 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
878 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
881 xbt_heap_push(heap, this, key);
884 void Action::heapRemove(xbt_heap_t heap)
887 if (m_indexHeap >= 0) {
888 xbt_heap_remove(heap, m_indexHeap);
892 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
895 if (m_indexHeap >= 0) {
896 xbt_heap_update(heap, m_indexHeap, key);
898 xbt_heap_push(heap, this, key);
902 /* added to manage the communication action's heap */
903 void surf_action_lmm_update_index_heap(void *action, int i) {
904 static_cast<Action*>(action)->updateIndexHeap(i);
907 void Action::updateIndexHeap(int i) {
911 double Action::getRemains()
913 XBT_IN("(%p)", this);
914 /* update remains before return it */
915 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
916 updateRemainingLazy(surf_get_clock());
921 double Action::getRemainsNoUpdate()
926 //FIXME split code in the right places
927 void Action::updateRemainingLazy(double now)
931 if(getModel() == surf_network_model)
933 if (m_suspended != 0)
938 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
939 "You're updating an action that is not running.");
941 /* bogus priority, skip it */
942 xbt_assert(m_priority > 0,
943 "You're updating an action that seems suspended.");
946 delta = now - m_lastUpdate;
949 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
950 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
952 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
953 Resource *cpu = static_cast<Resource*>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
954 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
956 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
959 if(getModel() == surf_network_model)
961 if (m_maxDuration != NO_MAX_DURATION)
962 double_update(&m_maxDuration, delta, sg_surf_precision);
964 //FIXME: duplicated code
965 if ((m_remains <= 0) &&
966 (lmm_get_variable_weight(getVariable()) > 0)) {
968 setState(SURF_ACTION_DONE);
969 heapRemove(getModel()->getActionHeap());
970 } else if (((m_maxDuration != NO_MAX_DURATION)
971 && (m_maxDuration <= 0))) {
973 setState(SURF_ACTION_DONE);
974 heapRemove(getModel()->getActionHeap());
979 m_lastValue = lmm_variable_getvalue(getVariable());