1 #include "surf_private.h"
2 #include "surf_interface.hpp"
3 #include "network_interface.hpp"
4 #include "cpu_interface.hpp"
5 #include "workstation_interface.hpp"
6 #include "vm_workstation_interface.hpp"
7 #include "simix/smx_host_private.h"
8 #include "surf_routing.hpp"
9 #include "simgrid/sg_config.h"
12 XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
14 "Logging specific to SURF (kernel)");
20 /* This function is a pimple that we ought to fix. But it won't be easy.
22 * The surf_solve() function does properly return the set of actions that changed.
23 * Instead, each model change a global data, and then the caller of surf_solve must
24 * pick into these sets of action_failed and action_done.
26 * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
27 * We worked by putting sentinel actions on every resources we are interested in,
28 * so that surf informs us if/when the corresponding resource fails.
30 * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
31 * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
32 * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
33 * that was turned back up in the meanwhile. This is UGLY and slow.
35 * The proper solution would be to not rely on globals for the action_failed and action_done swags.
36 * They must be passed as parameter by the caller (the handling of these actions in simix may let you
37 * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
38 * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
41 * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
42 * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
43 * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
44 * sees it and react accordingly. This would kill that need for surf to call simix.
48 /*static void remove_watched_host(void *key)
50 xbt_dict_remove(watched_hosts_lib, *(char**)key);
53 /*void surf_watched_hosts(void)
57 xbt_dict_cursor_t cursor;
58 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
60 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
61 xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
63 if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
64 XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
65 SIMIX_host_autorestart((smx_host_t)host);
66 xbt_dynar_push_as(hosts, char*, key);
69 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
71 xbt_dynar_map(hosts, remove_watched_host);
72 xbt_dynar_free(&hosts);
75 /* model_list_invoke contains only surf_workstation and surf_vm_workstation.
76 * The callback functions of cpu_model and network_model will be called from
77 * those of these workstation models. */
78 xbt_dynar_t model_list = NULL; /* for destroying all models correctly */
79 xbt_dynar_t model_list_invoke = NULL; /* for invoking callbacks */
81 tmgr_history_t history = NULL;
82 lmm_system_t maxmin_system = NULL;
83 xbt_dynar_t surf_path = NULL;
84 xbt_dynar_t host_that_restart = NULL;
85 xbt_dict_t watched_hosts_lib;
87 /* Don't forget to update the option description in smx_config when you change this */
88 s_surf_model_description_t surf_network_model_description[] = {
90 "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). ",
91 surf_network_model_init_LegrandVelho},
93 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
94 surf_network_model_init_Constant},
96 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
97 surf_network_model_init_SMPI},
99 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
100 surf_network_model_init_CM02},
103 "Network pseudo-model using the GTNets simulator instead of an analytic model",
104 surf_network_model_init_GTNETS},
108 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
109 surf_network_model_init_NS3},
112 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
113 surf_network_model_init_Reno},
115 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
116 surf_network_model_init_Reno2},
118 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
119 surf_network_model_init_Vegas},
120 {NULL, NULL, NULL} /* this array must be NULL terminated */
123 s_surf_model_description_t surf_cpu_model_description[] = {
125 "Simplistic CPU model (time=size/power).",
126 surf_cpu_model_init_Cas01},
127 {NULL, NULL, NULL} /* this array must be NULL terminated */
130 s_surf_model_description_t surf_workstation_model_description[] = {
132 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
133 surf_workstation_model_init_current_default},
135 "Workstation model that is automatically chosen if you change the network and CPU models",
136 surf_workstation_model_init_compound},
137 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
138 surf_workstation_model_init_ptask_L07},
139 {NULL, NULL, NULL} /* this array must be NULL terminated */
142 s_surf_model_description_t surf_vm_workstation_model_description[] = {
144 "Default vm workstation model.)",
145 surf_vm_workstation_model_init_current_default},
146 {NULL, NULL, NULL} /* this array must be NULL terminated */
149 s_surf_model_description_t surf_optimization_mode_description[] = {
151 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
154 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
157 "Full update of remaining and variables. Slow but may be useful when debugging.",
159 {NULL, NULL, NULL} /* this array must be NULL terminated */
162 s_surf_model_description_t surf_storage_model_description[] = {
164 "Simplistic storage model.",
165 surf_storage_model_init_default},
166 {NULL, NULL, NULL} /* this array must be NULL terminated */
169 #ifdef CONTEXT_THREADS
170 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
174 double *surf_mins = NULL; /* return value of share_resources for each model */
175 int surf_min_index; /* current index in surf_mins */
176 double surf_min; /* duration determined by surf_solve */
178 double surf_get_clock(void)
184 # define FILE_DELIM "\\"
186 # define FILE_DELIM "/" /* FIXME: move to better location */
189 FILE *surf_fopen(const char *name, const char *mode)
192 char *path_elm = NULL;
198 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
199 return fopen(name, mode);
201 /* search relative files in the path */
202 xbt_dynar_foreach(surf_path, cpt, path_elm) {
203 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
204 file = fopen(buff, mode);
214 * Returns the initial path. On Windows the initial path is
215 * the current directory for the current process in the other
216 * case the function returns "./" that represents the current
217 * directory on Unix/Linux platforms.
220 const char *__surf_get_initial_path(void)
225 char current_directory[MAX_PATH + 1] = { 0 };
226 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
227 char root[4] = { 0 };
232 strncpy(root, current_directory, 3);
234 for (i = 0; i < MAX_DRIVE; i++) {
235 if (toupper(root[0]) == disk_drives_letter_table[i][0])
236 return disk_drives_letter_table[i];
245 /* The __surf_is_absolute_file_path() returns 1 if
246 * file_path is a absolute file path, in the other
247 * case the function returns 0.
249 int __surf_is_absolute_file_path(const char *file_path)
252 WIN32_FIND_DATA wfd = { 0 };
253 HANDLE hFile = FindFirstFile(file_path, &wfd);
255 if (INVALID_HANDLE_VALUE == hFile)
261 return (file_path[0] == '/');
265 /** Displays the long description of all registered models, and quit */
266 void model_help(const char *category, s_surf_model_description_t * table)
269 printf("Long description of the %s models accepted by this simulator:\n",
271 for (i = 0; table[i].name; i++)
272 printf(" %s: %s\n", table[i].name, table[i].description);
275 int find_model_description(s_surf_model_description_t * table,
279 char *name_list = NULL;
281 for (i = 0; table[i].name; i++)
282 if (!strcmp(name, table[i].name)) {
285 name_list = strdup(table[0].name);
286 for (i = 1; table[i].name; i++) {
287 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
288 strcat(name_list, ", ");
289 strcat(name_list, table[i].name);
291 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
295 static XBT_INLINE void routing_asr_host_free(void *p)
297 delete ((RoutingEdgePtr) p);
300 static XBT_INLINE void routing_asr_prop_free(void *p)
302 xbt_dict_t elm = (xbt_dict_t) p;
306 static XBT_INLINE void surf_cpu_free(void *r)
308 delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
311 static XBT_INLINE void surf_link_free(void *r)
313 delete dynamic_cast<NetworkLinkPtr>(static_cast<ResourcePtr>(r));
316 static XBT_INLINE void surf_workstation_free(void *r)
318 delete dynamic_cast<WorkstationPtr>(static_cast<ResourcePtr>(r));
322 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
323 *ver_major = SIMGRID_VERSION_MAJOR;
324 *ver_minor = SIMGRID_VERSION_MINOR;
325 *ver_patch = SIMGRID_VERSION_PATCH;
328 void surf_init(int *argc, char **argv)
330 XBT_DEBUG("Create all Libs");
331 host_lib = xbt_lib_new();
332 link_lib = xbt_lib_new();
333 as_router_lib = xbt_lib_new();
334 storage_lib = xbt_lib_new();
335 storage_type_lib = xbt_lib_new();
336 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
338 XBT_DEBUG("Add routing levels");
339 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
340 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
341 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
343 XBT_DEBUG("Add SURF levels");
344 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
345 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
346 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
348 xbt_init(argc, argv);
350 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
351 if (!model_list_invoke)
352 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
354 history = tmgr_history_new();
357 TRACE_add_start_function(TRACE_surf_alloc);
358 TRACE_add_end_function(TRACE_surf_release);
361 sg_config_init(argc, argv);
370 ModelPtr model = NULL;
373 TRACE_end(); /* Just in case it was not called by the upper
374 * layer (or there is no upper layer) */
377 sg_config_finalize();
379 xbt_dynar_foreach(model_list, iter, model)
381 xbt_dynar_free(&model_list);
382 xbt_dynar_free(&model_list_invoke);
386 lmm_system_free(maxmin_system);
387 maxmin_system = NULL;
390 tmgr_history_free(history);
394 #ifdef CONTEXT_THREADS
395 xbt_parmap_destroy(surf_parmap);
401 xbt_dynar_free(&host_that_restart);
402 xbt_dynar_free(&surf_path);
404 xbt_lib_free(&host_lib);
405 xbt_lib_free(&link_lib);
406 xbt_lib_free(&as_router_lib);
407 xbt_lib_free(&storage_lib);
408 xbt_lib_free(&storage_type_lib);
410 xbt_dict_free(&watched_hosts_lib);
413 surf_parse_lex_destroy();
414 surf_parse_free_callbacks();
416 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
422 Model::Model(const char *name)
423 : p_maxminSystem(0), p_name(name),
424 m_resOnCB(0), m_resOffCB(0),
425 m_actCancelCB(0), m_actSuspendCB(0), m_actResumeCB(0)
427 ActionPtr action = NULL;
428 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
429 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
430 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
431 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
433 p_modifiedSet = NULL;
435 p_updateMechanism = UM_UNDEFINED;
436 m_selectiveUpdate = 0;
440 xbt_swag_free(p_readyActionSet);
441 xbt_swag_free(p_runningActionSet);
442 xbt_swag_free(p_failedActionSet);
443 xbt_swag_free(p_doneActionSet);
446 double Model::shareResources(double now)
448 //FIXME: set the good function once and for all
449 if (p_updateMechanism == UM_LAZY)
450 return shareResourcesLazy(now);
451 else if (p_updateMechanism == UM_FULL)
452 return shareResourcesFull(now);
454 xbt_die("Invalid cpu update mechanism!");
457 double Model::shareResourcesLazy(double now)
459 ActionLmmPtr action = NULL;
464 ("Before share resources, the size of modified actions set is %d",
465 xbt_swag_size(p_modifiedSet));
467 lmm_solve(p_maxminSystem);
470 ("After share resources, The size of modified actions set is %d",
471 xbt_swag_size(p_modifiedSet));
473 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
474 int max_dur_flag = 0;
476 if (action->getStateSet() != p_runningActionSet)
479 /* bogus priority, skip it */
480 if (action->getPriority() <= 0)
483 action->updateRemainingLazy(now);
486 value = lmm_variable_getvalue(action->getVariable());
488 if (action->getRemains() > 0) {
489 value = action->getRemains() / value;
497 if ((action->getMaxDuration() != NO_MAX_DURATION)
499 || action->getStartTime() +
500 action->getMaxDuration() < min)) {
501 min = action->getStartTime() +
502 action->getMaxDuration();
506 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
507 action->getStartTime(), now + value,
508 action->getMaxDuration());
511 action->heapRemove(p_actionHeap);
512 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
513 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
515 } else DIE_IMPOSSIBLE;
518 //hereafter must have already the min value for this resource model
519 if (xbt_heap_size(p_actionHeap) > 0)
520 min = xbt_heap_maxkey(p_actionHeap) - now;
524 XBT_DEBUG("The minimum with the HEAP %lf", min);
529 double Model::shareResourcesFull(double /*now*/) {
534 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
536 void (*solve) (lmm_system_t))
538 void *_action = NULL;
539 ActionLmmPtr action = NULL;
545 xbt_swag_foreach(_action, running_actions) {
546 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
547 value = lmm_variable_getvalue(action->getVariable());
548 if ((value > 0) || (action->getMaxDuration() >= 0))
556 if (action->getRemains() > 0)
557 min = action->getRemains() / value;
560 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
561 min = action->getMaxDuration();
563 min = action->getMaxDuration();
566 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
568 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
569 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
570 value = lmm_variable_getvalue(action->getVariable());
572 if (action->getRemains() > 0)
573 value = action->getRemains() / value;
578 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
581 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
582 min = action->getMaxDuration();
583 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
586 XBT_DEBUG("min value : %f", min);
591 void Model::updateActionsState(double now, double delta)
593 if (p_updateMechanism == UM_FULL)
594 updateActionsStateFull(now, delta);
595 else if (p_updateMechanism == UM_LAZY)
596 updateActionsStateLazy(now, delta);
598 xbt_die("Invalid cpu update mechanism!");
601 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
606 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
612 void Model::addTurnedOnCallback(ResourceCallback rc)
617 void Model::notifyResourceTurnedOn(ResourcePtr r)
622 void Model::addTurnedOffCallback(ResourceCallback rc)
627 void Model::notifyResourceTurnedOff(ResourcePtr r)
632 void Model::addActionCancelCallback(ActionCallback ac)
637 void Model::notifyActionCancel(ActionPtr a)
642 void Model::addActionResumeCallback(ActionCallback ac)
647 void Model::notifyActionResume(ActionPtr a)
652 void Model::addActionSuspendCallback(ActionCallback ac)
657 void Model::notifyActionSuspend(ActionPtr a)
668 : p_name(NULL), p_properties(NULL), p_model(NULL)
671 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
672 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
673 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
676 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
677 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
678 , m_running(true), m_stateCurrent(stateInit)
681 e_surf_resource_state_t Resource::getState()
683 return m_stateCurrent;
686 void Resource::setState(e_surf_resource_state_t state)
688 m_stateCurrent = state;
691 bool Resource::isOn()
696 void Resource::turnOn()
700 getModel()->notifyResourceTurnedOn(this);
704 void Resource::turnOff()
708 getModel()->notifyResourceTurnedOff(this);
712 ResourceLmm::ResourceLmm()
716 ResourceLmm::ResourceLmm(lmm_constraint_t constraint)
717 : p_constraint(constraint)
724 const char *surf_action_state_names[6] = {
726 "SURF_ACTION_RUNNING",
727 "SURF_ACTION_FAILED",
729 "SURF_ACTION_TO_FREE",
730 "SURF_ACTION_NOT_IN_THE_SYSTEM"
737 Action::Action(ModelPtr model, double cost, bool failed)
740 , m_start(surf_get_clock()), m_finish(-1.0)
742 , m_maxDuration(NO_MAX_DURATION)
751 p_stateHookup.prev = 0;
752 p_stateHookup.next = 0;
754 p_stateSet = getModel()->getFailedActionSet();
756 p_stateSet = getModel()->getRunningActionSet();
758 xbt_swag_insert(this, p_stateSet);
763 xbt_free(p_category);
767 void Action::finish() {
768 m_finish = surf_get_clock();
775 void Action::cancel(){
779 void Action::recycle(){
783 e_surf_action_state_t Action::getState()
785 if (p_stateSet == getModel()->getReadyActionSet())
786 return SURF_ACTION_READY;
787 if (p_stateSet == getModel()->getRunningActionSet())
788 return SURF_ACTION_RUNNING;
789 if (p_stateSet == getModel()->getFailedActionSet())
790 return SURF_ACTION_FAILED;
791 if (p_stateSet == getModel()->getDoneActionSet())
792 return SURF_ACTION_DONE;
793 return SURF_ACTION_NOT_IN_THE_SYSTEM;
796 void Action::setState(e_surf_action_state_t state)
798 //surf_action_state_t action_state = &(action->model_type->states);
799 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
800 xbt_swag_remove(this, p_stateSet);
802 if (state == SURF_ACTION_READY)
803 p_stateSet = getModel()->getReadyActionSet();
804 else if (state == SURF_ACTION_RUNNING)
805 p_stateSet = getModel()->getRunningActionSet();
806 else if (state == SURF_ACTION_FAILED)
807 p_stateSet = getModel()->getFailedActionSet();
808 else if (state == SURF_ACTION_DONE)
809 p_stateSet = getModel()->getDoneActionSet();
814 xbt_swag_insert(this, p_stateSet);
818 double Action::getStartTime()
823 double Action::getFinishTime()
825 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
826 return m_remains == 0 ? m_finish : -1;
829 double Action::getRemains()
831 XBT_IN("(%p)", this);
836 void Action::setData(void* data)
842 void Action::setCategory(const char *category)
844 XBT_IN("(%p,%s)", this, category);
845 p_category = xbt_strdup(category);
854 void ActionLmm::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 ActionLmm::gapRemove() {}
865 void ActionLmm::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 ActionLmm::cancel(){
877 setState(SURF_ACTION_FAILED);
878 if (getModel()->getUpdateMechanism() == UM_LAZY) {
879 xbt_swag_remove(this, getModel()->getModifiedSet());
880 heapRemove(getModel()->getActionHeap());
884 int ActionLmm::unref(){
887 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
889 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
890 if (getModel()->getUpdateMechanism() == UM_LAZY) {
891 /* remove from heap */
892 heapRemove(getModel()->getActionHeap());
893 xbt_swag_remove(this, getModel()->getModifiedSet());
901 void ActionLmm::suspend()
903 XBT_IN("(%p)", this);
904 if (m_suspended != 2) {
905 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
907 if (getModel()->getUpdateMechanism() == UM_LAZY)
908 heapRemove(getModel()->getActionHeap());
913 void ActionLmm::resume()
915 XBT_IN("(%p)", this);
916 if (m_suspended != 2) {
917 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
919 if (getModel()->getUpdateMechanism() == UM_LAZY)
920 heapRemove(getModel()->getActionHeap());
925 bool ActionLmm::isSuspended()
927 return m_suspended == 1;
929 /* insert action on heap using a given key and a hat (heap_action_type)
930 * a hat can be of three types for communications:
932 * NORMAL = this is a normal heap entry stating the date to finish transmitting
933 * LATENCY = this is a heap entry to warn us when the latency is payed
934 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
936 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
939 xbt_heap_push(heap, this, key);
942 void ActionLmm::heapRemove(xbt_heap_t heap)
945 if (m_indexHeap >= 0) {
946 xbt_heap_remove(heap, m_indexHeap);
950 /* added to manage the communication action's heap */
951 void surf_action_lmm_update_index_heap(void *action, int i) {
952 ((ActionLmmPtr)action)->updateIndexHeap(i);
955 void ActionLmm::updateIndexHeap(int i) {
959 double ActionLmm::getRemains()
961 XBT_IN("(%p)", this);
962 /* update remains before return it */
963 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
964 updateRemainingLazy(surf_get_clock());
969 //FIXME split code in the right places
970 void ActionLmm::updateRemainingLazy(double now)
974 if(getModel() == static_cast<ModelPtr>(surf_network_model))
976 if (m_suspended != 0)
981 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
982 "You're updating an action that is not running.");
984 /* bogus priority, skip it */
985 xbt_assert(m_priority > 0,
986 "You're updating an action that seems suspended.");
989 delta = now - m_lastUpdate;
992 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
993 double_update(&m_remains, m_lastValue * delta);
996 if (getModel() == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
997 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
998 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1001 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1004 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1006 if (m_maxDuration != NO_MAX_DURATION)
1007 double_update(&m_maxDuration, delta);
1009 //FIXME: duplicated code
1010 if ((m_remains <= 0) &&
1011 (lmm_get_variable_weight(getVariable()) > 0)) {
1013 setState(SURF_ACTION_DONE);
1014 heapRemove(getModel()->getActionHeap());
1015 } else if (((m_maxDuration != NO_MAX_DURATION)
1016 && (m_maxDuration <= 0))) {
1018 setState(SURF_ACTION_DONE);
1019 heapRemove(getModel()->getActionHeap());
1024 m_lastValue = lmm_variable_getvalue(getVariable());
1027 /*void Action::cancel()
1029 p_model->notifyActionCancel(this);
1032 void Action::suspend()
1034 p_model->notifyActionSuspend(this);
1037 void Action::resume()
1039 p_model->notifyActionResume(this);
1042 bool Action::isSuspended()