1 /* Copyright (c) 2004-2014. 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 GTNets simulator instead of an analytic model",
127 surf_network_model_init_GTNETS},
131 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
132 surf_network_model_init_NS3},
135 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
136 surf_network_model_init_Reno},
138 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
139 surf_network_model_init_Reno2},
141 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
142 surf_network_model_init_Vegas},
143 {NULL, NULL, NULL} /* this array must be NULL terminated */
146 s_surf_model_description_t surf_cpu_model_description[] = {
148 "Simplistic CPU model (time=size/power).",
149 surf_cpu_model_init_Cas01},
150 {NULL, NULL, NULL} /* this array must be NULL terminated */
153 s_surf_model_description_t surf_host_model_description[] = {
155 "Default host model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
156 surf_host_model_init_current_default},
158 "Host model that is automatically chosen if you change the network and CPU models",
159 surf_host_model_init_compound},
160 {"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks",
161 surf_host_model_init_ptask_L07},
162 {NULL, NULL, NULL} /* this array must be NULL terminated */
165 s_surf_model_description_t surf_vm_model_description[] = {
168 surf_vm_model_init_HL13},
169 {NULL, NULL, NULL} /* this array must be NULL terminated */
172 s_surf_model_description_t surf_optimization_mode_description[] = {
174 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
177 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
180 "Full update of remaining and variables. Slow but may be useful when debugging.",
182 {NULL, NULL, NULL} /* this array must be NULL terminated */
185 s_surf_model_description_t surf_storage_model_description[] = {
187 "Simplistic storage model.",
188 surf_storage_model_init_default},
189 {NULL, NULL, NULL} /* this array must be NULL terminated */
192 #ifdef CONTEXT_THREADS
193 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
198 double surf_get_clock(void)
204 # define FILE_DELIM "\\"
206 # define FILE_DELIM "/" /* FIXME: move to better location */
209 FILE *surf_fopen(const char *name, const char *mode)
212 char *path_elm = NULL;
218 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
219 return fopen(name, mode);
221 /* search relative files in the path */
222 xbt_dynar_foreach(surf_path, cpt, path_elm) {
223 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
224 file = fopen(buff, mode);
236 static const char *disk_drives_letter_table[MAX_DRIVE] = {
237 "A:\\","B:\\","C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\",
238 "N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"
243 * Returns the initial path. On Windows the initial path is
244 * the current directory for the current process in the other
245 * case the function returns "./" that represents the current
246 * directory on Unix/Linux platforms.
249 const char *__surf_get_initial_path(void)
254 char current_directory[MAX_PATH + 1] = { 0 };
255 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
256 char root[4] = { 0 };
261 strncpy(root, current_directory, 3);
263 for (i = 0; i < MAX_DRIVE; i++) {
264 if (toupper(root[0]) == disk_drives_letter_table[i][0])
265 return disk_drives_letter_table[i];
274 /* The __surf_is_absolute_file_path() returns 1 if
275 * file_path is a absolute file path, in the other
276 * case the function returns 0.
278 int __surf_is_absolute_file_path(const char *file_path)
281 WIN32_FIND_DATA wfd = { 0 };
282 HANDLE hFile = FindFirstFile(file_path, &wfd);
284 if (INVALID_HANDLE_VALUE == hFile)
290 return (file_path[0] == '/');
294 /** Displays the long description of all registered models, and quit */
295 void model_help(const char *category, s_surf_model_description_t * table)
298 printf("Long description of the %s models accepted by this simulator:\n",
300 for (i = 0; table[i].name; i++)
301 printf(" %s: %s\n", table[i].name, table[i].description);
304 int find_model_description(s_surf_model_description_t * table,
308 char *name_list = NULL;
310 for (i = 0; table[i].name; i++)
311 if (!strcmp(name, table[i].name)) {
315 xbt_die("No model is valid! This is a bug.");
316 name_list = xbt_strdup(table[0].name);
317 for (i = 1; table[i].name; i++) {
318 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
319 strcat(name_list, ", ");
320 strcat(name_list, table[i].name);
322 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
326 static XBT_INLINE void routing_asr_prop_free(void *p)
328 //xbt_dict_t elm = (xbt_dict_t) p;
329 //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster
332 static XBT_INLINE void surf_host_free(void *r)
334 delete static_cast<Host*>(r);
337 static XBT_INLINE void surf_storage_free(void *r)
339 delete static_cast<Storage*>(r);
343 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
344 *ver_major = SIMGRID_VERSION_MAJOR;
345 *ver_minor = SIMGRID_VERSION_MINOR;
346 *ver_patch = SIMGRID_VERSION_PATCH;
349 void surf_init(int *argc, char **argv)
351 XBT_DEBUG("Create all Libs");
352 host_lib = xbt_lib_new();
353 as_router_lib = xbt_lib_new();
354 storage_lib = xbt_lib_new();
355 storage_type_lib = xbt_lib_new();
356 file_lib = xbt_lib_new();
357 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
361 XBT_DEBUG("Add routing levels");
362 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
364 XBT_DEBUG("Add SURF levels");
365 SURF_HOST_LEVEL = xbt_lib_add_level(host_lib,surf_host_free);
366 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
368 xbt_init(argc, argv);
370 model_list = xbt_dynar_new(sizeof(Model*), NULL);
371 if (!model_list_invoke)
372 model_list_invoke = xbt_dynar_new(sizeof(Model*), NULL);
374 history = tmgr_history_new();
376 TRACE_add_start_function(TRACE_surf_alloc);
377 TRACE_add_end_function(TRACE_surf_release);
379 sg_config_init(argc, argv);
390 TRACE_end(); /* Just in case it was not called by the upper
391 * layer (or there is no upper layer) */
393 sg_config_finalize();
395 xbt_dynar_free(&host_that_restart);
396 xbt_dynar_free(&surf_path);
398 xbt_lib_free(&host_lib);
399 xbt_lib_free(&as_router_lib);
400 xbt_lib_free(&storage_lib);
402 xbt_lib_free(&storage_type_lib);
403 xbt_lib_free(&file_lib);
404 xbt_dict_free(&watched_hosts_lib);
406 xbt_dynar_foreach(model_list, iter, model)
408 xbt_dynar_free(&model_list);
409 xbt_dynar_free(&model_list_invoke);
412 surf_callback_emit(surfExitCallbacks);
415 lmm_system_free(maxmin_system);
416 maxmin_system = NULL;
419 tmgr_history_free(history);
423 #ifdef CONTEXT_THREADS
424 xbt_parmap_destroy(surf_parmap);
428 surf_parse_lex_destroy();
429 surf_parse_free_callbacks();
431 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
438 Model::Model(const char *name)
439 : p_maxminSystem(NULL)
442 p_readyActionSet = new ActionList();
443 p_runningActionSet = new ActionList();
444 p_failedActionSet = new ActionList();
445 p_doneActionSet = new ActionList();
447 p_modifiedSet = NULL;
449 p_updateMechanism = UM_UNDEFINED;
450 m_selectiveUpdate = 0;
454 delete p_readyActionSet;
455 delete p_runningActionSet;
456 delete p_failedActionSet;
457 delete p_doneActionSet;
460 double Model::shareResources(double now)
462 //FIXME: set the good function once and for all
463 if (p_updateMechanism == UM_LAZY)
464 return shareResourcesLazy(now);
465 else if (p_updateMechanism == UM_FULL)
466 return shareResourcesFull(now);
468 xbt_die("Invalid cpu update mechanism!");
471 double Model::shareResourcesLazy(double now)
473 Action *action = NULL;
478 ("Before share resources, the size of modified actions set is %zd",
479 p_modifiedSet->size());
481 lmm_solve(p_maxminSystem);
484 ("After share resources, The size of modified actions set is %zd",
485 p_modifiedSet->size());
487 while(!p_modifiedSet->empty()) {
488 action = &(p_modifiedSet->front());
489 p_modifiedSet->pop_front();
490 int max_dur_flag = 0;
492 if (action->getStateSet() != p_runningActionSet)
495 /* bogus priority, skip it */
496 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
499 action->updateRemainingLazy(now);
502 share = lmm_variable_getvalue(action->getVariable());
505 double time_to_completion;
506 if (action->getRemains() > 0) {
507 time_to_completion = action->getRemainsNoUpdate() / share;
509 time_to_completion = 0.0;
511 min = now + time_to_completion; // when the task will complete if nothing changes
514 if ((action->getMaxDuration() != NO_MAX_DURATION)
516 || action->getStartTime() +
517 action->getMaxDuration() < min)) {
518 min = action->getStartTime() +
519 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
524 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
526 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
527 action->getStartTime(), min, share,
528 action->getMaxDuration());
531 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
532 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
534 } else DIE_IMPOSSIBLE;
537 //hereafter must have already the min value for this resource model
538 if (xbt_heap_size(p_actionHeap) > 0)
539 min = xbt_heap_maxkey(p_actionHeap) - now;
543 XBT_DEBUG("The minimum with the HEAP %f", min);
548 double Model::shareResourcesFull(double /*now*/) {
552 double Model::shareResourcesMaxMin(ActionList *running_actions,
554 void (*solve) (lmm_system_t))
556 Action *action = NULL;
562 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
563 for(; it != itend ; ++it) {
565 value = lmm_variable_getvalue(action->getVariable());
566 if ((value > 0) || (action->getMaxDuration() >= 0))
574 if (action->getRemains() > 0)
575 min = action->getRemainsNoUpdate() / value;
578 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
579 min = action->getMaxDuration();
581 min = action->getMaxDuration();
584 for (++it; it != itend; ++it) {
586 value = lmm_variable_getvalue(action->getVariable());
588 if (action->getRemains() > 0)
589 value = action->getRemainsNoUpdate() / value;
594 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
597 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
598 min = action->getMaxDuration();
599 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
602 XBT_DEBUG("min value : %f", min);
607 void Model::updateActionsState(double now, double delta)
609 if (p_updateMechanism == UM_FULL)
610 updateActionsStateFull(now, delta);
611 else if (p_updateMechanism == UM_LAZY)
612 updateActionsStateLazy(now, delta);
614 xbt_die("Invalid cpu update mechanism!");
617 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
622 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
632 : p_name(NULL), p_properties(NULL), p_model(NULL)
635 Resource::Resource(Model *model, const char *name, xbt_dict_t props)
636 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
637 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
640 Resource::Resource(Model *model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
641 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
642 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON), p_constraint(constraint)
645 Resource::Resource(Model *model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
646 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
647 , m_running(true), m_stateCurrent(stateInit)
650 Resource::~Resource() {
651 xbt_free((void*)p_name);
652 xbt_dict_free(&p_properties);
655 e_surf_resource_state_t Resource::getState()
657 return m_stateCurrent;
660 void Resource::setState(e_surf_resource_state_t state)
662 m_stateCurrent = state;
665 bool Resource::isOn()
670 void Resource::turnOn()
677 void Resource::turnOff()
684 Model *Resource::getModel() {
688 const char *Resource::getName() {
692 xbt_dict_t Resource::getProperties() {
693 if (p_properties==NULL)
694 p_properties = xbt_dict_new();
698 lmm_constraint_t Resource::getConstraint() {
706 const char *surf_action_state_names[6] = {
708 "SURF_ACTION_RUNNING",
709 "SURF_ACTION_FAILED",
711 "SURF_ACTION_TO_FREE",
712 "SURF_ACTION_NOT_IN_THE_SYSTEM"
715 void Action::initialize(Model *model, double cost, bool failed,
721 m_maxDuration = NO_MAX_DURATION;
724 m_start = surf_get_clock();
735 Action::Action(Model *model, double cost, bool failed)
737 initialize(model, cost, failed);
739 p_stateHookup.prev = 0;
740 p_stateHookup.next = 0;
742 p_stateSet = getModel()->getFailedActionSet();
744 p_stateSet = getModel()->getRunningActionSet();
746 p_stateSet->push_back(*this);
749 Action::Action(Model *model, double cost, bool failed, lmm_variable_t var)
751 initialize(model, cost, failed, var);
753 p_stateHookup.prev = 0;
754 p_stateHookup.next = 0;
756 p_stateSet = getModel()->getFailedActionSet();
758 p_stateSet = getModel()->getRunningActionSet();
760 p_stateSet->push_back(*this);
764 xbt_free(p_category);
767 void Action::finish() {
768 m_finish = surf_get_clock();
771 e_surf_action_state_t Action::getState()
773 if (p_stateSet == getModel()->getReadyActionSet())
774 return SURF_ACTION_READY;
775 if (p_stateSet == getModel()->getRunningActionSet())
776 return SURF_ACTION_RUNNING;
777 if (p_stateSet == getModel()->getFailedActionSet())
778 return SURF_ACTION_FAILED;
779 if (p_stateSet == getModel()->getDoneActionSet())
780 return SURF_ACTION_DONE;
781 return SURF_ACTION_NOT_IN_THE_SYSTEM;
784 void Action::setState(e_surf_action_state_t state)
786 //surf_action_state_t action_state = &(action->model_type->states);
787 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
788 p_stateSet->erase(p_stateSet->iterator_to(*this));
789 if (state == SURF_ACTION_READY)
790 p_stateSet = getModel()->getReadyActionSet();
791 else if (state == SURF_ACTION_RUNNING)
792 p_stateSet = getModel()->getRunningActionSet();
793 else if (state == SURF_ACTION_FAILED)
794 p_stateSet = getModel()->getFailedActionSet();
795 else if (state == SURF_ACTION_DONE)
796 p_stateSet = getModel()->getDoneActionSet();
801 p_stateSet->push_back(*this);
805 double Action::getBound()
807 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
810 void Action::setBound(double bound)
812 XBT_IN("(%p,%g)", this, bound);
814 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
816 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
817 heapRemove(getModel()->getActionHeap());
821 double Action::getStartTime()
826 double Action::getFinishTime()
828 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
829 return m_remains == 0 ? m_finish : -1;
832 void Action::setData(void* data)
837 void Action::setCategory(const char *category)
839 XBT_IN("(%p,%s)", this, category);
840 p_category = xbt_strdup(category);
848 void Action::setMaxDuration(double duration)
850 XBT_IN("(%p,%g)", this, duration);
851 m_maxDuration = duration;
852 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
853 heapRemove(getModel()->getActionHeap());
857 void Action::gapRemove() {}
859 void Action::setPriority(double priority)
861 XBT_IN("(%p,%g)", this, priority);
862 m_priority = priority;
863 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
865 if (getModel()->getUpdateMechanism() == UM_LAZY)
866 heapRemove(getModel()->getActionHeap());
870 void Action::cancel(){
871 setState(SURF_ACTION_FAILED);
872 if (getModel()->getUpdateMechanism() == UM_LAZY) {
873 if (actionLmmHook::is_linked())
874 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
875 heapRemove(getModel()->getActionHeap());
882 if (actionHook::is_linked())
883 p_stateSet->erase(p_stateSet->iterator_to(*this));
885 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
886 if (getModel()->getUpdateMechanism() == UM_LAZY) {
887 /* remove from heap */
888 heapRemove(getModel()->getActionHeap());
889 if (actionLmmHook::is_linked())
890 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
898 void Action::suspend()
900 XBT_IN("(%p)", this);
901 if (m_suspended != 2) {
902 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
904 if (getModel()->getUpdateMechanism() == UM_LAZY)
905 heapRemove(getModel()->getActionHeap());
910 void Action::resume()
912 XBT_IN("(%p)", this);
913 if (m_suspended != 2) {
914 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
916 if (getModel()->getUpdateMechanism() == UM_LAZY)
917 heapRemove(getModel()->getActionHeap());
922 bool Action::isSuspended()
924 return m_suspended == 1;
926 /* insert action on heap using a given key and a hat (heap_action_type)
927 * a hat can be of three types for communications:
929 * NORMAL = this is a normal heap entry stating the date to finish transmitting
930 * LATENCY = this is a heap entry to warn us when the latency is payed
931 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
933 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
936 xbt_heap_push(heap, this, key);
939 void Action::heapRemove(xbt_heap_t heap)
942 if (m_indexHeap >= 0) {
943 xbt_heap_remove(heap, m_indexHeap);
947 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
950 if (m_indexHeap >= 0) {
951 xbt_heap_update(heap, m_indexHeap, key);
953 xbt_heap_push(heap, this, key);
957 /* added to manage the communication action's heap */
958 void surf_action_lmm_update_index_heap(void *action, int i) {
959 static_cast<Action*>(action)->updateIndexHeap(i);
962 void Action::updateIndexHeap(int i) {
966 double Action::getRemains()
968 XBT_IN("(%p)", this);
969 /* update remains before return it */
970 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
971 updateRemainingLazy(surf_get_clock());
976 double Action::getRemainsNoUpdate()
981 //FIXME split code in the right places
982 void Action::updateRemainingLazy(double now)
986 if(getModel() == surf_network_model)
988 if (m_suspended != 0)
993 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
994 "You're updating an action that is not running.");
996 /* bogus priority, skip it */
997 xbt_assert(m_priority > 0,
998 "You're updating an action that seems suspended.");
1001 delta = now - m_lastUpdate;
1003 if (m_remains > 0) {
1004 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1005 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
1007 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
1008 Resource *cpu = static_cast<Resource*>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
1009 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1011 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1014 if(getModel() == surf_network_model)
1016 if (m_maxDuration != NO_MAX_DURATION)
1017 double_update(&m_maxDuration, delta, sg_surf_precision);
1019 //FIXME: duplicated code
1020 if ((m_remains <= 0) &&
1021 (lmm_get_variable_weight(getVariable()) > 0)) {
1023 setState(SURF_ACTION_DONE);
1024 heapRemove(getModel()->getActionHeap());
1025 } else if (((m_maxDuration != NO_MAX_DURATION)
1026 && (m_maxDuration <= 0))) {
1028 setState(SURF_ACTION_DONE);
1029 heapRemove(getModel()->getActionHeap());
1034 m_lastValue = lmm_variable_getvalue(getVariable());