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 s_surf_model_description_t surf_plugin_description[] = {
89 "Cpu energy consumption.",
90 sg_energy_plugin_init},
91 {NULL, NULL, NULL} /* this array must be NULL terminated */
94 /* Don't forget to update the option description in smx_config when you change this */
95 s_surf_model_description_t surf_network_model_description[] = {
97 "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). ",
98 surf_network_model_init_LegrandVelho},
100 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
101 surf_network_model_init_Constant},
103 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
104 surf_network_model_init_SMPI},
106 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
107 surf_network_model_init_CM02},
110 "Network pseudo-model using the GTNets simulator instead of an analytic model",
111 surf_network_model_init_GTNETS},
115 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
116 surf_network_model_init_NS3},
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_Reno},
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_Reno2},
125 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
126 surf_network_model_init_Vegas},
127 {NULL, NULL, NULL} /* this array must be NULL terminated */
130 s_surf_model_description_t surf_cpu_model_description[] = {
132 "Simplistic CPU model (time=size/power).",
133 surf_cpu_model_init_Cas01},
134 {NULL, NULL, NULL} /* this array must be NULL terminated */
137 s_surf_model_description_t surf_workstation_model_description[] = {
139 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
140 surf_workstation_model_init_current_default},
142 "Workstation model that is automatically chosen if you change the network and CPU models",
143 surf_workstation_model_init_compound},
144 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
145 surf_workstation_model_init_ptask_L07},
146 {NULL, NULL, NULL} /* this array must be NULL terminated */
149 s_surf_model_description_t surf_vm_workstation_model_description[] = {
151 "Default vm workstation model.)",
152 surf_vm_workstation_model_init_current_default},
153 {NULL, NULL, NULL} /* this array must be NULL terminated */
156 s_surf_model_description_t surf_optimization_mode_description[] = {
158 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
161 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
164 "Full update of remaining and variables. Slow but may be useful when debugging.",
166 {NULL, NULL, NULL} /* this array must be NULL terminated */
169 s_surf_model_description_t surf_storage_model_description[] = {
171 "Simplistic storage model.",
172 surf_storage_model_init_default},
173 {NULL, NULL, NULL} /* this array must be NULL terminated */
176 #ifdef CONTEXT_THREADS
177 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
181 double *surf_mins = NULL; /* return value of share_resources for each model */
182 int surf_min_index; /* current index in surf_mins */
183 double surf_min; /* duration determined by surf_solve */
185 double surf_get_clock(void)
191 # define FILE_DELIM "\\"
193 # define FILE_DELIM "/" /* FIXME: move to better location */
196 FILE *surf_fopen(const char *name, const char *mode)
199 char *path_elm = NULL;
205 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
206 return fopen(name, mode);
208 /* search relative files in the path */
209 xbt_dynar_foreach(surf_path, cpt, path_elm) {
210 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
211 file = fopen(buff, mode);
227 static const char *disk_drives_letter_table[MAX_DRIVE] = {
258 * Returns the initial path. On Windows the initial path is
259 * the current directory for the current process in the other
260 * case the function returns "./" that represents the current
261 * directory on Unix/Linux platforms.
264 const char *__surf_get_initial_path(void)
269 char current_directory[MAX_PATH + 1] = { 0 };
270 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
271 char root[4] = { 0 };
276 strncpy(root, current_directory, 3);
278 for (i = 0; i < MAX_DRIVE; i++) {
279 if (toupper(root[0]) == disk_drives_letter_table[i][0])
280 return disk_drives_letter_table[i];
289 /* The __surf_is_absolute_file_path() returns 1 if
290 * file_path is a absolute file path, in the other
291 * case the function returns 0.
293 int __surf_is_absolute_file_path(const char *file_path)
296 WIN32_FIND_DATA wfd = { 0 };
297 HANDLE hFile = FindFirstFile(file_path, &wfd);
299 if (INVALID_HANDLE_VALUE == hFile)
305 return (file_path[0] == '/');
309 /** Displays the long description of all registered models, and quit */
310 void model_help(const char *category, s_surf_model_description_t * table)
313 printf("Long description of the %s models accepted by this simulator:\n",
315 for (i = 0; table[i].name; i++)
316 printf(" %s: %s\n", table[i].name, table[i].description);
319 int find_model_description(s_surf_model_description_t * table,
323 char *name_list = NULL;
325 for (i = 0; table[i].name; i++)
326 if (!strcmp(name, table[i].name)) {
329 name_list = strdup(table[0].name);
330 for (i = 1; table[i].name; i++) {
331 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
332 strcat(name_list, ", ");
333 strcat(name_list, table[i].name);
335 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
339 static XBT_INLINE void routing_asr_host_free(void *p)
341 delete ((RoutingEdgePtr) p);
344 static XBT_INLINE void routing_asr_prop_free(void *p)
346 xbt_dict_t elm = (xbt_dict_t) p;
350 static XBT_INLINE void surf_cpu_free(void *r)
352 delete static_cast<CpuPtr>(r);
355 static XBT_INLINE void surf_link_free(void *r)
357 delete static_cast<NetworkLinkPtr>(r);
360 static XBT_INLINE void surf_workstation_free(void *r)
362 delete static_cast<WorkstationPtr>(r);
366 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
367 *ver_major = SIMGRID_VERSION_MAJOR;
368 *ver_minor = SIMGRID_VERSION_MINOR;
369 *ver_patch = SIMGRID_VERSION_PATCH;
372 void surf_init(int *argc, char **argv)
374 XBT_DEBUG("Create all Libs");
375 host_lib = xbt_lib_new();
376 link_lib = xbt_lib_new();
377 as_router_lib = xbt_lib_new();
378 storage_lib = xbt_lib_new();
379 storage_type_lib = xbt_lib_new();
380 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
382 XBT_DEBUG("Add routing levels");
383 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
384 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
385 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
387 XBT_DEBUG("Add SURF levels");
388 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
389 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
390 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
392 xbt_init(argc, argv);
394 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
395 if (!model_list_invoke)
396 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
398 history = tmgr_history_new();
401 TRACE_add_start_function(TRACE_surf_alloc);
402 TRACE_add_end_function(TRACE_surf_release);
405 sg_config_init(argc, argv);
414 ModelPtr model = NULL;
417 TRACE_end(); /* Just in case it was not called by the upper
418 * layer (or there is no upper layer) */
421 sg_config_finalize();
423 xbt_dynar_foreach(model_list, iter, model)
425 xbt_dynar_free(&model_list);
426 xbt_dynar_free(&model_list_invoke);
430 lmm_system_free(maxmin_system);
431 maxmin_system = NULL;
434 tmgr_history_free(history);
438 #ifdef CONTEXT_THREADS
439 xbt_parmap_destroy(surf_parmap);
445 xbt_dynar_free(&host_that_restart);
446 xbt_dynar_free(&surf_path);
448 xbt_lib_free(&host_lib);
449 xbt_lib_free(&link_lib);
450 xbt_lib_free(&as_router_lib);
451 xbt_lib_free(&storage_lib);
452 xbt_lib_free(&storage_type_lib);
454 xbt_dict_free(&watched_hosts_lib);
457 surf_parse_lex_destroy();
458 surf_parse_free_callbacks();
460 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
466 Model::Model(const char *name)
467 : p_name(name), p_maxminSystem(0),
468 m_resOnCB(0), m_resOffCB(0),
469 m_actCancelCB(0), m_actSuspendCB(0), m_actResumeCB(0)
471 p_readyActionSet = new ActionList();
472 p_runningActionSet = new ActionList();
473 p_failedActionSet = new ActionList();
474 p_doneActionSet = new ActionList();
476 p_modifiedSet = NULL;
478 p_updateMechanism = UM_UNDEFINED;
479 m_selectiveUpdate = 0;
483 delete p_readyActionSet;
484 delete p_runningActionSet;
485 delete p_failedActionSet;
486 delete p_doneActionSet;
489 double Model::shareResources(double now)
491 //FIXME: set the good function once and for all
492 if (p_updateMechanism == UM_LAZY)
493 return shareResourcesLazy(now);
494 else if (p_updateMechanism == UM_FULL)
495 return shareResourcesFull(now);
497 xbt_die("Invalid cpu update mechanism!");
500 double Model::shareResourcesLazy(double now)
502 ActionPtr action = NULL;
507 ("Before share resources, the size of modified actions set is %d",
508 p_modifiedSet->size());
510 lmm_solve(p_maxminSystem);
513 ("After share resources, The size of modified actions set is %d",
514 p_modifiedSet->size());
516 while(!p_modifiedSet->empty()) {
517 action = &(p_modifiedSet->front());
518 p_modifiedSet->pop_front();
519 int max_dur_flag = 0;
521 if (action->getStateSet() != p_runningActionSet)
524 /* bogus priority, skip it */
525 if (action->getPriority() <= 0)
528 action->updateRemainingLazy(now);
531 value = lmm_variable_getvalue(action->getVariable());
533 if (action->getRemains() > 0) {
534 value = action->getRemains() / value;
542 if ((action->getMaxDuration() != NO_MAX_DURATION)
544 || action->getStartTime() +
545 action->getMaxDuration() < min)) {
546 min = action->getStartTime() +
547 action->getMaxDuration();
551 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
552 action->getStartTime(), now + value,
553 action->getMaxDuration());
556 action->heapRemove(p_actionHeap);
557 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
558 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
560 } else DIE_IMPOSSIBLE;
563 //hereafter must have already the min value for this resource model
564 if (xbt_heap_size(p_actionHeap) > 0)
565 min = xbt_heap_maxkey(p_actionHeap) - now;
569 XBT_DEBUG("The minimum with the HEAP %lf", min);
574 double Model::shareResourcesFull(double /*now*/) {
579 double Model::shareResourcesMaxMin(ActionListPtr running_actions,
581 void (*solve) (lmm_system_t))
583 void *_action = NULL;
584 ActionPtr action = NULL;
590 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
591 for(; it != itend ; ++it) {
593 value = lmm_variable_getvalue(action->getVariable());
594 if ((value > 0) || (action->getMaxDuration() >= 0))
602 if (action->getRemains() > 0)
603 min = action->getRemains() / value;
606 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
607 min = action->getMaxDuration();
609 min = action->getMaxDuration();
612 for (++it; it != itend; ++it) {
614 value = lmm_variable_getvalue(action->getVariable());
616 if (action->getRemains() > 0)
617 value = action->getRemains() / value;
622 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
625 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
626 min = action->getMaxDuration();
627 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
630 XBT_DEBUG("min value : %f", min);
635 void Model::updateActionsState(double now, double delta)
637 if (p_updateMechanism == UM_FULL)
638 updateActionsStateFull(now, delta);
639 else if (p_updateMechanism == UM_LAZY)
640 updateActionsStateLazy(now, delta);
642 xbt_die("Invalid cpu update mechanism!");
645 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
650 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
656 void Model::addTurnedOnCallback(ResourceCallback rc)
661 void Model::notifyResourceTurnedOn(ResourcePtr r)
666 void Model::addTurnedOffCallback(ResourceCallback rc)
671 void Model::notifyResourceTurnedOff(ResourcePtr r)
676 void Model::addActionCancelCallback(ActionCallback ac)
681 void Model::notifyActionCancel(ActionPtr a)
686 void Model::addActionResumeCallback(ActionCallback ac)
691 void Model::notifyActionResume(ActionPtr a)
696 void Model::addActionSuspendCallback(ActionCallback ac)
701 void Model::notifyActionSuspend(ActionPtr a)
712 : p_name(NULL), p_properties(NULL), p_model(NULL)
715 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
716 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
717 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
720 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
721 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
722 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON), p_constraint(constraint)
725 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
726 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
727 , m_running(true), m_stateCurrent(stateInit)
730 e_surf_resource_state_t Resource::getState()
732 return m_stateCurrent;
735 void Resource::setState(e_surf_resource_state_t state)
737 m_stateCurrent = state;
740 bool Resource::isOn()
745 void Resource::turnOn()
749 getModel()->notifyResourceTurnedOn(this);
753 void Resource::turnOff()
757 getModel()->notifyResourceTurnedOff(this);
765 const char *surf_action_state_names[6] = {
767 "SURF_ACTION_RUNNING",
768 "SURF_ACTION_FAILED",
770 "SURF_ACTION_TO_FREE",
771 "SURF_ACTION_NOT_IN_THE_SYSTEM"
778 Action::Action(ModelPtr model, double cost, bool failed)
781 , m_start(surf_get_clock()), m_finish(-1.0)
783 , m_maxDuration(NO_MAX_DURATION)
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)
809 , m_start(surf_get_clock()), m_finish(-1.0)
811 , m_maxDuration(NO_MAX_DURATION)
824 p_stateHookup.prev = 0;
825 p_stateHookup.next = 0;
827 p_stateSet = getModel()->getFailedActionSet();
829 p_stateSet = getModel()->getRunningActionSet();
831 p_stateSet->push_back(*this);
836 xbt_free(p_category);
840 void Action::finish() {
841 m_finish = surf_get_clock();
844 e_surf_action_state_t Action::getState()
846 if (p_stateSet == getModel()->getReadyActionSet())
847 return SURF_ACTION_READY;
848 if (p_stateSet == getModel()->getRunningActionSet())
849 return SURF_ACTION_RUNNING;
850 if (p_stateSet == getModel()->getFailedActionSet())
851 return SURF_ACTION_FAILED;
852 if (p_stateSet == getModel()->getDoneActionSet())
853 return SURF_ACTION_DONE;
854 return SURF_ACTION_NOT_IN_THE_SYSTEM;
857 void Action::setState(e_surf_action_state_t state)
859 //surf_action_state_t action_state = &(action->model_type->states);
860 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
861 p_stateSet->erase(p_stateSet->iterator_to(*this));
862 if (state == SURF_ACTION_READY)
863 p_stateSet = getModel()->getReadyActionSet();
864 else if (state == SURF_ACTION_RUNNING)
865 p_stateSet = getModel()->getRunningActionSet();
866 else if (state == SURF_ACTION_FAILED)
867 p_stateSet = getModel()->getFailedActionSet();
868 else if (state == SURF_ACTION_DONE)
869 p_stateSet = getModel()->getDoneActionSet();
874 p_stateSet->push_back(*this);
878 double Action::getStartTime()
883 double Action::getFinishTime()
885 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
886 return m_remains == 0 ? m_finish : -1;
889 void Action::setData(void* data)
895 void Action::setCategory(const char *category)
897 XBT_IN("(%p,%s)", this, category);
898 p_category = xbt_strdup(category);
907 void Action::setMaxDuration(double duration)
909 XBT_IN("(%p,%g)", this, duration);
910 m_maxDuration = duration;
911 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
912 heapRemove(getModel()->getActionHeap());
916 void Action::gapRemove() {}
918 void Action::setPriority(double priority)
920 XBT_IN("(%p,%g)", this, priority);
921 m_priority = priority;
922 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
924 if (getModel()->getUpdateMechanism() == UM_LAZY)
925 heapRemove(getModel()->getActionHeap());
929 void Action::cancel(){
930 setState(SURF_ACTION_FAILED);
931 if (getModel()->getUpdateMechanism() == UM_LAZY) {
932 if (actionLmmHook::is_linked())
933 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
934 heapRemove(getModel()->getActionHeap());
941 if (actionHook::is_linked())
942 p_stateSet->erase(p_stateSet->iterator_to(*this));
944 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
945 if (getModel()->getUpdateMechanism() == UM_LAZY) {
946 /* remove from heap */
947 heapRemove(getModel()->getActionHeap());
948 if (actionLmmHook::is_linked())
949 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
957 void Action::suspend()
959 XBT_IN("(%p)", this);
960 if (m_suspended != 2) {
961 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
963 if (getModel()->getUpdateMechanism() == UM_LAZY)
964 heapRemove(getModel()->getActionHeap());
969 void Action::resume()
971 XBT_IN("(%p)", this);
972 if (m_suspended != 2) {
973 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
975 if (getModel()->getUpdateMechanism() == UM_LAZY)
976 heapRemove(getModel()->getActionHeap());
981 bool Action::isSuspended()
983 return m_suspended == 1;
985 /* insert action on heap using a given key and a hat (heap_action_type)
986 * a hat can be of three types for communications:
988 * NORMAL = this is a normal heap entry stating the date to finish transmitting
989 * LATENCY = this is a heap entry to warn us when the latency is payed
990 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
992 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
995 xbt_heap_push(heap, this, key);
998 void Action::heapRemove(xbt_heap_t heap)
1001 if (m_indexHeap >= 0) {
1002 xbt_heap_remove(heap, m_indexHeap);
1006 /* added to manage the communication action's heap */
1007 void surf_action_lmm_update_index_heap(void *action, int i) {
1008 ((ActionPtr)action)->updateIndexHeap(i);
1011 void Action::updateIndexHeap(int i) {
1015 double Action::getRemains()
1017 XBT_IN("(%p)", this);
1018 /* update remains before return it */
1019 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
1020 updateRemainingLazy(surf_get_clock());
1025 double Action::getRemainsNoUpdate()
1030 //FIXME split code in the right places
1031 void Action::updateRemainingLazy(double now)
1035 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1037 if (m_suspended != 0)
1042 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
1043 "You're updating an action that is not running.");
1045 /* bogus priority, skip it */
1046 xbt_assert(m_priority > 0,
1047 "You're updating an action that seems suspended.");
1050 delta = now - m_lastUpdate;
1052 if (m_remains > 0) {
1053 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1054 double_update(&m_remains, m_lastValue * delta);
1057 if (getModel() == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
1058 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
1059 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1062 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1065 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1067 if (m_maxDuration != NO_MAX_DURATION)
1068 double_update(&m_maxDuration, delta);
1070 //FIXME: duplicated code
1071 if ((m_remains <= 0) &&
1072 (lmm_get_variable_weight(getVariable()) > 0)) {
1074 setState(SURF_ACTION_DONE);
1075 heapRemove(getModel()->getActionHeap());
1076 } else if (((m_maxDuration != NO_MAX_DURATION)
1077 && (m_maxDuration <= 0))) {
1079 setState(SURF_ACTION_DONE);
1080 heapRemove(getModel()->getActionHeap());
1085 m_lastValue = lmm_variable_getvalue(getVariable());