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 "workstation_interface.hpp"
12 #include "vm_workstation_interface.hpp"
13 #include "simix/smx_host_private.h"
14 #include "surf_routing.hpp"
15 #include "simgrid/sg_config.h"
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_workstation and surf_vm_workstation.
88 * The callback functions of cpu_model and network_model will be called from
89 * those of these workstation 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[] = {
103 "Cpu energy consumption.",
104 sg_energy_plugin_init},
105 {NULL, NULL, NULL} /* this array must be NULL terminated */
108 /* Don't forget to update the option description in smx_config when you change
110 s_surf_model_description_t surf_network_model_description[] = {
112 "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). ",
113 surf_network_model_init_LegrandVelho},
115 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
116 surf_network_model_init_Constant},
118 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
119 surf_network_model_init_SMPI},
121 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
122 surf_network_model_init_CM02},
125 "Network pseudo-model using the GTNets simulator instead of an analytic model",
126 surf_network_model_init_GTNETS},
130 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
131 surf_network_model_init_NS3},
134 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
135 surf_network_model_init_Reno},
137 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
138 surf_network_model_init_Reno2},
140 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
141 surf_network_model_init_Vegas},
142 {NULL, NULL, NULL} /* this array must be NULL terminated */
145 s_surf_model_description_t surf_cpu_model_description[] = {
147 "Simplistic CPU model (time=size/power).",
148 surf_cpu_model_init_Cas01},
149 {NULL, NULL, NULL} /* this array must be NULL terminated */
152 s_surf_model_description_t surf_workstation_model_description[] = {
154 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
155 surf_workstation_model_init_current_default},
157 "Workstation model that is automatically chosen if you change the network and CPU models",
158 surf_workstation_model_init_compound},
159 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
160 surf_workstation_model_init_ptask_L07},
161 {NULL, NULL, NULL} /* this array must be NULL terminated */
164 s_surf_model_description_t surf_vm_workstation_model_description[] = {
166 "Default vm workstation model.",
167 surf_vm_workstation_model_init_HL13},
168 {NULL, NULL, NULL} /* this array must be NULL terminated */
171 s_surf_model_description_t surf_optimization_mode_description[] = {
173 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
176 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
179 "Full update of remaining and variables. Slow but may be useful when debugging.",
181 {NULL, NULL, NULL} /* this array must be NULL terminated */
184 s_surf_model_description_t surf_storage_model_description[] = {
186 "Simplistic storage model.",
187 surf_storage_model_init_default},
188 {NULL, NULL, NULL} /* this array must be NULL terminated */
191 #ifdef CONTEXT_THREADS
192 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
196 double *surf_mins = NULL; /* return value of share_resources for each model */
197 int surf_min_index; /* current index in surf_mins */
198 double surf_min; /* duration determined by surf_solve */
200 double surf_get_clock(void)
206 # define FILE_DELIM "\\"
208 # define FILE_DELIM "/" /* FIXME: move to better location */
211 FILE *surf_fopen(const char *name, const char *mode)
214 char *path_elm = NULL;
220 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
221 return fopen(name, mode);
223 /* search relative files in the path */
224 xbt_dynar_foreach(surf_path, cpt, path_elm) {
225 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
226 file = fopen(buff, mode);
242 static const char *disk_drives_letter_table[MAX_DRIVE] = {
273 * Returns the initial path. On Windows the initial path is
274 * the current directory for the current process in the other
275 * case the function returns "./" that represents the current
276 * directory on Unix/Linux platforms.
279 const char *__surf_get_initial_path(void)
284 char current_directory[MAX_PATH + 1] = { 0 };
285 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
286 char root[4] = { 0 };
291 strncpy(root, current_directory, 3);
293 for (i = 0; i < MAX_DRIVE; i++) {
294 if (toupper(root[0]) == disk_drives_letter_table[i][0])
295 return disk_drives_letter_table[i];
304 /* The __surf_is_absolute_file_path() returns 1 if
305 * file_path is a absolute file path, in the other
306 * case the function returns 0.
308 int __surf_is_absolute_file_path(const char *file_path)
311 WIN32_FIND_DATA wfd = { 0 };
312 HANDLE hFile = FindFirstFile(file_path, &wfd);
314 if (INVALID_HANDLE_VALUE == hFile)
320 return (file_path[0] == '/');
324 /** Displays the long description of all registered models, and quit */
325 void model_help(const char *category, s_surf_model_description_t * table)
328 printf("Long description of the %s models accepted by this simulator:\n",
330 for (i = 0; table[i].name; i++)
331 printf(" %s: %s\n", table[i].name, table[i].description);
334 int find_model_description(s_surf_model_description_t * table,
338 char *name_list = NULL;
340 for (i = 0; table[i].name; i++)
341 if (!strcmp(name, table[i].name)) {
345 xbt_die("No model is valid! This is a bug.");
346 name_list = xbt_strdup(table[0].name);
347 for (i = 1; table[i].name; i++) {
348 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
349 strcat(name_list, ", ");
350 strcat(name_list, table[i].name);
352 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
356 static XBT_INLINE void routing_asr_host_free(void *p)
358 delete ((RoutingEdgePtr) p);
361 static XBT_INLINE void routing_asr_prop_free(void *p)
363 xbt_dict_t elm = (xbt_dict_t) p;
367 static XBT_INLINE void surf_cpu_free(void *r)
369 delete static_cast<CpuPtr>(r);
372 static XBT_INLINE void surf_link_free(void *r)
374 delete static_cast<NetworkLinkPtr>(r);
377 static XBT_INLINE void surf_workstation_free(void *r)
379 delete static_cast<WorkstationPtr>(r);
382 static XBT_INLINE void surf_storage_free(void *r)
384 delete static_cast<StoragePtr>(r);
388 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
389 *ver_major = SIMGRID_VERSION_MAJOR;
390 *ver_minor = SIMGRID_VERSION_MINOR;
391 *ver_patch = SIMGRID_VERSION_PATCH;
394 void surf_init(int *argc, char **argv)
396 XBT_DEBUG("Create all Libs");
397 host_lib = xbt_lib_new();
398 link_lib = xbt_lib_new();
399 as_router_lib = xbt_lib_new();
400 storage_lib = xbt_lib_new();
401 storage_type_lib = xbt_lib_new();
402 file_lib = xbt_lib_new();
403 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
405 XBT_DEBUG("Add routing levels");
406 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
407 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
408 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
410 XBT_DEBUG("Add SURF levels");
411 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
412 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
413 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
414 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
416 xbt_init(argc, argv);
418 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
419 if (!model_list_invoke)
420 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
422 history = tmgr_history_new();
425 TRACE_add_start_function(TRACE_surf_alloc);
426 TRACE_add_end_function(TRACE_surf_release);
429 sg_config_init(argc, argv);
438 ModelPtr model = NULL;
441 TRACE_end(); /* Just in case it was not called by the upper
442 * layer (or there is no upper layer) */
445 sg_config_finalize();
447 xbt_dynar_free(&host_that_restart);
448 xbt_dynar_free(&surf_path);
450 xbt_lib_free(&host_lib);
451 xbt_lib_free(&link_lib);
452 xbt_lib_free(&as_router_lib);
453 xbt_lib_free(&storage_lib);
454 xbt_lib_free(&storage_type_lib);
455 xbt_lib_free(&file_lib);
456 xbt_dict_free(&watched_hosts_lib);
458 xbt_dynar_foreach(model_list, iter, model)
460 xbt_dynar_free(&model_list);
461 xbt_dynar_free(&model_list_invoke);
464 surf_callback_emit(surfExitCallbacks);
467 lmm_system_free(maxmin_system);
468 maxmin_system = NULL;
471 tmgr_history_free(history);
475 #ifdef CONTEXT_THREADS
476 xbt_parmap_destroy(surf_parmap);
483 surf_parse_lex_destroy();
484 surf_parse_free_callbacks();
486 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
493 Model::Model(const char *name)
494 : p_maxminSystem(NULL)
497 p_readyActionSet = new ActionList();
498 p_runningActionSet = new ActionList();
499 p_failedActionSet = new ActionList();
500 p_doneActionSet = new ActionList();
502 p_modifiedSet = NULL;
504 p_updateMechanism = UM_UNDEFINED;
505 m_selectiveUpdate = 0;
509 delete p_readyActionSet;
510 delete p_runningActionSet;
511 delete p_failedActionSet;
512 delete p_doneActionSet;
515 double Model::shareResources(double now)
517 //FIXME: set the good function once and for all
518 if (p_updateMechanism == UM_LAZY)
519 return shareResourcesLazy(now);
520 else if (p_updateMechanism == UM_FULL)
521 return shareResourcesFull(now);
523 xbt_die("Invalid cpu update mechanism!");
526 double Model::shareResourcesLazy(double now)
528 ActionPtr action = NULL;
533 ("Before share resources, the size of modified actions set is %zd",
534 p_modifiedSet->size());
536 lmm_solve(p_maxminSystem);
539 ("After share resources, The size of modified actions set is %zd",
540 p_modifiedSet->size());
542 while(!p_modifiedSet->empty()) {
543 action = &(p_modifiedSet->front());
544 p_modifiedSet->pop_front();
545 int max_dur_flag = 0;
547 if (action->getStateSet() != p_runningActionSet)
550 /* bogus priority, skip it */
551 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
554 action->updateRemainingLazy(now);
557 share = lmm_variable_getvalue(action->getVariable());
560 double time_to_completion;
561 if (action->getRemains() > 0) {
562 time_to_completion = action->getRemainsNoUpdate() / share;
564 time_to_completion = 0.0;
566 min = now + time_to_completion; // when the task will complete if nothing changes
569 if ((action->getMaxDuration() != NO_MAX_DURATION)
571 || action->getStartTime() +
572 action->getMaxDuration() < min)) {
573 min = action->getStartTime() +
574 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
579 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
581 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
582 action->getStartTime(), min, share,
583 action->getMaxDuration());
586 action->heapUpdate(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
587 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
589 } else DIE_IMPOSSIBLE;
592 //hereafter must have already the min value for this resource model
593 if (xbt_heap_size(p_actionHeap) > 0)
594 min = xbt_heap_maxkey(p_actionHeap) - now;
598 XBT_DEBUG("The minimum with the HEAP %f", min);
603 double Model::shareResourcesFull(double /*now*/) {
607 double Model::shareResourcesMaxMin(ActionListPtr running_actions,
609 void (*solve) (lmm_system_t))
611 ActionPtr action = NULL;
617 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
618 for(; it != itend ; ++it) {
620 value = lmm_variable_getvalue(action->getVariable());
621 if ((value > 0) || (action->getMaxDuration() >= 0))
629 if (action->getRemains() > 0)
630 min = action->getRemainsNoUpdate() / value;
633 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
634 min = action->getMaxDuration();
636 min = action->getMaxDuration();
639 for (++it; it != itend; ++it) {
641 value = lmm_variable_getvalue(action->getVariable());
643 if (action->getRemains() > 0)
644 value = action->getRemainsNoUpdate() / value;
649 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
652 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
653 min = action->getMaxDuration();
654 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
657 XBT_DEBUG("min value : %f", min);
662 void Model::updateActionsState(double now, double delta)
664 if (p_updateMechanism == UM_FULL)
665 updateActionsStateFull(now, delta);
666 else if (p_updateMechanism == UM_LAZY)
667 updateActionsStateLazy(now, delta);
669 xbt_die("Invalid cpu update mechanism!");
672 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
677 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
687 : p_name(NULL), p_properties(NULL), p_model(NULL)
690 Resource::Resource(ModelPtr model, const char *name, xbt_dict_t props)
691 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
692 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
695 Resource::Resource(ModelPtr model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
696 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
697 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON), p_constraint(constraint)
700 Resource::Resource(ModelPtr model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
701 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
702 , m_running(true), m_stateCurrent(stateInit)
705 Resource::~Resource() {
706 xbt_free((void*)p_name);
707 xbt_dict_free(&p_properties);
710 e_surf_resource_state_t Resource::getState()
712 return m_stateCurrent;
715 void Resource::setState(e_surf_resource_state_t state)
717 m_stateCurrent = state;
720 bool Resource::isOn()
725 void Resource::turnOn()
732 void Resource::turnOff()
739 ModelPtr Resource::getModel() {
743 const char *Resource::getName() {
747 xbt_dict_t Resource::getProperties() {
748 if (p_properties==NULL)
749 p_properties = xbt_dict_new();
753 lmm_constraint_t Resource::getConstraint() {
761 const char *surf_action_state_names[6] = {
763 "SURF_ACTION_RUNNING",
764 "SURF_ACTION_FAILED",
766 "SURF_ACTION_TO_FREE",
767 "SURF_ACTION_NOT_IN_THE_SYSTEM"
770 void Action::initialize(ModelPtr model, double cost, bool failed,
776 m_maxDuration = NO_MAX_DURATION;
779 m_start = surf_get_clock();
790 Action::Action(ModelPtr model, double cost, bool failed)
792 initialize(model, cost, failed);
796 p_stateHookup.prev = 0;
797 p_stateHookup.next = 0;
799 p_stateSet = getModel()->getFailedActionSet();
801 p_stateSet = getModel()->getRunningActionSet();
803 p_stateSet->push_back(*this);
806 Action::Action(ModelPtr model, double cost, bool failed, lmm_variable_t var)
808 initialize(model, cost, failed, var);
812 p_stateHookup.prev = 0;
813 p_stateHookup.next = 0;
815 p_stateSet = getModel()->getFailedActionSet();
817 p_stateSet = getModel()->getRunningActionSet();
819 p_stateSet->push_back(*this);
824 xbt_free(p_category);
828 void Action::finish() {
829 m_finish = surf_get_clock();
832 e_surf_action_state_t Action::getState()
834 if (p_stateSet == getModel()->getReadyActionSet())
835 return SURF_ACTION_READY;
836 if (p_stateSet == getModel()->getRunningActionSet())
837 return SURF_ACTION_RUNNING;
838 if (p_stateSet == getModel()->getFailedActionSet())
839 return SURF_ACTION_FAILED;
840 if (p_stateSet == getModel()->getDoneActionSet())
841 return SURF_ACTION_DONE;
842 return SURF_ACTION_NOT_IN_THE_SYSTEM;
845 void Action::setState(e_surf_action_state_t state)
847 //surf_action_state_t action_state = &(action->model_type->states);
848 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
849 p_stateSet->erase(p_stateSet->iterator_to(*this));
850 if (state == SURF_ACTION_READY)
851 p_stateSet = getModel()->getReadyActionSet();
852 else if (state == SURF_ACTION_RUNNING)
853 p_stateSet = getModel()->getRunningActionSet();
854 else if (state == SURF_ACTION_FAILED)
855 p_stateSet = getModel()->getFailedActionSet();
856 else if (state == SURF_ACTION_DONE)
857 p_stateSet = getModel()->getDoneActionSet();
862 p_stateSet->push_back(*this);
866 double Action::getBound()
868 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
871 void Action::setBound(double bound)
873 XBT_IN("(%p,%g)", this, bound);
875 lmm_update_variable_bound(getModel()->getMaxminSystem(), getVariable(), bound);
877 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
878 heapRemove(getModel()->getActionHeap());
882 double Action::getStartTime()
887 double Action::getFinishTime()
889 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
890 return m_remains == 0 ? m_finish : -1;
893 void Action::setData(void* data)
899 void Action::setCategory(const char *category)
901 XBT_IN("(%p,%s)", this, category);
902 p_category = xbt_strdup(category);
911 void Action::setMaxDuration(double duration)
913 XBT_IN("(%p,%g)", this, duration);
914 m_maxDuration = duration;
915 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
916 heapRemove(getModel()->getActionHeap());
920 void Action::gapRemove() {}
922 void Action::setPriority(double priority)
924 XBT_IN("(%p,%g)", this, priority);
925 m_priority = priority;
926 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
928 if (getModel()->getUpdateMechanism() == UM_LAZY)
929 heapRemove(getModel()->getActionHeap());
933 void Action::cancel(){
934 setState(SURF_ACTION_FAILED);
935 if (getModel()->getUpdateMechanism() == UM_LAZY) {
936 if (actionLmmHook::is_linked())
937 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
938 heapRemove(getModel()->getActionHeap());
945 if (actionHook::is_linked())
946 p_stateSet->erase(p_stateSet->iterator_to(*this));
948 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
949 if (getModel()->getUpdateMechanism() == UM_LAZY) {
950 /* remove from heap */
951 heapRemove(getModel()->getActionHeap());
952 if (actionLmmHook::is_linked())
953 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
961 void Action::suspend()
963 XBT_IN("(%p)", this);
964 if (m_suspended != 2) {
965 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
967 if (getModel()->getUpdateMechanism() == UM_LAZY)
968 heapRemove(getModel()->getActionHeap());
973 void Action::resume()
975 XBT_IN("(%p)", this);
976 if (m_suspended != 2) {
977 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
979 if (getModel()->getUpdateMechanism() == UM_LAZY)
980 heapRemove(getModel()->getActionHeap());
985 bool Action::isSuspended()
987 return m_suspended == 1;
989 /* insert action on heap using a given key and a hat (heap_action_type)
990 * a hat can be of three types for communications:
992 * NORMAL = this is a normal heap entry stating the date to finish transmitting
993 * LATENCY = this is a heap entry to warn us when the latency is payed
994 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
996 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
999 xbt_heap_push(heap, this, key);
1002 void Action::heapRemove(xbt_heap_t heap)
1005 if (m_indexHeap >= 0) {
1006 xbt_heap_remove(heap, m_indexHeap);
1010 void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
1013 if (m_indexHeap >= 0) {
1014 xbt_heap_update(heap, m_indexHeap, key);
1016 xbt_heap_push(heap, this, key);
1020 /* added to manage the communication action's heap */
1021 void surf_action_lmm_update_index_heap(void *action, int i) {
1022 ((ActionPtr)action)->updateIndexHeap(i);
1025 void Action::updateIndexHeap(int i) {
1029 double Action::getRemains()
1031 XBT_IN("(%p)", this);
1032 /* update remains before return it */
1033 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
1034 updateRemainingLazy(surf_get_clock());
1039 double Action::getRemainsNoUpdate()
1044 //FIXME split code in the right places
1045 void Action::updateRemainingLazy(double now)
1049 if(getModel() == surf_network_model)
1051 if (m_suspended != 0)
1056 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
1057 "You're updating an action that is not running.");
1059 /* bogus priority, skip it */
1060 xbt_assert(m_priority > 0,
1061 "You're updating an action that seems suspended.");
1064 delta = now - m_lastUpdate;
1066 if (m_remains > 0) {
1067 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1068 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
1071 if (getModel() == surf_cpu_model_pm && TRACE_is_enabled()) {
1072 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
1073 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1076 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1079 if(getModel() == surf_network_model)
1081 if (m_maxDuration != NO_MAX_DURATION)
1082 double_update(&m_maxDuration, delta, sg_surf_precision);
1084 //FIXME: duplicated code
1085 if ((m_remains <= 0) &&
1086 (lmm_get_variable_weight(getVariable()) > 0)) {
1088 setState(SURF_ACTION_DONE);
1089 heapRemove(getModel()->getActionHeap());
1090 } else if (((m_maxDuration != NO_MAX_DURATION)
1091 && (m_maxDuration <= 0))) {
1093 setState(SURF_ACTION_DONE);
1094 heapRemove(getModel()->getActionHeap());
1099 m_lastValue = lmm_variable_getvalue(getVariable());