1 #include "surf_private.h"
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)");
22 /* This function is a pimple that we ought to fix. But it won't be easy.
24 * The surf_solve() function does properly return the set of actions that changed.
25 * Instead, each model change a global data, and then the caller of surf_solve must
26 * pick into these sets of action_failed and action_done.
28 * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
29 * We worked by putting sentinel actions on every resources we are interested in,
30 * so that surf informs us if/when the corresponding resource fails.
32 * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
33 * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
34 * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
35 * that was turned back up in the meanwhile. This is UGLY and slow.
37 * The proper solution would be to not rely on globals for the action_failed and action_done swags.
38 * They must be passed as parameter by the caller (the handling of these actions in simix may let you
39 * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
40 * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
43 * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
44 * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
45 * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
46 * sees it and react accordingly. This would kill that need for surf to call simix.
50 static void remove_watched_host(void *key)
52 xbt_dict_remove(watched_hosts_lib, *(char**)key);
55 /*void surf_watched_hosts(void)
59 xbt_dict_cursor_t cursor;
60 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
62 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
63 xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
65 if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
66 XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
67 SIMIX_host_autorestart((smx_host_t)host);
68 xbt_dynar_push_as(hosts, char*, key);
71 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
73 xbt_dynar_map(hosts, remove_watched_host);
74 xbt_dynar_free(&hosts);
77 /* model_list_invoke contains only surf_workstation and surf_vm_workstation.
78 * The callback functions of cpu_model and network_model will be called from
79 * those of these workstation models. */
80 xbt_dynar_t model_list = NULL; /* for destroying all models correctly */
81 xbt_dynar_t model_list_invoke = NULL; /* for invoking callbacks */
83 tmgr_history_t history = NULL;
84 lmm_system_t maxmin_system = NULL;
85 xbt_dynar_t surf_path = NULL;
86 xbt_dynar_t host_that_restart = NULL;
87 xbt_dict_t watched_hosts_lib;
89 /* Don't forget to update the option description in smx_config when you change this */
90 s_surf_model_description_t surf_network_model_description[] = {
92 "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). ",
93 surf_network_model_init_LegrandVelho},
95 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
96 surf_network_model_init_Constant},
98 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
99 surf_network_model_init_SMPI},
101 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
102 surf_network_model_init_CM02},
105 "Network pseudo-model using the GTNets simulator instead of an analytic model",
106 surf_network_model_init_GTNETS},
110 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
111 surf_network_model_init_NS3},
114 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
115 surf_network_model_init_Reno},
117 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
118 surf_network_model_init_Reno2},
120 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
121 surf_network_model_init_Vegas},
122 {NULL, NULL, NULL} /* this array must be NULL terminated */
125 s_surf_model_description_t surf_cpu_model_description[] = {
127 "Simplistic CPU model (time=size/power).",
128 surf_cpu_model_init_Cas01},
129 {NULL, NULL, NULL} /* this array must be NULL terminated */
132 s_surf_model_description_t surf_workstation_model_description[] = {
134 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
135 surf_workstation_model_init_current_default},
137 "Workstation model that is automatically chosen if you change the network and CPU models",
138 surf_workstation_model_init_compound},
139 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
140 surf_workstation_model_init_ptask_L07},
141 {NULL, NULL, NULL} /* this array must be NULL terminated */
144 s_surf_model_description_t surf_vm_workstation_model_description[] = {
146 "Default vm workstation model.)",
147 surf_vm_workstation_model_init_current_default},
148 {NULL, NULL, NULL} /* this array must be NULL terminated */
151 s_surf_model_description_t surf_optimization_mode_description[] = {
153 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
156 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
159 "Full update of remaining and variables. Slow but may be useful when debugging.",
161 {NULL, NULL, NULL} /* this array must be NULL terminated */
164 s_surf_model_description_t surf_storage_model_description[] = {
166 "Simplistic storage model.",
167 surf_storage_model_init_default},
168 {NULL, NULL, NULL} /* this array must be NULL terminated */
171 #ifdef CONTEXT_THREADS
172 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
175 static double *surf_mins = NULL; /* return value of share_resources for each model */
179 double surf_get_clock(void)
185 # define FILE_DELIM "\\"
187 # define FILE_DELIM "/" /* FIXME: move to better location */
190 FILE *surf_fopen(const char *name, const char *mode)
193 char *path_elm = NULL;
199 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
200 return fopen(name, mode);
202 /* search relative files in the path */
203 xbt_dynar_foreach(surf_path, cpt, path_elm) {
204 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
205 file = fopen(buff, mode);
215 * Returns the initial path. On Windows the initial path is
216 * the current directory for the current process in the other
217 * case the function returns "./" that represents the current
218 * directory on Unix/Linux platforms.
221 const char *__surf_get_initial_path(void)
226 char current_directory[MAX_PATH + 1] = { 0 };
227 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
228 char root[4] = { 0 };
233 strncpy(root, current_directory, 3);
235 for (i = 0; i < MAX_DRIVE; i++) {
236 if (toupper(root[0]) == disk_drives_letter_table[i][0])
237 return disk_drives_letter_table[i];
246 /* The __surf_is_absolute_file_path() returns 1 if
247 * file_path is a absolute file path, in the other
248 * case the function returns 0.
250 int __surf_is_absolute_file_path(const char *file_path)
253 WIN32_FIND_DATA wfd = { 0 };
254 HANDLE hFile = FindFirstFile(file_path, &wfd);
256 if (INVALID_HANDLE_VALUE == hFile)
262 return (file_path[0] == '/');
266 /** Displays the long description of all registered models, and quit */
267 void model_help(const char *category, s_surf_model_description_t * table)
270 printf("Long description of the %s models accepted by this simulator:\n",
272 for (i = 0; table[i].name; i++)
273 printf(" %s: %s\n", table[i].name, table[i].description);
276 int find_model_description(s_surf_model_description_t * table,
280 char *name_list = NULL;
282 for (i = 0; table[i].name; i++)
283 if (!strcmp(name, table[i].name)) {
286 name_list = strdup(table[0].name);
287 for (i = 1; table[i].name; i++) {
288 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
289 strcat(name_list, ", ");
290 strcat(name_list, table[i].name);
292 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
296 static XBT_INLINE void routing_asr_host_free(void *p)
298 delete ((RoutingEdgePtr) p);
301 static XBT_INLINE void routing_asr_prop_free(void *p)
303 xbt_dict_t elm = (xbt_dict_t) p;
307 static XBT_INLINE void surf_cpu_free(void *r)
309 delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
312 static XBT_INLINE void surf_link_free(void *r)
314 delete dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(r));
317 static XBT_INLINE void surf_workstation_free(void *r)
319 delete dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(r));
323 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
324 *ver_major = SIMGRID_VERSION_MAJOR;
325 *ver_minor = SIMGRID_VERSION_MINOR;
326 *ver_patch = SIMGRID_VERSION_PATCH;
329 void surf_init(int *argc, char **argv)
331 XBT_DEBUG("Create all Libs");
332 host_lib = xbt_lib_new();
333 link_lib = xbt_lib_new();
334 as_router_lib = xbt_lib_new();
335 storage_lib = xbt_lib_new();
336 storage_type_lib = xbt_lib_new();
337 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
339 XBT_DEBUG("Add routing levels");
340 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
341 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
342 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
344 XBT_DEBUG("Add SURF levels");
345 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
346 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
347 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
349 xbt_init(argc, argv);
351 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
352 if (!model_list_invoke)
353 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
355 history = tmgr_history_new();
358 TRACE_add_start_function(TRACE_surf_alloc);
359 TRACE_add_end_function(TRACE_surf_release);
362 sg_config_init(argc, argv);
371 ModelPtr model = NULL;
374 TRACE_end(); /* Just in case it was not called by the upper
375 * layer (or there is no upper layer) */
378 sg_config_finalize();
380 xbt_dynar_foreach(model_list, iter, model)
382 xbt_dynar_free(&model_list);
383 xbt_dynar_free(&model_list_invoke);
387 lmm_system_free(maxmin_system);
388 maxmin_system = NULL;
391 tmgr_history_free(history);
395 #ifdef CONTEXT_THREADS
396 xbt_parmap_destroy(surf_parmap);
400 xbt_dynar_free(&host_that_restart);
401 xbt_dynar_free(&surf_path);
403 xbt_lib_free(&host_lib);
404 xbt_lib_free(&link_lib);
405 xbt_lib_free(&as_router_lib);
406 xbt_lib_free(&storage_lib);
407 xbt_lib_free(&storage_type_lib);
409 xbt_dict_free(&watched_hosts_lib);
412 surf_parse_lex_destroy();
413 surf_parse_free_callbacks();
415 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
421 Model::Model(string name)
422 : m_name(name), m_resOnCB(0), m_resOffCB(0),
423 m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0),
426 ActionPtr action = NULL;
427 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
428 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
429 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
430 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
432 p_modifiedSet = NULL;
434 p_updateMechanism = UM_UNDEFINED;
435 m_selectiveUpdate = 0;
439 xbt_swag_free(p_readyActionSet);
440 xbt_swag_free(p_runningActionSet);
441 xbt_swag_free(p_failedActionSet);
442 xbt_swag_free(p_doneActionSet);
445 double Model::shareResources(double now)
447 //FIXME: set the good function once and for all
448 if (p_updateMechanism == UM_LAZY)
449 return shareResourcesLazy(now);
450 else if (p_updateMechanism == UM_FULL)
451 return shareResourcesFull(now);
453 xbt_die("Invalid cpu update mechanism!");
456 double Model::shareResourcesLazy(double now)
458 ActionLmmPtr action = NULL;
463 ("Before share resources, the size of modified actions set is %d",
464 xbt_swag_size(p_modifiedSet));
466 lmm_solve(p_maxminSystem);
469 ("After share resources, The size of modified actions set is %d",
470 xbt_swag_size(p_modifiedSet));
472 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
473 int max_dur_flag = 0;
475 if (action->p_stateSet != p_runningActionSet)
478 /* bogus priority, skip it */
479 if (action->m_priority <= 0)
482 action->updateRemainingLazy(now);
485 value = lmm_variable_getvalue(action->p_variable);
487 if (action->m_remains > 0) {
488 value = action->m_remains / value;
496 if ((action->m_maxDuration != NO_MAX_DURATION)
499 action->m_maxDuration < min)) {
500 min = action->m_start +
501 action->m_maxDuration;
505 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
506 action->m_start, now + value,
507 action->m_maxDuration);
510 action->heapRemove(p_actionHeap);
511 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
512 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
514 } else DIE_IMPOSSIBLE;
517 //hereafter must have already the min value for this resource model
518 if (xbt_heap_size(p_actionHeap) > 0)
519 min = xbt_heap_maxkey(p_actionHeap) - now;
523 XBT_DEBUG("The minimum with the HEAP %lf", min);
528 double Model::shareResourcesFull(double /*now*/) {
533 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
535 void (*solve) (lmm_system_t))
537 void *_action = NULL;
538 ActionLmmPtr action = NULL;
544 xbt_swag_foreach(_action, running_actions) {
545 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
546 value = lmm_variable_getvalue(action->p_variable);
547 if ((value > 0) || (action->m_maxDuration >= 0))
555 if (action->m_remains > 0)
556 min = action->m_remains / value;
559 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
560 min = action->m_maxDuration;
562 min = action->m_maxDuration;
565 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
567 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
568 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
569 value = lmm_variable_getvalue(action->p_variable);
571 if (action->m_remains > 0)
572 value = action->m_remains / value;
577 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
580 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
581 min = action->m_maxDuration;
582 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
585 XBT_DEBUG("min value : %f", min);
590 void Model::updateActionsState(double now, double delta)
592 if (p_updateMechanism == UM_FULL)
593 updateActionsStateFull(now, delta);
594 else if (p_updateMechanism == UM_LAZY)
595 updateActionsStateLazy(now, delta);
597 xbt_die("Invalid cpu update mechanism!");
600 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
605 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
611 void Model::addTurnedOnCallback(ResourceCallback rc)
616 void Model::notifyResourceTurnedOn(ResourcePtr r)
621 void Model::addTurnedOffCallback(ResourceCallback rc)
626 void Model::notifyResourceTurnedOff(ResourcePtr r)
631 void Model::addActionCancelCallback(ActionCallback ac)
636 void Model::notifyActionCancel(ActionPtr a)
641 void Model::addActionResumeCallback(ActionCallback ac)
646 void Model::notifyActionResume(ActionPtr a)
651 void Model::addActionSuspendCallback(ActionCallback ac)
656 void Model::notifyActionSuspend(ActionPtr a)
666 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
667 : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props)
670 Resource::Resource(){
671 //FIXME:free(m_name);
672 //FIXME:xbt_dict_free(&m_properties);
675 const char *Resource::getName()
680 xbt_dict_t Resource::getProperties()
685 e_surf_resource_state_t Resource::getState()
687 return p_stateCurrent;
690 void Resource::setState(e_surf_resource_state_t state)
692 p_stateCurrent = state;
695 bool Resource::isOn()
700 void Resource::turnOn()
704 p_model->notifyResourceTurnedOn(this);
708 void Resource::turnOff()
712 p_model->notifyResourceTurnedOff(this);
716 ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
718 double constraint_value,
719 tmgr_history_t history,
720 e_surf_resource_state_t state_init,
721 tmgr_trace_t state_trace,
723 tmgr_trace_t metric_trace)
724 : Resource(model, name, props)
726 p_constraint = lmm_constraint_new(system, this, constraint_value);
727 p_stateCurrent = state_init;
729 p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
731 p_power.peak = metric_peak;
733 p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
740 const char *surf_action_state_names[6] = {
742 "SURF_ACTION_RUNNING",
743 "SURF_ACTION_FAILED",
745 "SURF_ACTION_TO_FREE",
746 "SURF_ACTION_NOT_IN_THE_SYSTEM"
751 Action::Action(ModelPtr model, double cost, bool failed):
752 m_cost(cost), p_model(model), m_failed(failed), m_remains(cost),
753 m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
754 m_start(surf_get_clock()), m_finish(-1.0)
759 p_stateHookup.prev = 0;
760 p_stateHookup.next = 0;
762 p_stateSet = p_model->p_failedActionSet;
764 p_stateSet = p_model->p_runningActionSet;
766 xbt_swag_insert(this, p_stateSet);
775 void Action::cancel(){
779 void Action::recycle(){
783 e_surf_action_state_t Action::getState()
785 if (p_stateSet == p_model->p_readyActionSet)
786 return SURF_ACTION_READY;
787 if (p_stateSet == p_model->p_runningActionSet)
788 return SURF_ACTION_RUNNING;
789 if (p_stateSet == p_model->p_failedActionSet)
790 return SURF_ACTION_FAILED;
791 if (p_stateSet == p_model->p_doneActionSet)
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 = p_model->p_readyActionSet;
804 else if (state == SURF_ACTION_RUNNING)
805 p_stateSet = p_model->p_runningActionSet;
806 else if (state == SURF_ACTION_FAILED)
807 p_stateSet = p_model->p_failedActionSet;
808 else if (state == SURF_ACTION_DONE)
809 p_stateSet = p_model->p_doneActionSet;
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 (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
859 heapRemove(p_model->p_actionHeap);
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(p_model->p_maxminSystem, p_variable, priority);
871 if (p_model->p_updateMechanism == UM_LAZY)
872 heapRemove(p_model->p_actionHeap);
876 void ActionLmm::cancel(){
877 setState(SURF_ACTION_FAILED);
878 if (p_model->p_updateMechanism == UM_LAZY) {
879 xbt_swag_remove(this, p_model->p_modifiedSet);
880 heapRemove(p_model->p_actionHeap);
884 int ActionLmm::unref(){
887 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
889 lmm_variable_free(p_model->p_maxminSystem, p_variable);
890 if (p_model->p_updateMechanism == UM_LAZY) {
891 /* remove from heap */
892 heapRemove(p_model->p_actionHeap);
893 xbt_swag_remove(this, p_model->p_modifiedSet);
896 xbt_free(p_category);
904 void ActionLmm::suspend()
906 XBT_IN("(%p)", this);
907 if (m_suspended != 2) {
908 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
910 if (p_model->p_updateMechanism == UM_LAZY)
911 heapRemove(p_model->p_actionHeap);
916 void ActionLmm::resume()
918 XBT_IN("(%p)", this);
919 if (m_suspended != 2) {
920 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
922 if (p_model->p_updateMechanism == UM_LAZY)
923 heapRemove(p_model->p_actionHeap);
928 bool ActionLmm::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 ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
942 xbt_heap_push(heap, this, key);
945 void ActionLmm::heapRemove(xbt_heap_t heap)
948 if (m_indexHeap >= 0) {
949 xbt_heap_remove(heap, m_indexHeap);
953 /* added to manage the communication action's heap */
954 void surf_action_lmm_update_index_heap(void *action, int i) {
955 ((ActionLmmPtr)action)->updateIndexHeap(i);
958 void ActionLmm::updateIndexHeap(int i) {
962 double ActionLmm::getRemains()
964 XBT_IN("(%p)", this);
965 /* update remains before return it */
966 if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
967 updateRemainingLazy(surf_get_clock());
972 //FIXME split code in the right places
973 void ActionLmm::updateRemainingLazy(double now)
977 if(p_model == static_cast<ModelPtr>(surf_network_model))
979 if (m_suspended != 0)
984 xbt_assert(p_stateSet == p_model->p_runningActionSet,
985 "You're updating an action that is not running.");
987 /* bogus priority, skip it */
988 xbt_assert(m_priority > 0,
989 "You're updating an action that seems suspended.");
992 delta = now - m_lastUpdate;
995 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
996 double_update(&m_remains, m_lastValue * delta);
999 if (p_model == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
1000 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
1001 TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
1004 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1007 if(p_model == static_cast<ModelPtr>(surf_network_model))
1009 if (m_maxDuration != NO_MAX_DURATION)
1010 double_update(&m_maxDuration, delta);
1012 //FIXME: duplicated code
1013 if ((m_remains <= 0) &&
1014 (lmm_get_variable_weight(p_variable) > 0)) {
1015 m_finish = surf_get_clock();
1016 setState(SURF_ACTION_DONE);
1017 heapRemove(p_model->p_actionHeap);
1018 } else if (((m_maxDuration != NO_MAX_DURATION)
1019 && (m_maxDuration <= 0))) {
1020 m_finish = surf_get_clock();
1021 setState(SURF_ACTION_DONE);
1022 heapRemove(p_model->p_actionHeap);
1027 m_lastValue = lmm_variable_getvalue(p_variable);
1030 /*void Action::cancel()
1032 p_model->notifyActionCancel(this);
1035 void Action::suspend()
1037 p_model->notifyActionSuspend(this);
1040 void Action::resume()
1042 p_model->notifyActionResume(this);
1045 bool Action::isSuspended()