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 "simix/smx_host_private.h"
13 #include "surf_routing.hpp"
14 #include "simgrid/sg_config.h"
16 #include "vm_interface.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 /* This function is a pimple that we ought to fix. But it won't be easy.
28 * The surf_solve() function does properly return the set of actions that
29 * changed. Instead, each model change a global data, and then the caller of
30 * surf_solve must pick into these sets of action_failed and action_done.
32 * This was not clean but ok as long as we didn't had to restart the processes
33 * when the resource comes back up.
34 * We worked by putting sentinel actions on every resources we are interested
35 * in, so that surf informs us if/when the corresponding resource fails.
37 * But this does not work to get Simix informed of when a resource comes back
38 * up, and this is where this pimple comes. We have a set of resources that are
39 * currently down and for which simix needs to know when it comes back up.
40 * And the current function is called *at every simulation step* to sweep over
41 * that set, searching for a resource that was turned back up in the meanwhile.
42 * This is UGLY and slow.
44 * The proper solution would be to not rely on globals for the action_failed and
45 * action_done swags. They must be passed as parameter by the caller (the
46 * handling of these actions in simix may let you think that these two sets can
47 * be merged, but their handling in SimDag induce the contrary unless this
48 * simdag code can check by itself whether the action is done of failed -- seems
49 * very doable, but yet more cleanup to do).
51 * Once surf_solve() is passed the set of actions that changed, you want to add
52 * a new set of resources back up as parameter to this function. You also want
53 * to add a boolean field "restart_watched" to each resource, and make sure that
54 * whenever a resource with this field enabled comes back up, it's added to that
55 * set so that Simix sees it and react accordingly. This would kill that need
56 * for surf to call simix.
60 /*static void remove_watched_host(void *key)
62 xbt_dict_remove(watched_hosts_lib, *(char**)key);
65 /*void surf_watched_hosts(void)
69 xbt_dict_cursor_t cursor;
70 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
72 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
73 xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
75 if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
76 XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
77 SIMIX_host_autorestart((smx_host_t)host);
78 xbt_dynar_push_as(hosts, char*, key);
81 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
83 xbt_dynar_map(hosts, remove_watched_host);
84 xbt_dynar_free(&hosts);
87 /* model_list_invoke contains only surf_host and surf_vm.
88 * The callback functions of cpu_model and network_model will be called from
89 * those of these host models. */
90 xbt_dynar_t model_list = NULL; /* for destroying all models correctly */
91 xbt_dynar_t model_list_invoke = NULL; /* for invoking callbacks */
93 tmgr_history_t history = NULL;
94 lmm_system_t maxmin_system = NULL;
95 xbt_dynar_t surf_path = NULL;
96 xbt_dynar_t host_that_restart = NULL;
97 xbt_dict_t watched_hosts_lib;
99 surf_callback(void, void) surfExitCallbacks;
101 s_surf_model_description_t surf_plugin_description[] = {
102 {"Energy", "Cpu energy consumption.", sg_energy_plugin_init},
103 {NULL, NULL, NULL} /* this array must be NULL terminated */
106 /* Don't forget to update the option description in smx_config when you change
108 s_surf_model_description_t surf_network_model_description[] = {
110 "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). ",
111 surf_network_model_init_LegrandVelho},
113 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
114 surf_network_model_init_Constant},
116 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
117 surf_network_model_init_SMPI},
119 "Realistic network model specifically tailored for HPC settings, with Infiniband contention model",
120 surf_network_model_init_IB},
122 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
123 surf_network_model_init_CM02},
126 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
127 surf_network_model_init_NS3},
130 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
131 surf_network_model_init_Reno},
133 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
134 surf_network_model_init_Reno2},
136 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
137 surf_network_model_init_Vegas},
138 {NULL, NULL, NULL} /* this array must be NULL terminated */
141 s_surf_model_description_t surf_cpu_model_description[] = {
143 "Simplistic CPU model (time=size/power).",
144 surf_cpu_model_init_Cas01},
145 {NULL, NULL, NULL} /* this array must be NULL terminated */
148 s_surf_model_description_t surf_host_model_description[] = {
150 "Default host model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
151 surf_host_model_init_current_default},
153 "Host model that is automatically chosen if you change the network and CPU models",
154 surf_host_model_init_compound},
155 {"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks",
156 surf_host_model_init_ptask_L07},
157 {NULL, NULL, NULL} /* this array must be NULL terminated */
160 s_surf_model_description_t surf_vm_model_description[] = {
163 surf_vm_model_init_HL13},
164 {NULL, NULL, NULL} /* this array must be NULL terminated */
167 s_surf_model_description_t surf_optimization_mode_description[] = {
169 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
172 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
175 "Full update of remaining and variables. Slow but may be useful when debugging.",
177 {NULL, NULL, NULL} /* this array must be NULL terminated */
180 s_surf_model_description_t surf_storage_model_description[] = {
182 "Simplistic storage model.",
183 surf_storage_model_init_default},
184 {NULL, NULL, NULL} /* this array must be NULL terminated */
187 #ifdef CONTEXT_THREADS
188 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
193 double surf_get_clock(void)
199 # define FILE_DELIM "\\"
201 # define FILE_DELIM "/" /* FIXME: move to better location */
204 FILE *surf_fopen(const char *name, const char *mode)
207 char *path_elm = NULL;
213 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
214 return fopen(name, mode);
216 /* search relative files in the path */
217 xbt_dynar_foreach(surf_path, cpt, path_elm) {
218 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
219 file = fopen(buff, mode);
231 static const char *disk_drives_letter_table[MAX_DRIVE] = {
232 "A:\\","B:\\","C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\",
233 "N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"
238 * Returns the initial path. On Windows the initial path is
239 * the current directory for the current process in the other
240 * case the function returns "./" that represents the current
241 * directory on Unix/Linux platforms.
244 const char *__surf_get_initial_path(void)
249 char current_directory[MAX_PATH + 1] = { 0 };
250 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
251 char root[4] = { 0 };
256 strncpy(root, current_directory, 3);
258 for (i = 0; i < MAX_DRIVE; i++) {
259 if (toupper(root[0]) == disk_drives_letter_table[i][0])
260 return disk_drives_letter_table[i];
269 /* The __surf_is_absolute_file_path() returns 1 if
270 * file_path is a absolute file path, in the other
271 * case the function returns 0.
273 int __surf_is_absolute_file_path(const char *file_path)
276 WIN32_FIND_DATA wfd = { 0 };
277 HANDLE hFile = FindFirstFile(file_path, &wfd);
279 if (INVALID_HANDLE_VALUE == hFile)
285 return (file_path[0] == '/');
289 /** Displays the long description of all registered models, and quit */
290 void model_help(const char *category, s_surf_model_description_t * table)
293 printf("Long description of the %s models accepted by this simulator:\n",
295 for (i = 0; table[i].name; i++)
296 printf(" %s: %s\n", table[i].name, table[i].description);
299 int find_model_description(s_surf_model_description_t * table,
303 char *name_list = NULL;
305 for (i = 0; table[i].name; i++)
306 if (!strcmp(name, table[i].name)) {
310 xbt_die("No model is valid! This is a bug.");
311 name_list = xbt_strdup(table[0].name);
312 for (i = 1; table[i].name; i++) {
313 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
314 strcat(name_list, ", ");
315 strcat(name_list, table[i].name);
317 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
321 static XBT_INLINE void routing_asr_prop_free(void *p)
323 //xbt_dict_t elm = (xbt_dict_t) p;
324 //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster
327 static XBT_INLINE void surf_host_free(void *r)
329 delete static_cast<Host*>(r);
332 static XBT_INLINE void surf_storage_free(void *r)
334 delete static_cast<Storage*>(r);
337 void sg_version_check(int lib_version_major,int lib_version_minor,int lib_version_patch) {
338 if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) {
340 "FATAL ERROR: Your program was compiled with SimGrid version %d.%d.%d, "
341 "and then linked against SimGrid %d.%d.%d. Please fix this.\n",
342 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
343 lib_version_major,lib_version_minor,lib_version_patch);
346 if (lib_version_patch != SIMGRID_VERSION_PATCH) {
348 "Warning: Your program was compiled with SimGrid version %d.%d.%d, "
349 "and then linked against SimGrid %d.%d.%d. Proceeding anyway.\n",
350 SIMGRID_VERSION_MAJOR,SIMGRID_VERSION_MINOR,SIMGRID_VERSION_PATCH,
351 lib_version_major,lib_version_minor,lib_version_patch);
355 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
356 *ver_major = SIMGRID_VERSION_MAJOR;
357 *ver_minor = SIMGRID_VERSION_MINOR;
358 *ver_patch = SIMGRID_VERSION_PATCH;
361 void surf_init(int *argc, char **argv)
363 XBT_DEBUG("Create all Libs");
364 host_lib = xbt_lib_new();
365 as_router_lib = xbt_lib_new();
366 storage_lib = xbt_lib_new();
367 storage_type_lib = xbt_lib_new();
368 file_lib = xbt_lib_new();
369 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
373 XBT_DEBUG("Add routing levels");
374 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
376 XBT_DEBUG("Add SURF levels");
377 SURF_HOST_LEVEL = xbt_lib_add_level(host_lib,surf_host_free);
378 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
380 xbt_init(argc, argv);
382 model_list = xbt_dynar_new(sizeof(Model*), NULL);
383 if (!model_list_invoke)
384 model_list_invoke = xbt_dynar_new(sizeof(Model*), NULL);
386 history = tmgr_history_new();
388 TRACE_add_start_function(TRACE_surf_alloc);
389 TRACE_add_end_function(TRACE_surf_release);
391 sg_config_init(argc, argv);
402 TRACE_end(); /* Just in case it was not called by the upper
403 * layer (or there is no upper layer) */
405 sg_config_finalize();
407 xbt_dynar_free(&host_that_restart);
408 xbt_dynar_free(&surf_path);
410 xbt_lib_free(&host_lib);
411 xbt_lib_free(&as_router_lib);
412 xbt_lib_free(&storage_lib);
414 xbt_lib_free(&storage_type_lib);
415 xbt_lib_free(&file_lib);
416 xbt_dict_free(&watched_hosts_lib);
418 xbt_dynar_foreach(model_list, iter, model)
420 xbt_dynar_free(&model_list);
421 xbt_dynar_free(&model_list_invoke);
424 surf_callback_emit(surfExitCallbacks);
427 lmm_system_free(maxmin_system);
428 maxmin_system = NULL;
431 tmgr_history_free(history);
435 #ifdef CONTEXT_THREADS
436 xbt_parmap_destroy(surf_parmap);
440 surf_parse_lex_destroy();
441 surf_parse_free_callbacks();
443 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
451 : p_maxminSystem(NULL)
453 p_readyActionSet = new ActionList();
454 p_runningActionSet = new ActionList();
455 p_failedActionSet = new ActionList();
456 p_doneActionSet = new ActionList();
458 p_modifiedSet = NULL;
460 p_updateMechanism = UM_UNDEFINED;
461 m_selectiveUpdate = 0;
465 delete p_readyActionSet;
466 delete p_runningActionSet;
467 delete p_failedActionSet;
468 delete p_doneActionSet;
471 double Model::shareResources(double now)
473 //FIXME: set the good function once and for all
474 if (p_updateMechanism == UM_LAZY)
475 return shareResourcesLazy(now);
476 else if (p_updateMechanism == UM_FULL)
477 return shareResourcesFull(now);
479 xbt_die("Invalid cpu update mechanism!");
482 double Model::shareResourcesLazy(double now)
484 Action *action = NULL;
489 ("Before share resources, the size of modified actions set is %zd",
490 p_modifiedSet->size());
492 lmm_solve(p_maxminSystem);
495 ("After share resources, The size of modified actions set is %zd",
496 p_modifiedSet->size());
498 while(!p_modifiedSet->empty()) {
499 action = &(p_modifiedSet->front());
500 p_modifiedSet->pop_front();
501 int max_dur_flag = 0;
503 if (action->getStateSet() != p_runningActionSet)
506 /* bogus priority, skip it */
507 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
510 action->updateRemainingLazy(now);
513 share = lmm_variable_getvalue(action->getVariable());
516 double time_to_completion;
517 if (action->getRemains() > 0) {
518 time_to_completion = action->getRemainsNoUpdate() / share;
520 time_to_completion = 0.0;
522 min = now + time_to_completion; // when the task will complete if nothing changes
525 if ((action->getMaxDuration() != NO_MAX_DURATION)
527 || action->getStartTime() +
528 action->getMaxDuration() < min)) {
529 min = action->getStartTime() +
530 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
535 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
537 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
538 action->getStartTime(), min, share,
539 action->getMaxDuration());
542 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
543 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
545 } else DIE_IMPOSSIBLE;
548 //hereafter must have already the min value for this resource model
549 if (xbt_heap_size(p_actionHeap) > 0)
550 min = xbt_heap_maxkey(p_actionHeap) - now;
554 XBT_DEBUG("The minimum with the HEAP %f", min);
559 double Model::shareResourcesFull(double /*now*/) {
563 double Model::shareResourcesMaxMin(ActionList *running_actions,
565 void (*solve) (lmm_system_t))
567 Action *action = NULL;
573 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
574 for(; it != itend ; ++it) {
576 value = lmm_variable_getvalue(action->getVariable());
577 if ((value > 0) || (action->getMaxDuration() >= 0))
585 if (action->getRemains() > 0)
586 min = action->getRemainsNoUpdate() / value;
589 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
590 min = action->getMaxDuration();
592 min = action->getMaxDuration();
595 for (++it; it != itend; ++it) {
597 value = lmm_variable_getvalue(action->getVariable());
599 if (action->getRemains() > 0)
600 value = action->getRemainsNoUpdate() / value;
605 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
608 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
609 min = action->getMaxDuration();
610 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
613 XBT_DEBUG("min value : %f", min);
618 void Model::updateActionsState(double now, double delta)
620 if (p_updateMechanism == UM_FULL)
621 updateActionsStateFull(now, delta);
622 else if (p_updateMechanism == UM_LAZY)
623 updateActionsStateLazy(now, delta);
625 xbt_die("Invalid cpu update mechanism!");
628 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
633 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
643 : p_name(NULL), p_properties(NULL), p_model(NULL)
646 Resource::Resource(Model *model, const char *name, xbt_dict_t props)
647 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
648 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
651 Resource::Resource(Model *model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
652 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
653 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON), p_constraint(constraint)
656 Resource::Resource(Model *model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
657 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
658 , m_running(true), m_stateCurrent(stateInit)
661 Resource::~Resource() {
662 xbt_free((void*)p_name);
663 xbt_dict_free(&p_properties);
666 e_surf_resource_state_t Resource::getState()
668 return m_stateCurrent;
671 void Resource::setState(e_surf_resource_state_t state)
673 m_stateCurrent = state;
676 bool Resource::isOn()
681 void Resource::turnOn()
688 void Resource::turnOff()
695 Model *Resource::getModel() {
699 const char *Resource::getName() {
703 xbt_dict_t Resource::getProperties() {
704 if (p_properties==NULL)
705 p_properties = xbt_dict_new();
709 lmm_constraint_t Resource::getConstraint() {
717 const char *surf_action_state_names[6] = {
719 "SURF_ACTION_RUNNING",
720 "SURF_ACTION_FAILED",
722 "SURF_ACTION_TO_FREE",
723 "SURF_ACTION_NOT_IN_THE_SYSTEM"
726 void Action::initialize(Model *model, double cost, bool failed,
732 m_maxDuration = NO_MAX_DURATION;
734 m_start = surf_get_clock();
744 p_stateHookup.prev = 0;
745 p_stateHookup.next = 0;
747 p_stateSet = getModel()->getFailedActionSet();
749 p_stateSet = getModel()->getRunningActionSet();
751 p_stateSet->push_back(*this);
754 Action::Action(Model *model, double cost, bool failed)
756 initialize(model, cost, failed);
759 Action::Action(Model *model, double cost, bool failed, lmm_variable_t var)
761 initialize(model, cost, failed, var);
765 xbt_free(p_category);
768 void Action::finish() {
769 m_finish = surf_get_clock();
772 e_surf_action_state_t Action::getState()
774 if (p_stateSet == getModel()->getReadyActionSet())
775 return SURF_ACTION_READY;
776 if (p_stateSet == getModel()->getRunningActionSet())
777 return SURF_ACTION_RUNNING;
778 if (p_stateSet == getModel()->getFailedActionSet())
779 return SURF_ACTION_FAILED;
780 if (p_stateSet == getModel()->getDoneActionSet())
781 return SURF_ACTION_DONE;
782 return SURF_ACTION_NOT_IN_THE_SYSTEM;
785 void Action::setState(e_surf_action_state_t state)
787 //surf_action_state_t action_state = &(action->model_type->states);
788 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
789 p_stateSet->erase(p_stateSet->iterator_to(*this));
790 if (state == SURF_ACTION_READY)
791 p_stateSet = getModel()->getReadyActionSet();
792 else if (state == SURF_ACTION_RUNNING)
793 p_stateSet = getModel()->getRunningActionSet();
794 else if (state == SURF_ACTION_FAILED)
795 p_stateSet = getModel()->getFailedActionSet();
796 else if (state == SURF_ACTION_DONE)
797 p_stateSet = getModel()->getDoneActionSet();
802 p_stateSet->push_back(*this);
806 double Action::getBound()
808 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
811 void Action::setBound(double bound)
813 XBT_IN("(%p,%g)", this, bound);
815 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
817 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
818 heapRemove(getModel()->getActionHeap());
822 double Action::getStartTime()
827 double Action::getFinishTime()
829 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
830 return m_remains == 0 ? m_finish : -1;
833 void Action::setData(void* data)
838 void Action::setCategory(const char *category)
840 XBT_IN("(%p,%s)", this, category);
841 p_category = xbt_strdup(category);
849 void Action::setMaxDuration(double duration)
851 XBT_IN("(%p,%g)", this, duration);
852 m_maxDuration = duration;
853 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
854 heapRemove(getModel()->getActionHeap());
858 void Action::gapRemove() {}
860 void Action::setPriority(double priority)
862 XBT_IN("(%p,%g)", this, priority);
863 m_priority = priority;
864 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
866 if (getModel()->getUpdateMechanism() == UM_LAZY)
867 heapRemove(getModel()->getActionHeap());
871 void Action::cancel(){
872 setState(SURF_ACTION_FAILED);
873 if (getModel()->getUpdateMechanism() == UM_LAZY) {
874 if (action_lmm_hook.is_linked())
875 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
876 heapRemove(getModel()->getActionHeap());
883 if (action_hook.is_linked())
884 p_stateSet->erase(p_stateSet->iterator_to(*this));
886 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
887 if (getModel()->getUpdateMechanism() == UM_LAZY) {
888 /* remove from heap */
889 heapRemove(getModel()->getActionHeap());
890 if (action_lmm_hook.is_linked())
891 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
899 void Action::suspend()
901 XBT_IN("(%p)", this);
902 if (m_suspended != 2) {
903 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
905 if (getModel()->getUpdateMechanism() == UM_LAZY)
906 heapRemove(getModel()->getActionHeap());
911 void Action::resume()
913 XBT_IN("(%p)", this);
914 if (m_suspended != 2) {
915 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
917 if (getModel()->getUpdateMechanism() == UM_LAZY)
918 heapRemove(getModel()->getActionHeap());
923 bool Action::isSuspended()
925 return m_suspended == 1;
927 /* insert action on heap using a given key and a hat (heap_action_type)
928 * a hat can be of three types for communications:
930 * NORMAL = this is a normal heap entry stating the date to finish transmitting
931 * LATENCY = this is a heap entry to warn us when the latency is payed
932 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
934 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
937 xbt_heap_push(heap, this, key);
940 void Action::heapRemove(xbt_heap_t heap)
943 if (m_indexHeap >= 0) {
944 xbt_heap_remove(heap, m_indexHeap);
948 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
951 if (m_indexHeap >= 0) {
952 xbt_heap_update(heap, m_indexHeap, key);
954 xbt_heap_push(heap, this, key);
958 /* added to manage the communication action's heap */
959 void surf_action_lmm_update_index_heap(void *action, int i) {
960 static_cast<Action*>(action)->updateIndexHeap(i);
963 void Action::updateIndexHeap(int i) {
967 double Action::getRemains()
969 XBT_IN("(%p)", this);
970 /* update remains before return it */
971 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
972 updateRemainingLazy(surf_get_clock());
977 double Action::getRemainsNoUpdate()
982 //FIXME split code in the right places
983 void Action::updateRemainingLazy(double now)
987 if(getModel() == surf_network_model)
989 if (m_suspended != 0)
994 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
995 "You're updating an action that is not running.");
997 /* bogus priority, skip it */
998 xbt_assert(m_priority > 0,
999 "You're updating an action that seems suspended.");
1002 delta = now - m_lastUpdate;
1004 if (m_remains > 0) {
1005 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1006 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
1008 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
1009 Resource *cpu = static_cast<Resource*>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
1010 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1012 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1015 if(getModel() == surf_network_model)
1017 if (m_maxDuration != NO_MAX_DURATION)
1018 double_update(&m_maxDuration, delta, sg_surf_precision);
1020 //FIXME: duplicated code
1021 if ((m_remains <= 0) &&
1022 (lmm_get_variable_weight(getVariable()) > 0)) {
1024 setState(SURF_ACTION_DONE);
1025 heapRemove(getModel()->getActionHeap());
1026 } else if (((m_maxDuration != NO_MAX_DURATION)
1027 && (m_maxDuration <= 0))) {
1029 setState(SURF_ACTION_DONE);
1030 heapRemove(getModel()->getActionHeap());
1035 m_lastValue = lmm_variable_getvalue(getVariable());