1 #include "surf_private.h"
3 #include "network_interface.hpp"
4 #include "cpu_interface.hpp"
5 #include "workstation.hpp"
6 #include "vm_workstation.hpp"
7 #include "simix/smx_host_private.h"
8 #include "surf_routing.hpp"
9 #include "simgrid/sg_config.h"
13 XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
15 "Logging specific to SURF (kernel)");
24 /* This function is a pimple that we ought to fix. But it won't be easy.
26 * The surf_solve() function does properly return the set of actions that changed.
27 * Instead, each model change a global data, and then the caller of surf_solve must
28 * pick into these sets of action_failed and action_done.
30 * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
31 * We worked by putting sentinel actions on every resources we are interested in,
32 * so that surf informs us if/when the corresponding resource fails.
34 * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
35 * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
36 * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
37 * that was turned back up in the meanwhile. This is UGLY and slow.
39 * The proper solution would be to not rely on globals for the action_failed and action_done swags.
40 * They must be passed as parameter by the caller (the handling of these actions in simix may let you
41 * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
42 * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
45 * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
46 * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
47 * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
48 * sees it and react accordingly. This would kill that need for surf to call simix.
52 static void remove_watched_host(void *key)
54 xbt_dict_remove(watched_hosts_lib, *(char**)key);
57 /*void surf_watched_hosts(void)
61 xbt_dict_cursor_t cursor;
62 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
64 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
65 xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
67 if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
68 XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
69 SIMIX_host_autorestart((smx_host_t)host);
70 xbt_dynar_push_as(hosts, char*, key);
73 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
75 xbt_dynar_map(hosts, remove_watched_host);
76 xbt_dynar_free(&hosts);
79 /* model_list_invoke contains only surf_workstation and surf_vm_workstation.
80 * The callback functions of cpu_model and network_model will be called from
81 * those of these workstation models. */
82 xbt_dynar_t model_list = NULL; /* for destroying all models correctly */
83 xbt_dynar_t model_list_invoke = NULL; /* for invoking callbacks */
85 tmgr_history_t history = NULL;
86 lmm_system_t maxmin_system = NULL;
87 xbt_dynar_t surf_path = NULL;
88 xbt_dynar_t host_that_restart = NULL;
89 xbt_dict_t watched_hosts_lib;
91 /* Don't forget to update the option description in smx_config when you change this */
92 s_surf_model_description_t surf_network_model_description[] = {
94 "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). ",
95 surf_network_model_init_LegrandVelho},
97 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
98 surf_network_model_init_Constant},
100 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
101 surf_network_model_init_SMPI},
103 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
104 surf_network_model_init_CM02},
107 "Network pseudo-model using the GTNets simulator instead of an analytic model",
108 surf_network_model_init_GTNETS},
112 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
113 surf_network_model_init_NS3},
116 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
117 surf_network_model_init_Reno},
119 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
120 surf_network_model_init_Reno2},
122 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
123 surf_network_model_init_Vegas},
124 {NULL, NULL, NULL} /* this array must be NULL terminated */
127 s_surf_model_description_t surf_cpu_model_description[] = {
129 "Simplistic CPU model (time=size/power).",
130 surf_cpu_model_init_Cas01},
131 {NULL, NULL, NULL} /* this array must be NULL terminated */
134 s_surf_model_description_t surf_workstation_model_description[] = {
136 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
137 surf_workstation_model_init_current_default},
139 "Workstation model that is automatically chosen if you change the network and CPU models",
140 surf_workstation_model_init_compound},
141 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
142 surf_workstation_model_init_ptask_L07},
143 {NULL, NULL, NULL} /* this array must be NULL terminated */
146 s_surf_model_description_t surf_vm_workstation_model_description[] = {
148 "Default vm workstation model.)",
149 surf_vm_workstation_model_init_current_default},
150 {NULL, NULL, NULL} /* this array must be NULL terminated */
153 s_surf_model_description_t surf_optimization_mode_description[] = {
155 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
158 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
161 "Full update of remaining and variables. Slow but may be useful when debugging.",
163 {NULL, NULL, NULL} /* this array must be NULL terminated */
166 s_surf_model_description_t surf_storage_model_description[] = {
168 "Simplistic storage model.",
169 surf_storage_model_init_default},
170 {NULL, NULL, NULL} /* this array must be NULL terminated */
173 #ifdef CONTEXT_THREADS
174 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
178 double *surf_mins = NULL; /* return value of share_resources for each model */
179 int surf_min_index; /* current index in surf_mins */
180 double surf_min; /* duration determined by surf_solve */
182 double surf_get_clock(void)
188 # define FILE_DELIM "\\"
190 # define FILE_DELIM "/" /* FIXME: move to better location */
193 FILE *surf_fopen(const char *name, const char *mode)
196 char *path_elm = NULL;
202 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
203 return fopen(name, mode);
205 /* search relative files in the path */
206 xbt_dynar_foreach(surf_path, cpt, path_elm) {
207 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
208 file = fopen(buff, mode);
218 * Returns the initial path. On Windows the initial path is
219 * the current directory for the current process in the other
220 * case the function returns "./" that represents the current
221 * directory on Unix/Linux platforms.
224 const char *__surf_get_initial_path(void)
229 char current_directory[MAX_PATH + 1] = { 0 };
230 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
231 char root[4] = { 0 };
236 strncpy(root, current_directory, 3);
238 for (i = 0; i < MAX_DRIVE; i++) {
239 if (toupper(root[0]) == disk_drives_letter_table[i][0])
240 return disk_drives_letter_table[i];
249 /* The __surf_is_absolute_file_path() returns 1 if
250 * file_path is a absolute file path, in the other
251 * case the function returns 0.
253 int __surf_is_absolute_file_path(const char *file_path)
256 WIN32_FIND_DATA wfd = { 0 };
257 HANDLE hFile = FindFirstFile(file_path, &wfd);
259 if (INVALID_HANDLE_VALUE == hFile)
265 return (file_path[0] == '/');
269 /** Displays the long description of all registered models, and quit */
270 void model_help(const char *category, s_surf_model_description_t * table)
273 printf("Long description of the %s models accepted by this simulator:\n",
275 for (i = 0; table[i].name; i++)
276 printf(" %s: %s\n", table[i].name, table[i].description);
279 int find_model_description(s_surf_model_description_t * table,
283 char *name_list = NULL;
285 for (i = 0; table[i].name; i++)
286 if (!strcmp(name, table[i].name)) {
289 name_list = strdup(table[0].name);
290 for (i = 1; table[i].name; i++) {
291 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
292 strcat(name_list, ", ");
293 strcat(name_list, table[i].name);
295 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
299 static XBT_INLINE void routing_asr_host_free(void *p)
301 delete ((RoutingEdgePtr) p);
304 static XBT_INLINE void routing_asr_prop_free(void *p)
306 xbt_dict_t elm = (xbt_dict_t) p;
310 static XBT_INLINE void surf_cpu_free(void *r)
312 delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
315 static XBT_INLINE void surf_link_free(void *r)
317 delete dynamic_cast<NetworkLinkPtr>(static_cast<ResourcePtr>(r));
320 static XBT_INLINE void surf_workstation_free(void *r)
322 delete dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(r));
326 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
327 *ver_major = SIMGRID_VERSION_MAJOR;
328 *ver_minor = SIMGRID_VERSION_MINOR;
329 *ver_patch = SIMGRID_VERSION_PATCH;
332 void surf_init(int *argc, char **argv)
334 XBT_DEBUG("Create all Libs");
335 host_lib = xbt_lib_new();
336 link_lib = xbt_lib_new();
337 as_router_lib = xbt_lib_new();
338 storage_lib = xbt_lib_new();
339 storage_type_lib = xbt_lib_new();
340 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
342 XBT_DEBUG("Add routing levels");
343 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
344 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
345 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
347 XBT_DEBUG("Add SURF levels");
348 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
349 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
350 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
352 xbt_init(argc, argv);
354 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
355 if (!model_list_invoke)
356 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
358 history = tmgr_history_new();
361 TRACE_add_start_function(TRACE_surf_alloc);
362 TRACE_add_end_function(TRACE_surf_release);
365 sg_config_init(argc, argv);
374 ModelPtr model = NULL;
377 TRACE_end(); /* Just in case it was not called by the upper
378 * layer (or there is no upper layer) */
381 sg_config_finalize();
383 xbt_dynar_foreach(model_list, iter, model)
385 xbt_dynar_free(&model_list);
386 xbt_dynar_free(&model_list_invoke);
390 lmm_system_free(maxmin_system);
391 maxmin_system = NULL;
394 tmgr_history_free(history);
398 #ifdef CONTEXT_THREADS
399 xbt_parmap_destroy(surf_parmap);
405 xbt_dynar_free(&host_that_restart);
406 xbt_dynar_free(&surf_path);
408 xbt_lib_free(&host_lib);
409 xbt_lib_free(&link_lib);
410 xbt_lib_free(&as_router_lib);
411 xbt_lib_free(&storage_lib);
412 xbt_lib_free(&storage_type_lib);
414 xbt_dict_free(&watched_hosts_lib);
417 surf_parse_lex_destroy();
418 surf_parse_free_callbacks();
420 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
426 Model::Model(string name)
427 : p_maxminSystem(0), m_name(name),
428 m_resOnCB(0), m_resOffCB(0),
429 m_actCancelCB(0), m_actSuspendCB(0), m_actResumeCB(0)
431 ActionPtr action = NULL;
432 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
433 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
434 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
435 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
437 p_modifiedSet = NULL;
439 p_updateMechanism = UM_UNDEFINED;
440 m_selectiveUpdate = 0;
444 xbt_swag_free(p_readyActionSet);
445 xbt_swag_free(p_runningActionSet);
446 xbt_swag_free(p_failedActionSet);
447 xbt_swag_free(p_doneActionSet);
450 double Model::shareResources(double now)
452 //FIXME: set the good function once and for all
453 if (p_updateMechanism == UM_LAZY)
454 return shareResourcesLazy(now);
455 else if (p_updateMechanism == UM_FULL)
456 return shareResourcesFull(now);
458 xbt_die("Invalid cpu update mechanism!");
461 double Model::shareResourcesLazy(double now)
463 ActionLmmPtr action = NULL;
468 ("Before share resources, the size of modified actions set is %d",
469 xbt_swag_size(p_modifiedSet));
471 lmm_solve(p_maxminSystem);
474 ("After share resources, The size of modified actions set is %d",
475 xbt_swag_size(p_modifiedSet));
477 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
478 int max_dur_flag = 0;
480 if (action->p_stateSet != p_runningActionSet)
483 /* bogus priority, skip it */
484 if (action->m_priority <= 0)
487 action->updateRemainingLazy(now);
490 value = lmm_variable_getvalue(action->p_variable);
492 if (action->m_remains > 0) {
493 value = action->m_remains / value;
501 if ((action->m_maxDuration != NO_MAX_DURATION)
504 action->m_maxDuration < min)) {
505 min = action->m_start +
506 action->m_maxDuration;
510 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
511 action->m_start, now + value,
512 action->m_maxDuration);
515 action->heapRemove(p_actionHeap);
516 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
517 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
519 } else DIE_IMPOSSIBLE;
522 //hereafter must have already the min value for this resource model
523 if (xbt_heap_size(p_actionHeap) > 0)
524 min = xbt_heap_maxkey(p_actionHeap) - now;
528 XBT_DEBUG("The minimum with the HEAP %lf", min);
533 double Model::shareResourcesFull(double /*now*/) {
538 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
540 void (*solve) (lmm_system_t))
542 void *_action = NULL;
543 ActionLmmPtr action = NULL;
549 xbt_swag_foreach(_action, running_actions) {
550 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
551 value = lmm_variable_getvalue(action->p_variable);
552 if ((value > 0) || (action->m_maxDuration >= 0))
560 if (action->m_remains > 0)
561 min = action->m_remains / value;
564 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
565 min = action->m_maxDuration;
567 min = action->m_maxDuration;
570 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
572 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
573 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
574 value = lmm_variable_getvalue(action->p_variable);
576 if (action->m_remains > 0)
577 value = action->m_remains / value;
582 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
585 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
586 min = action->m_maxDuration;
587 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
590 XBT_DEBUG("min value : %f", min);
595 void Model::updateActionsState(double now, double delta)
597 if (p_updateMechanism == UM_FULL)
598 updateActionsStateFull(now, delta);
599 else if (p_updateMechanism == UM_LAZY)
600 updateActionsStateLazy(now, delta);
602 xbt_die("Invalid cpu update mechanism!");
605 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
610 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
616 void Model::addTurnedOnCallback(ResourceCallback rc)
621 void Model::notifyResourceTurnedOn(ResourcePtr r)
626 void Model::addTurnedOffCallback(ResourceCallback rc)
631 void Model::notifyResourceTurnedOff(ResourcePtr r)
636 void Model::addActionCancelCallback(ActionCallback ac)
641 void Model::notifyActionCancel(ActionPtr a)
646 void Model::addActionResumeCallback(ActionCallback ac)
651 void Model::notifyActionResume(ActionPtr a)
656 void Model::addActionSuspendCallback(ActionCallback ac)
661 void Model::notifyActionSuspend(ActionPtr a)
671 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
672 : m_name(xbt_strdup(name)), m_properties(props), p_model(model), m_running(true)
676 : m_name(NULL), m_properties(NULL), p_model(NULL)
679 const char *Resource::getName()
684 xbt_dict_t Resource::getProperties()
689 e_surf_resource_state_t Resource::getState()
691 return p_stateCurrent;
694 void Resource::setState(e_surf_resource_state_t state)
696 p_stateCurrent = state;
699 bool Resource::isOn()
704 void Resource::turnOn()
708 p_model->notifyResourceTurnedOn(this);
712 void Resource::turnOff()
716 p_model->notifyResourceTurnedOff(this);
720 ResourceLmm::ResourceLmm(lmm_system_t system,
721 double constraint_value,
722 tmgr_history_t history,
723 e_surf_resource_state_t state_init,
724 tmgr_trace_t state_trace,
726 tmgr_trace_t metric_trace)
728 p_constraint = lmm_constraint_new(system, this, constraint_value);
729 p_stateCurrent = state_init;
731 p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
733 p_power.peak = metric_peak;
735 p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
737 p_power.event = NULL;
744 const char *surf_action_state_names[6] = {
746 "SURF_ACTION_RUNNING",
747 "SURF_ACTION_FAILED",
749 "SURF_ACTION_TO_FREE",
750 "SURF_ACTION_NOT_IN_THE_SYSTEM"
755 Action::Action(ModelPtr model, double cost, bool failed):
758 m_start(surf_get_clock()), m_finish(-1.0),
760 m_maxDuration(NO_MAX_DURATION),
769 p_stateHookup.prev = 0;
770 p_stateHookup.next = 0;
772 p_stateSet = p_model->p_failedActionSet;
774 p_stateSet = p_model->p_runningActionSet;
776 xbt_swag_insert(this, p_stateSet);
785 void Action::cancel(){
789 void Action::recycle(){
793 e_surf_action_state_t Action::getState()
795 if (p_stateSet == p_model->p_readyActionSet)
796 return SURF_ACTION_READY;
797 if (p_stateSet == p_model->p_runningActionSet)
798 return SURF_ACTION_RUNNING;
799 if (p_stateSet == p_model->p_failedActionSet)
800 return SURF_ACTION_FAILED;
801 if (p_stateSet == p_model->p_doneActionSet)
802 return SURF_ACTION_DONE;
803 return SURF_ACTION_NOT_IN_THE_SYSTEM;
806 void Action::setState(e_surf_action_state_t state)
808 //surf_action_state_t action_state = &(action->model_type->states);
809 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
810 xbt_swag_remove(this, p_stateSet);
812 if (state == SURF_ACTION_READY)
813 p_stateSet = p_model->p_readyActionSet;
814 else if (state == SURF_ACTION_RUNNING)
815 p_stateSet = p_model->p_runningActionSet;
816 else if (state == SURF_ACTION_FAILED)
817 p_stateSet = p_model->p_failedActionSet;
818 else if (state == SURF_ACTION_DONE)
819 p_stateSet = p_model->p_doneActionSet;
824 xbt_swag_insert(this, p_stateSet);
828 double Action::getStartTime()
833 double Action::getFinishTime()
835 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
836 return m_remains == 0 ? m_finish : -1;
839 double Action::getRemains()
841 XBT_IN("(%p)", this);
846 void Action::setData(void* data)
852 void Action::setCategory(const char *category)
854 XBT_IN("(%p,%s)", this, category);
855 p_category = xbt_strdup(category);
864 void ActionLmm::setMaxDuration(double duration)
866 XBT_IN("(%p,%g)", this, duration);
867 m_maxDuration = duration;
868 if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
869 heapRemove(p_model->p_actionHeap);
873 void ActionLmm::gapRemove() {}
875 void ActionLmm::setPriority(double priority)
877 XBT_IN("(%p,%g)", this, priority);
878 m_priority = priority;
879 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
881 if (p_model->p_updateMechanism == UM_LAZY)
882 heapRemove(p_model->p_actionHeap);
886 void ActionLmm::cancel(){
887 setState(SURF_ACTION_FAILED);
888 if (p_model->p_updateMechanism == UM_LAZY) {
889 xbt_swag_remove(this, p_model->p_modifiedSet);
890 heapRemove(p_model->p_actionHeap);
894 int ActionLmm::unref(){
897 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
899 lmm_variable_free(p_model->p_maxminSystem, p_variable);
900 if (p_model->p_updateMechanism == UM_LAZY) {
901 /* remove from heap */
902 heapRemove(p_model->p_actionHeap);
903 xbt_swag_remove(this, p_model->p_modifiedSet);
906 xbt_free(p_category);
914 void ActionLmm::suspend()
916 XBT_IN("(%p)", this);
917 if (m_suspended != 2) {
918 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
920 if (p_model->p_updateMechanism == UM_LAZY)
921 heapRemove(p_model->p_actionHeap);
926 void ActionLmm::resume()
928 XBT_IN("(%p)", this);
929 if (m_suspended != 2) {
930 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
932 if (p_model->p_updateMechanism == UM_LAZY)
933 heapRemove(p_model->p_actionHeap);
938 bool ActionLmm::isSuspended()
940 return m_suspended == 1;
942 /* insert action on heap using a given key and a hat (heap_action_type)
943 * a hat can be of three types for communications:
945 * NORMAL = this is a normal heap entry stating the date to finish transmitting
946 * LATENCY = this is a heap entry to warn us when the latency is payed
947 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
949 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
952 xbt_heap_push(heap, this, key);
955 void ActionLmm::heapRemove(xbt_heap_t heap)
958 if (m_indexHeap >= 0) {
959 xbt_heap_remove(heap, m_indexHeap);
963 /* added to manage the communication action's heap */
964 void surf_action_lmm_update_index_heap(void *action, int i) {
965 ((ActionLmmPtr)action)->updateIndexHeap(i);
968 void ActionLmm::updateIndexHeap(int i) {
972 double ActionLmm::getRemains()
974 XBT_IN("(%p)", this);
975 /* update remains before return it */
976 if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
977 updateRemainingLazy(surf_get_clock());
982 //FIXME split code in the right places
983 void ActionLmm::updateRemainingLazy(double now)
987 if(p_model == static_cast<ModelPtr>(surf_network_model))
989 if (m_suspended != 0)
994 xbt_assert(p_stateSet == p_model->p_runningActionSet,
995 "You're updating an action that is not running.");
997 /* bogus priority, skip it */
998 xbt_assert(m_priority > 0,
999 "You're updating an action that seems suspended.");
1002 delta = now - m_lastUpdate;
1004 if (m_remains > 0) {
1005 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1006 double_update(&m_remains, m_lastValue * delta);
1009 if (p_model == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
1010 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
1011 TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
1014 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1017 if(p_model == static_cast<ModelPtr>(surf_network_model))
1019 if (m_maxDuration != NO_MAX_DURATION)
1020 double_update(&m_maxDuration, delta);
1022 //FIXME: duplicated code
1023 if ((m_remains <= 0) &&
1024 (lmm_get_variable_weight(p_variable) > 0)) {
1025 m_finish = surf_get_clock();
1026 setState(SURF_ACTION_DONE);
1027 heapRemove(p_model->p_actionHeap);
1028 } else if (((m_maxDuration != NO_MAX_DURATION)
1029 && (m_maxDuration <= 0))) {
1030 m_finish = surf_get_clock();
1031 setState(SURF_ACTION_DONE);
1032 heapRemove(p_model->p_actionHeap);
1037 m_lastValue = lmm_variable_getvalue(p_variable);
1040 /*void Action::cancel()
1042 p_model->notifyActionCancel(this);
1045 void Action::suspend()
1047 p_model->notifyActionSuspend(this);
1050 void Action::resume()
1052 p_model->notifyActionResume(this);
1055 bool Action::isSuspended()