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 */
197 double *surf_mins = NULL; /* return value of share_resources for each model */
198 int surf_min_index; /* current index in surf_mins */
199 double surf_min; /* duration determined by surf_solve */
201 double surf_get_clock(void)
207 # define FILE_DELIM "\\"
209 # define FILE_DELIM "/" /* FIXME: move to better location */
212 FILE *surf_fopen(const char *name, const char *mode)
215 char *path_elm = NULL;
221 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
222 return fopen(name, mode);
224 /* search relative files in the path */
225 xbt_dynar_foreach(surf_path, cpt, path_elm) {
226 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
227 file = fopen(buff, mode);
239 static const char *disk_drives_letter_table[MAX_DRIVE] = {
240 "A:\\","B:\\","C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\",
241 "N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"
246 * Returns the initial path. On Windows the initial path is
247 * the current directory for the current process in the other
248 * case the function returns "./" that represents the current
249 * directory on Unix/Linux platforms.
252 const char *__surf_get_initial_path(void)
257 char current_directory[MAX_PATH + 1] = { 0 };
258 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
259 char root[4] = { 0 };
264 strncpy(root, current_directory, 3);
266 for (i = 0; i < MAX_DRIVE; i++) {
267 if (toupper(root[0]) == disk_drives_letter_table[i][0])
268 return disk_drives_letter_table[i];
277 /* The __surf_is_absolute_file_path() returns 1 if
278 * file_path is a absolute file path, in the other
279 * case the function returns 0.
281 int __surf_is_absolute_file_path(const char *file_path)
284 WIN32_FIND_DATA wfd = { 0 };
285 HANDLE hFile = FindFirstFile(file_path, &wfd);
287 if (INVALID_HANDLE_VALUE == hFile)
293 return (file_path[0] == '/');
297 /** Displays the long description of all registered models, and quit */
298 void model_help(const char *category, s_surf_model_description_t * table)
301 printf("Long description of the %s models accepted by this simulator:\n",
303 for (i = 0; table[i].name; i++)
304 printf(" %s: %s\n", table[i].name, table[i].description);
307 int find_model_description(s_surf_model_description_t * table,
311 char *name_list = NULL;
313 for (i = 0; table[i].name; i++)
314 if (!strcmp(name, table[i].name)) {
318 xbt_die("No model is valid! This is a bug.");
319 name_list = xbt_strdup(table[0].name);
320 for (i = 1; table[i].name; i++) {
321 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
322 strcat(name_list, ", ");
323 strcat(name_list, table[i].name);
325 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
329 static XBT_INLINE void routing_asr_prop_free(void *p)
331 //xbt_dict_t elm = (xbt_dict_t) p;
332 //xbt_dict_free(&elm); FIXME: leaking in some case? That's a sometimes double-free with AsCluster::~AsCluster
335 static XBT_INLINE void surf_host_free(void *r)
337 delete static_cast<Host*>(r);
340 static XBT_INLINE void surf_storage_free(void *r)
342 delete static_cast<Storage*>(r);
346 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
347 *ver_major = SIMGRID_VERSION_MAJOR;
348 *ver_minor = SIMGRID_VERSION_MINOR;
349 *ver_patch = SIMGRID_VERSION_PATCH;
352 void surf_init(int *argc, char **argv)
354 XBT_DEBUG("Create all Libs");
355 host_lib = xbt_lib_new();
356 as_router_lib = xbt_lib_new();
357 storage_lib = xbt_lib_new();
358 storage_type_lib = xbt_lib_new();
359 file_lib = xbt_lib_new();
360 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
364 XBT_DEBUG("Add routing levels");
365 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
367 XBT_DEBUG("Add SURF levels");
368 SURF_HOST_LEVEL = xbt_lib_add_level(host_lib,surf_host_free);
369 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
371 xbt_init(argc, argv);
373 model_list = xbt_dynar_new(sizeof(Model*), NULL);
374 if (!model_list_invoke)
375 model_list_invoke = xbt_dynar_new(sizeof(Model*), NULL);
377 history = tmgr_history_new();
379 TRACE_add_start_function(TRACE_surf_alloc);
380 TRACE_add_end_function(TRACE_surf_release);
382 sg_config_init(argc, argv);
393 TRACE_end(); /* Just in case it was not called by the upper
394 * layer (or there is no upper layer) */
396 sg_config_finalize();
398 xbt_dynar_free(&host_that_restart);
399 xbt_dynar_free(&surf_path);
401 xbt_lib_free(&host_lib);
402 xbt_lib_free(&as_router_lib);
403 xbt_lib_free(&storage_lib);
405 xbt_lib_free(&storage_type_lib);
406 xbt_lib_free(&file_lib);
407 xbt_dict_free(&watched_hosts_lib);
409 xbt_dynar_foreach(model_list, iter, model)
411 xbt_dynar_free(&model_list);
412 xbt_dynar_free(&model_list_invoke);
415 surf_callback_emit(surfExitCallbacks);
418 lmm_system_free(maxmin_system);
419 maxmin_system = NULL;
422 tmgr_history_free(history);
426 #ifdef CONTEXT_THREADS
427 xbt_parmap_destroy(surf_parmap);
434 surf_parse_lex_destroy();
435 surf_parse_free_callbacks();
437 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
444 Model::Model(const char *name)
445 : p_maxminSystem(NULL)
448 p_readyActionSet = new ActionList();
449 p_runningActionSet = new ActionList();
450 p_failedActionSet = new ActionList();
451 p_doneActionSet = new ActionList();
453 p_modifiedSet = NULL;
455 p_updateMechanism = UM_UNDEFINED;
456 m_selectiveUpdate = 0;
460 delete p_readyActionSet;
461 delete p_runningActionSet;
462 delete p_failedActionSet;
463 delete p_doneActionSet;
466 double Model::shareResources(double now)
468 //FIXME: set the good function once and for all
469 if (p_updateMechanism == UM_LAZY)
470 return shareResourcesLazy(now);
471 else if (p_updateMechanism == UM_FULL)
472 return shareResourcesFull(now);
474 xbt_die("Invalid cpu update mechanism!");
477 double Model::shareResourcesLazy(double now)
479 Action *action = NULL;
484 ("Before share resources, the size of modified actions set is %zd",
485 p_modifiedSet->size());
487 lmm_solve(p_maxminSystem);
490 ("After share resources, The size of modified actions set is %zd",
491 p_modifiedSet->size());
493 while(!p_modifiedSet->empty()) {
494 action = &(p_modifiedSet->front());
495 p_modifiedSet->pop_front();
496 int max_dur_flag = 0;
498 if (action->getStateSet() != p_runningActionSet)
501 /* bogus priority, skip it */
502 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
505 action->updateRemainingLazy(now);
508 share = lmm_variable_getvalue(action->getVariable());
511 double time_to_completion;
512 if (action->getRemains() > 0) {
513 time_to_completion = action->getRemainsNoUpdate() / share;
515 time_to_completion = 0.0;
517 min = now + time_to_completion; // when the task will complete if nothing changes
520 if ((action->getMaxDuration() != NO_MAX_DURATION)
522 || action->getStartTime() +
523 action->getMaxDuration() < min)) {
524 min = action->getStartTime() +
525 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
530 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
532 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
533 action->getStartTime(), min, share,
534 action->getMaxDuration());
537 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
538 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
540 } else DIE_IMPOSSIBLE;
543 //hereafter must have already the min value for this resource model
544 if (xbt_heap_size(p_actionHeap) > 0)
545 min = xbt_heap_maxkey(p_actionHeap) - now;
549 XBT_DEBUG("The minimum with the HEAP %f", min);
554 double Model::shareResourcesFull(double /*now*/) {
558 double Model::shareResourcesMaxMin(ActionList *running_actions,
560 void (*solve) (lmm_system_t))
562 Action *action = NULL;
568 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
569 for(; it != itend ; ++it) {
571 value = lmm_variable_getvalue(action->getVariable());
572 if ((value > 0) || (action->getMaxDuration() >= 0))
580 if (action->getRemains() > 0)
581 min = action->getRemainsNoUpdate() / value;
584 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
585 min = action->getMaxDuration();
587 min = action->getMaxDuration();
590 for (++it; it != itend; ++it) {
592 value = lmm_variable_getvalue(action->getVariable());
594 if (action->getRemains() > 0)
595 value = action->getRemainsNoUpdate() / value;
600 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
603 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
604 min = action->getMaxDuration();
605 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
608 XBT_DEBUG("min value : %f", min);
613 void Model::updateActionsState(double now, double delta)
615 if (p_updateMechanism == UM_FULL)
616 updateActionsStateFull(now, delta);
617 else if (p_updateMechanism == UM_LAZY)
618 updateActionsStateLazy(now, delta);
620 xbt_die("Invalid cpu update mechanism!");
623 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
628 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
638 : p_name(NULL), p_properties(NULL), p_model(NULL)
641 Resource::Resource(Model *model, const char *name, xbt_dict_t props)
642 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
643 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
646 Resource::Resource(Model *model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
647 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
648 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON), p_constraint(constraint)
651 Resource::Resource(Model *model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
652 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
653 , m_running(true), m_stateCurrent(stateInit)
656 Resource::~Resource() {
657 xbt_free((void*)p_name);
658 xbt_dict_free(&p_properties);
661 e_surf_resource_state_t Resource::getState()
663 return m_stateCurrent;
666 void Resource::setState(e_surf_resource_state_t state)
668 m_stateCurrent = state;
671 bool Resource::isOn()
676 void Resource::turnOn()
683 void Resource::turnOff()
690 Model *Resource::getModel() {
694 const char *Resource::getName() {
698 xbt_dict_t Resource::getProperties() {
699 if (p_properties==NULL)
700 p_properties = xbt_dict_new();
704 lmm_constraint_t Resource::getConstraint() {
712 const char *surf_action_state_names[6] = {
714 "SURF_ACTION_RUNNING",
715 "SURF_ACTION_FAILED",
717 "SURF_ACTION_TO_FREE",
718 "SURF_ACTION_NOT_IN_THE_SYSTEM"
721 void Action::initialize(Model *model, double cost, bool failed,
727 m_maxDuration = NO_MAX_DURATION;
730 m_start = surf_get_clock();
741 Action::Action(Model *model, double cost, bool failed)
743 initialize(model, cost, failed);
745 p_stateHookup.prev = 0;
746 p_stateHookup.next = 0;
748 p_stateSet = getModel()->getFailedActionSet();
750 p_stateSet = getModel()->getRunningActionSet();
752 p_stateSet->push_back(*this);
755 Action::Action(Model *model, double cost, bool failed, lmm_variable_t var)
757 initialize(model, cost, failed, var);
759 p_stateHookup.prev = 0;
760 p_stateHookup.next = 0;
762 p_stateSet = getModel()->getFailedActionSet();
764 p_stateSet = getModel()->getRunningActionSet();
766 p_stateSet->push_back(*this);
770 xbt_free(p_category);
773 void Action::finish() {
774 m_finish = surf_get_clock();
777 e_surf_action_state_t Action::getState()
779 if (p_stateSet == getModel()->getReadyActionSet())
780 return SURF_ACTION_READY;
781 if (p_stateSet == getModel()->getRunningActionSet())
782 return SURF_ACTION_RUNNING;
783 if (p_stateSet == getModel()->getFailedActionSet())
784 return SURF_ACTION_FAILED;
785 if (p_stateSet == getModel()->getDoneActionSet())
786 return SURF_ACTION_DONE;
787 return SURF_ACTION_NOT_IN_THE_SYSTEM;
790 void Action::setState(e_surf_action_state_t state)
792 //surf_action_state_t action_state = &(action->model_type->states);
793 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
794 p_stateSet->erase(p_stateSet->iterator_to(*this));
795 if (state == SURF_ACTION_READY)
796 p_stateSet = getModel()->getReadyActionSet();
797 else if (state == SURF_ACTION_RUNNING)
798 p_stateSet = getModel()->getRunningActionSet();
799 else if (state == SURF_ACTION_FAILED)
800 p_stateSet = getModel()->getFailedActionSet();
801 else if (state == SURF_ACTION_DONE)
802 p_stateSet = getModel()->getDoneActionSet();
807 p_stateSet->push_back(*this);
811 double Action::getBound()
813 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
816 void Action::setBound(double bound)
818 XBT_IN("(%p,%g)", this, bound);
820 lmm_update_variable_bound(getModel()->getMaxminSystem(), p_variable, bound);
822 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
823 heapRemove(getModel()->getActionHeap());
827 double Action::getStartTime()
832 double Action::getFinishTime()
834 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
835 return m_remains == 0 ? m_finish : -1;
838 void Action::setData(void* data)
843 void Action::setCategory(const char *category)
845 XBT_IN("(%p,%s)", this, category);
846 p_category = xbt_strdup(category);
854 void Action::setMaxDuration(double duration)
856 XBT_IN("(%p,%g)", this, duration);
857 m_maxDuration = duration;
858 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
859 heapRemove(getModel()->getActionHeap());
863 void Action::gapRemove() {}
865 void Action::setPriority(double priority)
867 XBT_IN("(%p,%g)", this, priority);
868 m_priority = priority;
869 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
871 if (getModel()->getUpdateMechanism() == UM_LAZY)
872 heapRemove(getModel()->getActionHeap());
876 void Action::cancel(){
877 setState(SURF_ACTION_FAILED);
878 if (getModel()->getUpdateMechanism() == UM_LAZY) {
879 if (actionLmmHook::is_linked())
880 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
881 heapRemove(getModel()->getActionHeap());
888 if (actionHook::is_linked())
889 p_stateSet->erase(p_stateSet->iterator_to(*this));
891 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
892 if (getModel()->getUpdateMechanism() == UM_LAZY) {
893 /* remove from heap */
894 heapRemove(getModel()->getActionHeap());
895 if (actionLmmHook::is_linked())
896 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
904 void Action::suspend()
906 XBT_IN("(%p)", this);
907 if (m_suspended != 2) {
908 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
910 if (getModel()->getUpdateMechanism() == UM_LAZY)
911 heapRemove(getModel()->getActionHeap());
916 void Action::resume()
918 XBT_IN("(%p)", this);
919 if (m_suspended != 2) {
920 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
922 if (getModel()->getUpdateMechanism() == UM_LAZY)
923 heapRemove(getModel()->getActionHeap());
928 bool Action::isSuspended()
930 return m_suspended == 1;
932 /* insert action on heap using a given key and a hat (heap_action_type)
933 * a hat can be of three types for communications:
935 * NORMAL = this is a normal heap entry stating the date to finish transmitting
936 * LATENCY = this is a heap entry to warn us when the latency is payed
937 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
939 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
942 xbt_heap_push(heap, this, key);
945 void Action::heapRemove(xbt_heap_t heap)
948 if (m_indexHeap >= 0) {
949 xbt_heap_remove(heap, m_indexHeap);
953 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
956 if (m_indexHeap >= 0) {
957 xbt_heap_update(heap, m_indexHeap, key);
959 xbt_heap_push(heap, this, key);
963 /* added to manage the communication action's heap */
964 void surf_action_lmm_update_index_heap(void *action, int i) {
965 static_cast<Action*>(action)->updateIndexHeap(i);
968 void Action::updateIndexHeap(int i) {
972 double Action::getRemains()
974 XBT_IN("(%p)", this);
975 /* update remains before return it */
976 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
977 updateRemainingLazy(surf_get_clock());
982 double Action::getRemainsNoUpdate()
987 //FIXME split code in the right places
988 void Action::updateRemainingLazy(double now)
992 if(getModel() == surf_network_model)
994 if (m_suspended != 0)
999 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
1000 "You're updating an action that is not running.");
1002 /* bogus priority, skip it */
1003 xbt_assert(m_priority > 0,
1004 "You're updating an action that seems suspended.");
1007 delta = now - m_lastUpdate;
1009 if (m_remains > 0) {
1010 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1011 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
1013 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
1014 Resource *cpu = static_cast<Resource*>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
1015 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1017 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1020 if(getModel() == surf_network_model)
1022 if (m_maxDuration != NO_MAX_DURATION)
1023 double_update(&m_maxDuration, delta, sg_surf_precision);
1025 //FIXME: duplicated code
1026 if ((m_remains <= 0) &&
1027 (lmm_get_variable_weight(getVariable()) > 0)) {
1029 setState(SURF_ACTION_DONE);
1030 heapRemove(getModel()->getActionHeap());
1031 } else if (((m_maxDuration != NO_MAX_DURATION)
1032 && (m_maxDuration <= 0))) {
1034 setState(SURF_ACTION_DONE);
1035 heapRemove(getModel()->getActionHeap());
1040 m_lastValue = lmm_variable_getvalue(getVariable());