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_storage_free(void *r)
274 delete static_cast<simgrid::surf::Storage*>(r);
277 void sg_version_check(int lib_version_major,int lib_version_minor,int lib_version_patch) {
278 if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) {
280 "FATAL ERROR: Your program was compiled with SimGrid version %d.%d.%d, "
281 "and then linked against SimGrid %d.%d.%d. Please fix this.\n",
282 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
283 lib_version_major,lib_version_minor,lib_version_patch);
286 if (lib_version_patch != SIMGRID_VERSION_PATCH) {
288 "Warning: Your program was compiled with SimGrid version %d.%d.%d, "
289 "and then linked against SimGrid %d.%d.%d. Proceeding anyway.\n",
290 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
291 lib_version_major,lib_version_minor,lib_version_patch);
295 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
296 *ver_major = SIMGRID_VERSION_MAJOR;
297 *ver_minor = SIMGRID_VERSION_MINOR;
298 *ver_patch = SIMGRID_VERSION_PATCH;
301 void surf_init(int *argc, char **argv)
303 XBT_DEBUG("Create all Libs");
304 host_list = xbt_dict_new_homogeneous([](void*p) {
305 delete (simgrid::Host*)p;
307 as_router_lib = xbt_lib_new();
308 storage_lib = xbt_lib_new();
309 storage_type_lib = xbt_lib_new();
310 file_lib = xbt_lib_new();
311 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
315 XBT_DEBUG("Add routing levels");
316 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
318 XBT_DEBUG("Add SURF levels");
319 simgrid::surf::Host::init();
320 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
322 xbt_init(argc, argv);
323 if (!all_existing_models)
324 all_existing_models = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
325 if (!model_list_invoke)
326 model_list_invoke = xbt_dynar_new(sizeof(simgrid::surf::Model*), NULL);
328 history = tmgr_history_new();
330 TRACE_add_start_function(TRACE_surf_alloc);
331 TRACE_add_end_function(TRACE_surf_release);
333 sg_config_init(argc, argv);
342 simgrid::surf::Model *model = NULL;
344 TRACE_end(); /* Just in case it was not called by the upper
345 * layer (or there is no upper layer) */
347 sg_config_finalize();
349 xbt_dynar_free(&host_that_restart);
350 xbt_dynar_free(&surf_path);
352 xbt_dict_free(&host_list);
353 xbt_lib_free(&as_router_lib);
354 xbt_lib_free(&storage_lib);
356 xbt_lib_free(&storage_type_lib);
357 xbt_lib_free(&file_lib);
358 xbt_dict_free(&watched_hosts_lib);
360 xbt_dynar_foreach(all_existing_models, iter, model)
362 xbt_dynar_free(&all_existing_models);
363 xbt_dynar_free(&model_list_invoke);
366 surf_callback_emit(simgrid::surf::surfExitCallbacks);
369 lmm_system_free(maxmin_system);
370 maxmin_system = NULL;
373 tmgr_history_free(history);
377 #ifdef CONTEXT_THREADS
378 xbt_parmap_destroy(surf_parmap);
382 surf_parse_lex_destroy();
383 surf_parse_free_callbacks();
385 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
396 : p_maxminSystem(NULL)
398 p_readyActionSet = new ActionList();
399 p_runningActionSet = new ActionList();
400 p_failedActionSet = new ActionList();
401 p_doneActionSet = new ActionList();
403 p_modifiedSet = NULL;
405 p_updateMechanism = UM_UNDEFINED;
406 m_selectiveUpdate = 0;
410 delete p_readyActionSet;
411 delete p_runningActionSet;
412 delete p_failedActionSet;
413 delete p_doneActionSet;
416 double Model::shareResources(double now)
418 //FIXME: set the good function once and for all
419 if (p_updateMechanism == UM_LAZY)
420 return shareResourcesLazy(now);
421 else if (p_updateMechanism == UM_FULL)
422 return shareResourcesFull(now);
424 xbt_die("Invalid cpu update mechanism!");
427 double Model::shareResourcesLazy(double now)
429 Action *action = NULL;
434 ("Before share resources, the size of modified actions set is %zd",
435 p_modifiedSet->size());
437 lmm_solve(p_maxminSystem);
440 ("After share resources, The size of modified actions set is %zd",
441 p_modifiedSet->size());
443 while(!p_modifiedSet->empty()) {
444 action = &(p_modifiedSet->front());
445 p_modifiedSet->pop_front();
446 int max_dur_flag = 0;
448 if (action->getStateSet() != p_runningActionSet)
451 /* bogus priority, skip it */
452 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
455 action->updateRemainingLazy(now);
458 share = lmm_variable_getvalue(action->getVariable());
461 double time_to_completion;
462 if (action->getRemains() > 0) {
463 time_to_completion = action->getRemainsNoUpdate() / share;
465 time_to_completion = 0.0;
467 min = now + time_to_completion; // when the task will complete if nothing changes
470 if ((action->getMaxDuration() != NO_MAX_DURATION)
472 || action->getStartTime() +
473 action->getMaxDuration() < min)) {
474 min = action->getStartTime() +
475 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
480 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
482 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
483 action->getStartTime(), min, share,
484 action->getMaxDuration());
487 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
488 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
490 } else DIE_IMPOSSIBLE;
493 //hereafter must have already the min value for this resource model
494 if (xbt_heap_size(p_actionHeap) > 0)
495 min = xbt_heap_maxkey(p_actionHeap) - now;
499 XBT_DEBUG("The minimum with the HEAP %f", min);
504 double Model::shareResourcesFull(double /*now*/) {
508 double Model::shareResourcesMaxMin(ActionList *running_actions,
510 void (*solve) (lmm_system_t))
512 Action *action = NULL;
518 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
519 for(; it != itend ; ++it) {
521 value = lmm_variable_getvalue(action->getVariable());
522 if ((value > 0) || (action->getMaxDuration() >= 0))
530 if (action->getRemains() > 0)
531 min = action->getRemainsNoUpdate() / value;
534 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
535 min = action->getMaxDuration();
537 min = action->getMaxDuration();
540 for (++it; it != itend; ++it) {
542 value = lmm_variable_getvalue(action->getVariable());
544 if (action->getRemains() > 0)
545 value = action->getRemainsNoUpdate() / value;
550 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
553 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
554 min = action->getMaxDuration();
555 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
558 XBT_DEBUG("min value : %f", min);
563 void Model::updateActionsState(double now, double delta)
565 if (p_updateMechanism == UM_FULL)
566 updateActionsStateFull(now, delta);
567 else if (p_updateMechanism == UM_LAZY)
568 updateActionsStateLazy(now, delta);
570 xbt_die("Invalid cpu update mechanism!");
573 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
578 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
594 : p_name(NULL), p_model(NULL)
597 Resource::Resource(Model *model, const char *name)
598 : Resource(model, name, SURF_RESOURCE_ON)
601 Resource::Resource(Model *model, const char *name, lmm_constraint_t constraint)
602 : Resource(model, name, constraint, SURF_RESOURCE_ON)
606 Model *model, const char *name,
607 lmm_constraint_t constraint, e_surf_resource_state_t stateInit)
608 : p_name(xbt_strdup(name)), p_model(model)
609 , m_running(true), m_stateCurrent(stateInit), p_constraint(constraint)
612 Resource::Resource(Model *model, const char *name, e_surf_resource_state_t stateInit)
613 : p_name(xbt_strdup(name)), p_model(model)
614 , m_running(true), m_stateCurrent(stateInit)
617 /** Cleanup code of the full object.
619 * The destructed callbacks might need to have a fully
620 * created `Cpu` instance so they cannot be called `~Cpu()`
621 * (at this point the fields of the parents have been destroyed
622 * and the virtual methods are the ones of `Cpu`). If a `Cpu`
623 * subclass overrides any virtual method, it should call this
624 * method at the beginning of the destructor in order to trigger
625 * the callbacks in the real state of the Cpu.
627 * Once the method has been called once, it becomes a noop ensuring
628 * that the callbacks are not for each class of the hierarchy.
630 * A better solution would be to call a `Cpu::destroy()` method
631 * before calling the destructor and trigger the callbacks here.
641 void Resource::onDie() {}
643 Resource::~Resource() {
645 xbt_free((void*)p_name);
648 e_surf_resource_state_t Resource::getState()
650 return m_stateCurrent;
653 void Resource::setState(e_surf_resource_state_t state)
655 m_stateCurrent = state;
658 bool Resource::isOn()
663 void Resource::turnOn()
670 void Resource::turnOff()
677 Model *Resource::getModel() {
681 const char *Resource::getName() {
685 lmm_constraint_t Resource::getConstraint() {
696 const char *surf_action_state_names[6] = {
698 "SURF_ACTION_RUNNING",
699 "SURF_ACTION_FAILED",
701 "SURF_ACTION_TO_FREE",
702 "SURF_ACTION_NOT_IN_THE_SYSTEM"
705 /* added to manage the communication action's heap */
706 void surf_action_lmm_update_index_heap(void *action, int i) {
707 static_cast<simgrid::surf::Action*>(action)->updateIndexHeap(i);
713 void Action::initialize(simgrid::surf::Model *model, double cost, bool failed,
719 m_maxDuration = NO_MAX_DURATION;
721 m_start = surf_get_clock();
731 p_stateHookup.prev = 0;
732 p_stateHookup.next = 0;
734 p_stateSet = getModel()->getFailedActionSet();
736 p_stateSet = getModel()->getRunningActionSet();
738 p_stateSet->push_back(*this);
741 Action::Action(simgrid::surf::Model *model, double cost, bool failed)
743 initialize(model, cost, failed);
746 Action::Action(simgrid::surf::Model *model, double cost, bool failed, lmm_variable_t var)
748 initialize(model, cost, failed, var);
752 xbt_free(p_category);
755 void Action::finish() {
756 m_finish = surf_get_clock();
759 e_surf_action_state_t Action::getState()
761 if (p_stateSet == getModel()->getReadyActionSet())
762 return SURF_ACTION_READY;
763 if (p_stateSet == getModel()->getRunningActionSet())
764 return SURF_ACTION_RUNNING;
765 if (p_stateSet == getModel()->getFailedActionSet())
766 return SURF_ACTION_FAILED;
767 if (p_stateSet == getModel()->getDoneActionSet())
768 return SURF_ACTION_DONE;
769 return SURF_ACTION_NOT_IN_THE_SYSTEM;
772 void Action::setState(e_surf_action_state_t state)
774 //surf_action_state_t action_state = &(action->model_type->states);
775 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
776 p_stateSet->erase(p_stateSet->iterator_to(*this));
777 if (state == SURF_ACTION_READY)
778 p_stateSet = getModel()->getReadyActionSet();
779 else if (state == SURF_ACTION_RUNNING)
780 p_stateSet = getModel()->getRunningActionSet();
781 else if (state == SURF_ACTION_FAILED)
782 p_stateSet = getModel()->getFailedActionSet();
783 else if (state == SURF_ACTION_DONE)
784 p_stateSet = getModel()->getDoneActionSet();
789 p_stateSet->push_back(*this);
793 double Action::getBound()
795 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
798 void Action::setBound(double bound)
800 XBT_IN("(%p,%g)", this, bound);
802 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
804 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
805 heapRemove(getModel()->getActionHeap());
809 double Action::getStartTime()
814 double Action::getFinishTime()
816 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
817 return m_remains == 0 ? m_finish : -1;
820 void Action::setData(void* data)
825 void Action::setCategory(const char *category)
827 XBT_IN("(%p,%s)", this, category);
828 p_category = xbt_strdup(category);
836 void Action::setMaxDuration(double duration)
838 XBT_IN("(%p,%g)", this, duration);
839 m_maxDuration = duration;
840 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
841 heapRemove(getModel()->getActionHeap());
845 void Action::gapRemove() {}
847 void Action::setPriority(double priority)
849 XBT_IN("(%p,%g)", this, priority);
850 m_priority = priority;
851 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
853 if (getModel()->getUpdateMechanism() == UM_LAZY)
854 heapRemove(getModel()->getActionHeap());
858 void Action::cancel(){
859 setState(SURF_ACTION_FAILED);
860 if (getModel()->getUpdateMechanism() == UM_LAZY) {
861 if (action_lmm_hook.is_linked())
862 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
863 heapRemove(getModel()->getActionHeap());
870 if (action_hook.is_linked())
871 p_stateSet->erase(p_stateSet->iterator_to(*this));
873 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
874 if (getModel()->getUpdateMechanism() == UM_LAZY) {
875 /* remove from heap */
876 heapRemove(getModel()->getActionHeap());
877 if (action_lmm_hook.is_linked())
878 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
886 void Action::suspend()
888 XBT_IN("(%p)", this);
889 if (m_suspended != 2) {
890 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
892 if (getModel()->getUpdateMechanism() == UM_LAZY)
893 heapRemove(getModel()->getActionHeap());
898 void Action::resume()
900 XBT_IN("(%p)", this);
901 if (m_suspended != 2) {
902 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
904 if (getModel()->getUpdateMechanism() == UM_LAZY)
905 heapRemove(getModel()->getActionHeap());
910 bool Action::isSuspended()
912 return m_suspended == 1;
914 /* insert action on heap using a given key and a hat (heap_action_type)
915 * a hat can be of three types for communications:
917 * NORMAL = this is a normal heap entry stating the date to finish transmitting
918 * LATENCY = this is a heap entry to warn us when the latency is payed
919 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
921 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
924 xbt_heap_push(heap, this, key);
927 void Action::heapRemove(xbt_heap_t heap)
930 if (m_indexHeap >= 0) {
931 xbt_heap_remove(heap, m_indexHeap);
935 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
938 if (m_indexHeap >= 0) {
939 xbt_heap_update(heap, m_indexHeap, key);
941 xbt_heap_push(heap, this, key);
945 void Action::updateIndexHeap(int i) {
949 double Action::getRemains()
951 XBT_IN("(%p)", this);
952 /* update remains before return it */
953 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
954 updateRemainingLazy(surf_get_clock());
959 double Action::getRemainsNoUpdate()
964 //FIXME split code in the right places
965 void Action::updateRemainingLazy(double now)
969 if(getModel() == surf_network_model)
971 if (m_suspended != 0)
976 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
977 "You're updating an action that is not running.");
979 /* bogus priority, skip it */
980 xbt_assert(m_priority > 0,
981 "You're updating an action that seems suspended.");
984 delta = now - m_lastUpdate;
987 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
988 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
990 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
991 simgrid::surf::Resource *cpu = static_cast<simgrid::surf::Resource*>(
992 lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
993 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
995 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
998 if(getModel() == surf_network_model)
1000 if (m_maxDuration != NO_MAX_DURATION)
1001 double_update(&m_maxDuration, delta, sg_surf_precision);
1003 //FIXME: duplicated code
1004 if ((m_remains <= 0) &&
1005 (lmm_get_variable_weight(getVariable()) > 0)) {
1007 setState(SURF_ACTION_DONE);
1008 heapRemove(getModel()->getActionHeap());
1009 } else if (((m_maxDuration != NO_MAX_DURATION)
1010 && (m_maxDuration <= 0))) {
1012 setState(SURF_ACTION_DONE);
1013 heapRemove(getModel()->getActionHeap());
1018 m_lastValue = lmm_variable_getvalue(getVariable());