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 surf_callback(void, void) surfExitCallbacks;
46 s_surf_model_description_t surf_plugin_description[] = {
47 {"Energy", "Cpu energy consumption.", sg_energy_plugin_init},
48 {NULL, NULL, NULL} /* this array must be NULL terminated */
51 /* Don't forget to update the option description in smx_config when you change
53 s_surf_model_description_t surf_network_model_description[] = {
55 "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). ",
56 surf_network_model_init_LegrandVelho},
58 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
59 surf_network_model_init_Constant},
61 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
62 surf_network_model_init_SMPI},
64 "Realistic network model specifically tailored for HPC settings, with Infiniband contention model",
65 surf_network_model_init_IB},
67 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
68 surf_network_model_init_CM02},
71 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
72 surf_network_model_init_NS3},
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_Reno},
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_Reno2},
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_Vegas},
83 {NULL, NULL, NULL} /* this array must be NULL terminated */
86 s_surf_model_description_t surf_cpu_model_description[] = {
88 "Simplistic CPU model (time=size/power).",
89 surf_cpu_model_init_Cas01},
90 {NULL, NULL, NULL} /* this array must be NULL terminated */
93 s_surf_model_description_t surf_host_model_description[] = {
95 "Default host model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
96 surf_host_model_init_current_default},
98 "Host model that is automatically chosen if you change the network and CPU models",
99 surf_host_model_init_compound},
100 {"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks",
101 surf_host_model_init_ptask_L07},
102 {NULL, NULL, NULL} /* this array must be NULL terminated */
105 s_surf_model_description_t surf_vm_model_description[] = {
108 surf_vm_model_init_HL13},
109 {NULL, NULL, NULL} /* this array must be NULL terminated */
112 s_surf_model_description_t surf_optimization_mode_description[] = {
114 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
117 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
120 "Full update of remaining and variables. Slow but may be useful when debugging.",
122 {NULL, NULL, NULL} /* this array must be NULL terminated */
125 s_surf_model_description_t surf_storage_model_description[] = {
127 "Simplistic storage model.",
128 surf_storage_model_init_default},
129 {NULL, NULL, NULL} /* this array must be NULL terminated */
132 #ifdef CONTEXT_THREADS
133 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
138 double surf_get_clock(void)
144 # define FILE_DELIM "\\"
146 # define FILE_DELIM "/" /* FIXME: move to better location */
149 FILE *surf_fopen(const char *name, const char *mode)
152 char *path_elm = NULL;
158 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
159 return fopen(name, mode);
161 /* search relative files in the path */
162 xbt_dynar_foreach(surf_path, cpt, path_elm) {
163 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
164 file = fopen(buff, mode);
176 static const char *disk_drives_letter_table[MAX_DRIVE] = {
177 "A:\\","B:\\","C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\",
178 "N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"
183 * Returns the initial path. On Windows the initial path is
184 * the current directory for the current process in the other
185 * case the function returns "./" that represents the current
186 * directory on Unix/Linux platforms.
189 const char *__surf_get_initial_path(void)
194 char current_directory[MAX_PATH + 1] = { 0 };
195 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
196 char root[4] = { 0 };
201 strncpy(root, current_directory, 3);
203 for (i = 0; i < MAX_DRIVE; i++) {
204 if (toupper(root[0]) == disk_drives_letter_table[i][0])
205 return disk_drives_letter_table[i];
214 /* The __surf_is_absolute_file_path() returns 1 if
215 * file_path is a absolute file path, in the other
216 * case the function returns 0.
218 int __surf_is_absolute_file_path(const char *file_path)
221 WIN32_FIND_DATA wfd = { 0 };
222 HANDLE hFile = FindFirstFile(file_path, &wfd);
224 if (INVALID_HANDLE_VALUE == hFile)
230 return (file_path[0] == '/');
234 /** Displays the long description of all registered models, and quit */
235 void model_help(const char *category, s_surf_model_description_t * table)
238 printf("Long description of the %s models accepted by this simulator:\n",
240 for (i = 0; table[i].name; i++)
241 printf(" %s: %s\n", table[i].name, table[i].description);
244 int find_model_description(s_surf_model_description_t * table,
248 char *name_list = NULL;
250 for (i = 0; table[i].name; i++)
251 if (!strcmp(name, table[i].name)) {
255 xbt_die("No model is valid! This is a bug.");
256 name_list = xbt_strdup(table[0].name);
257 for (i = 1; table[i].name; i++) {
258 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
259 strcat(name_list, ", ");
260 strcat(name_list, table[i].name);
262 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
266 static XBT_INLINE void routing_asr_prop_free(void *p)
268 //xbt_dict_t elm = (xbt_dict_t) p;
269 //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster
272 static XBT_INLINE void surf_host_free(void *r)
274 delete static_cast<simgrid::surf::Host*>(r);
277 static XBT_INLINE void surf_storage_free(void *r)
279 delete static_cast<simgrid::surf::Storage*>(r);
282 void sg_version_check(int lib_version_major,int lib_version_minor,int lib_version_patch) {
283 if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) {
285 "FATAL ERROR: Your program was compiled with SimGrid version %d.%d.%d, "
286 "and then linked against SimGrid %d.%d.%d. Please fix this.\n",
287 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
288 lib_version_major,lib_version_minor,lib_version_patch);
291 if (lib_version_patch != SIMGRID_VERSION_PATCH) {
293 "Warning: Your program was compiled with SimGrid version %d.%d.%d, "
294 "and then linked against SimGrid %d.%d.%d. Proceeding anyway.\n",
295 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
296 lib_version_major,lib_version_minor,lib_version_patch);
300 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
301 *ver_major = SIMGRID_VERSION_MAJOR;
302 *ver_minor = SIMGRID_VERSION_MINOR;
303 *ver_patch = SIMGRID_VERSION_PATCH;
306 void surf_init(int *argc, char **argv)
308 XBT_DEBUG("Create all Libs");
309 host_list = xbt_dict_new_homogeneous([](void*p) {
310 delete (simgrid::Host*)p;
312 as_router_lib = xbt_lib_new();
313 storage_lib = xbt_lib_new();
314 storage_type_lib = xbt_lib_new();
315 file_lib = xbt_lib_new();
316 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
320 XBT_DEBUG("Add routing levels");
321 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
323 XBT_DEBUG("Add SURF levels");
324 SURF_HOST_LEVEL = simgrid::Host::add_level(surf_host_free);
325 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
327 xbt_init(argc, argv);
328 if (!all_existing_models)
329 all_existing_models = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
330 if (!model_list_invoke)
331 model_list_invoke = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
333 history = tmgr_history_new();
335 TRACE_add_start_function(TRACE_surf_alloc);
336 TRACE_add_end_function(TRACE_surf_release);
338 sg_config_init(argc, argv);
347 simgrid::surf::Model *model = NULL;
349 TRACE_end(); /* Just in case it was not called by the upper
350 * layer (or there is no upper layer) */
352 sg_config_finalize();
354 xbt_dynar_free(&host_that_restart);
355 xbt_dynar_free(&surf_path);
357 xbt_dict_free(&host_list);
358 xbt_lib_free(&as_router_lib);
359 xbt_lib_free(&storage_lib);
361 xbt_lib_free(&storage_type_lib);
362 xbt_lib_free(&file_lib);
363 xbt_dict_free(&watched_hosts_lib);
365 xbt_dynar_foreach(all_existing_models, iter, model)
367 xbt_dynar_free(&all_existing_models);
368 xbt_dynar_free(&model_list_invoke);
371 surf_callback_emit(simgrid::surf::surfExitCallbacks);
374 lmm_system_free(maxmin_system);
375 maxmin_system = NULL;
378 tmgr_history_free(history);
382 #ifdef CONTEXT_THREADS
383 xbt_parmap_destroy(surf_parmap);
387 surf_parse_lex_destroy();
388 surf_parse_free_callbacks();
390 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
401 : p_maxminSystem(NULL)
403 p_readyActionSet = new ActionList();
404 p_runningActionSet = new ActionList();
405 p_failedActionSet = new ActionList();
406 p_doneActionSet = new ActionList();
408 p_modifiedSet = NULL;
410 p_updateMechanism = UM_UNDEFINED;
411 m_selectiveUpdate = 0;
415 delete p_readyActionSet;
416 delete p_runningActionSet;
417 delete p_failedActionSet;
418 delete p_doneActionSet;
421 double Model::shareResources(double now)
423 //FIXME: set the good function once and for all
424 if (p_updateMechanism == UM_LAZY)
425 return shareResourcesLazy(now);
426 else if (p_updateMechanism == UM_FULL)
427 return shareResourcesFull(now);
429 xbt_die("Invalid cpu update mechanism!");
432 double Model::shareResourcesLazy(double now)
434 Action *action = NULL;
439 ("Before share resources, the size of modified actions set is %zd",
440 p_modifiedSet->size());
442 lmm_solve(p_maxminSystem);
445 ("After share resources, The size of modified actions set is %zd",
446 p_modifiedSet->size());
448 while(!p_modifiedSet->empty()) {
449 action = &(p_modifiedSet->front());
450 p_modifiedSet->pop_front();
451 int max_dur_flag = 0;
453 if (action->getStateSet() != p_runningActionSet)
456 /* bogus priority, skip it */
457 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
460 action->updateRemainingLazy(now);
463 share = lmm_variable_getvalue(action->getVariable());
466 double time_to_completion;
467 if (action->getRemains() > 0) {
468 time_to_completion = action->getRemainsNoUpdate() / share;
470 time_to_completion = 0.0;
472 min = now + time_to_completion; // when the task will complete if nothing changes
475 if ((action->getMaxDuration() != NO_MAX_DURATION)
477 || action->getStartTime() +
478 action->getMaxDuration() < min)) {
479 min = action->getStartTime() +
480 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
485 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
487 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
488 action->getStartTime(), min, share,
489 action->getMaxDuration());
492 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
493 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
495 } else DIE_IMPOSSIBLE;
498 //hereafter must have already the min value for this resource model
499 if (xbt_heap_size(p_actionHeap) > 0)
500 min = xbt_heap_maxkey(p_actionHeap) - now;
504 XBT_DEBUG("The minimum with the HEAP %f", min);
509 double Model::shareResourcesFull(double /*now*/) {
513 double Model::shareResourcesMaxMin(ActionList *running_actions,
515 void (*solve) (lmm_system_t))
517 Action *action = NULL;
523 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
524 for(; it != itend ; ++it) {
526 value = lmm_variable_getvalue(action->getVariable());
527 if ((value > 0) || (action->getMaxDuration() >= 0))
535 if (action->getRemains() > 0)
536 min = action->getRemainsNoUpdate() / value;
539 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
540 min = action->getMaxDuration();
542 min = action->getMaxDuration();
545 for (++it; it != itend; ++it) {
547 value = lmm_variable_getvalue(action->getVariable());
549 if (action->getRemains() > 0)
550 value = action->getRemainsNoUpdate() / value;
555 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
558 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
559 min = action->getMaxDuration();
560 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
563 XBT_DEBUG("min value : %f", min);
568 void Model::updateActionsState(double now, double delta)
570 if (p_updateMechanism == UM_FULL)
571 updateActionsStateFull(now, delta);
572 else if (p_updateMechanism == UM_LAZY)
573 updateActionsStateLazy(now, delta);
575 xbt_die("Invalid cpu update mechanism!");
578 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
583 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
599 : p_name(NULL), p_properties(NULL), p_model(NULL)
602 Resource::Resource(Model *model, const char *name, xbt_dict_t props)
603 : Resource(model, name, props, SURF_RESOURCE_ON)
606 Resource::Resource(Model *model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
607 : Resource(model, name, props, constraint, SURF_RESOURCE_ON)
611 Model *model, const char *name, xbt_dict_t props,
612 lmm_constraint_t constraint, e_surf_resource_state_t stateInit)
613 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
614 , m_running(true), m_stateCurrent(stateInit), p_constraint(constraint)
617 Resource::Resource(Model *model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
618 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
619 , m_running(true), m_stateCurrent(stateInit)
622 Resource::~Resource() {
623 xbt_free((void*)p_name);
624 xbt_dict_free(&p_properties);
627 e_surf_resource_state_t Resource::getState()
629 return m_stateCurrent;
632 void Resource::setState(e_surf_resource_state_t state)
634 m_stateCurrent = state;
637 bool Resource::isOn()
642 void Resource::turnOn()
649 void Resource::turnOff()
656 Model *Resource::getModel() {
660 const char *Resource::getName() {
664 xbt_dict_t Resource::getProperties() {
665 if (p_properties==NULL)
666 p_properties = xbt_dict_new();
670 lmm_constraint_t Resource::getConstraint() {
681 const char *surf_action_state_names[6] = {
683 "SURF_ACTION_RUNNING",
684 "SURF_ACTION_FAILED",
686 "SURF_ACTION_TO_FREE",
687 "SURF_ACTION_NOT_IN_THE_SYSTEM"
690 /* added to manage the communication action's heap */
691 void surf_action_lmm_update_index_heap(void *action, int i) {
692 static_cast<simgrid::surf::Action*>(action)->updateIndexHeap(i);
698 void Action::initialize(simgrid::surf::Model *model, double cost, bool failed,
704 m_maxDuration = NO_MAX_DURATION;
706 m_start = surf_get_clock();
716 p_stateHookup.prev = 0;
717 p_stateHookup.next = 0;
719 p_stateSet = getModel()->getFailedActionSet();
721 p_stateSet = getModel()->getRunningActionSet();
723 p_stateSet->push_back(*this);
726 Action::Action(simgrid::surf::Model *model, double cost, bool failed)
728 initialize(model, cost, failed);
731 Action::Action(simgrid::surf::Model *model, double cost, bool failed, lmm_variable_t var)
733 initialize(model, cost, failed, var);
737 xbt_free(p_category);
740 void Action::finish() {
741 m_finish = surf_get_clock();
744 e_surf_action_state_t Action::getState()
746 if (p_stateSet == getModel()->getReadyActionSet())
747 return SURF_ACTION_READY;
748 if (p_stateSet == getModel()->getRunningActionSet())
749 return SURF_ACTION_RUNNING;
750 if (p_stateSet == getModel()->getFailedActionSet())
751 return SURF_ACTION_FAILED;
752 if (p_stateSet == getModel()->getDoneActionSet())
753 return SURF_ACTION_DONE;
754 return SURF_ACTION_NOT_IN_THE_SYSTEM;
757 void Action::setState(e_surf_action_state_t state)
759 //surf_action_state_t action_state = &(action->model_type->states);
760 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
761 p_stateSet->erase(p_stateSet->iterator_to(*this));
762 if (state == SURF_ACTION_READY)
763 p_stateSet = getModel()->getReadyActionSet();
764 else if (state == SURF_ACTION_RUNNING)
765 p_stateSet = getModel()->getRunningActionSet();
766 else if (state == SURF_ACTION_FAILED)
767 p_stateSet = getModel()->getFailedActionSet();
768 else if (state == SURF_ACTION_DONE)
769 p_stateSet = getModel()->getDoneActionSet();
774 p_stateSet->push_back(*this);
778 double Action::getBound()
780 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
783 void Action::setBound(double bound)
785 XBT_IN("(%p,%g)", this, bound);
787 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
789 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
790 heapRemove(getModel()->getActionHeap());
794 double Action::getStartTime()
799 double Action::getFinishTime()
801 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
802 return m_remains == 0 ? m_finish : -1;
805 void Action::setData(void* data)
810 void Action::setCategory(const char *category)
812 XBT_IN("(%p,%s)", this, category);
813 p_category = xbt_strdup(category);
821 void Action::setMaxDuration(double duration)
823 XBT_IN("(%p,%g)", this, duration);
824 m_maxDuration = duration;
825 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
826 heapRemove(getModel()->getActionHeap());
830 void Action::gapRemove() {}
832 void Action::setPriority(double priority)
834 XBT_IN("(%p,%g)", this, priority);
835 m_priority = priority;
836 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
838 if (getModel()->getUpdateMechanism() == UM_LAZY)
839 heapRemove(getModel()->getActionHeap());
843 void Action::cancel(){
844 setState(SURF_ACTION_FAILED);
845 if (getModel()->getUpdateMechanism() == UM_LAZY) {
846 if (action_lmm_hook.is_linked())
847 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
848 heapRemove(getModel()->getActionHeap());
855 if (action_hook.is_linked())
856 p_stateSet->erase(p_stateSet->iterator_to(*this));
858 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
859 if (getModel()->getUpdateMechanism() == UM_LAZY) {
860 /* remove from heap */
861 heapRemove(getModel()->getActionHeap());
862 if (action_lmm_hook.is_linked())
863 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
871 void Action::suspend()
873 XBT_IN("(%p)", this);
874 if (m_suspended != 2) {
875 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
877 if (getModel()->getUpdateMechanism() == UM_LAZY)
878 heapRemove(getModel()->getActionHeap());
883 void Action::resume()
885 XBT_IN("(%p)", this);
886 if (m_suspended != 2) {
887 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
889 if (getModel()->getUpdateMechanism() == UM_LAZY)
890 heapRemove(getModel()->getActionHeap());
895 bool Action::isSuspended()
897 return m_suspended == 1;
899 /* insert action on heap using a given key and a hat (heap_action_type)
900 * a hat can be of three types for communications:
902 * NORMAL = this is a normal heap entry stating the date to finish transmitting
903 * LATENCY = this is a heap entry to warn us when the latency is payed
904 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
906 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
909 xbt_heap_push(heap, this, key);
912 void Action::heapRemove(xbt_heap_t heap)
915 if (m_indexHeap >= 0) {
916 xbt_heap_remove(heap, m_indexHeap);
920 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
923 if (m_indexHeap >= 0) {
924 xbt_heap_update(heap, m_indexHeap, key);
926 xbt_heap_push(heap, this, key);
930 void Action::updateIndexHeap(int i) {
934 double Action::getRemains()
936 XBT_IN("(%p)", this);
937 /* update remains before return it */
938 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
939 updateRemainingLazy(surf_get_clock());
944 double Action::getRemainsNoUpdate()
949 //FIXME split code in the right places
950 void Action::updateRemainingLazy(double now)
954 if(getModel() == surf_network_model)
956 if (m_suspended != 0)
961 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
962 "You're updating an action that is not running.");
964 /* bogus priority, skip it */
965 xbt_assert(m_priority > 0,
966 "You're updating an action that seems suspended.");
969 delta = now - m_lastUpdate;
972 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
973 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
975 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
976 simgrid::surf::Resource *cpu = static_cast<simgrid::surf::Resource*>(
977 lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
978 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
980 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
983 if(getModel() == surf_network_model)
985 if (m_maxDuration != NO_MAX_DURATION)
986 double_update(&m_maxDuration, delta, sg_surf_precision);
988 //FIXME: duplicated code
989 if ((m_remains <= 0) &&
990 (lmm_get_variable_weight(getVariable()) > 0)) {
992 setState(SURF_ACTION_DONE);
993 heapRemove(getModel()->getActionHeap());
994 } else if (((m_maxDuration != NO_MAX_DURATION)
995 && (m_maxDuration <= 0))) {
997 setState(SURF_ACTION_DONE);
998 heapRemove(getModel()->getActionHeap());
1003 m_lastValue = lmm_variable_getvalue(getVariable());