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(string name)
423 : p_maxminSystem(0), m_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->p_stateSet != p_runningActionSet)
479 /* bogus priority, skip it */
480 if (action->m_priority <= 0)
483 action->updateRemainingLazy(now);
486 value = lmm_variable_getvalue(action->p_variable);
488 if (action->m_remains > 0) {
489 value = action->m_remains / value;
497 if ((action->m_maxDuration != NO_MAX_DURATION)
500 action->m_maxDuration < min)) {
501 min = action->m_start +
502 action->m_maxDuration;
506 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
507 action->m_start, now + value,
508 action->m_maxDuration);
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->p_variable);
548 if ((value > 0) || (action->m_maxDuration >= 0))
556 if (action->m_remains > 0)
557 min = action->m_remains / value;
560 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
561 min = action->m_maxDuration;
563 min = action->m_maxDuration;
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->p_variable);
572 if (action->m_remains > 0)
573 value = action->m_remains / value;
578 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
581 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
582 min = action->m_maxDuration;
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)
667 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
668 : m_name(xbt_strdup(name)), m_properties(props), p_model(model), m_running(true)
672 : m_name(NULL), m_properties(NULL), p_model(NULL)
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(lmm_system_t system,
717 double constraint_value,
718 tmgr_history_t history,
719 e_surf_resource_state_t state_init,
720 tmgr_trace_t state_trace,
722 tmgr_trace_t metric_trace)
724 p_constraint = lmm_constraint_new(system, this, constraint_value);
725 p_stateCurrent = state_init;
727 p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
729 p_power.peak = metric_peak;
731 p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
733 p_power.event = NULL;
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"
753 Action::Action(ModelPtr model, double cost, bool failed)
756 , m_start(surf_get_clock()), m_finish(-1.0)
758 , m_maxDuration(NO_MAX_DURATION)
767 p_stateHookup.prev = 0;
768 p_stateHookup.next = 0;
770 p_stateSet = p_model->p_failedActionSet;
772 p_stateSet = p_model->p_runningActionSet;
774 xbt_swag_insert(this, p_stateSet);
783 void Action::cancel(){
787 void Action::recycle(){
791 e_surf_action_state_t Action::getState()
793 if (p_stateSet == p_model->p_readyActionSet)
794 return SURF_ACTION_READY;
795 if (p_stateSet == p_model->p_runningActionSet)
796 return SURF_ACTION_RUNNING;
797 if (p_stateSet == p_model->p_failedActionSet)
798 return SURF_ACTION_FAILED;
799 if (p_stateSet == p_model->p_doneActionSet)
800 return SURF_ACTION_DONE;
801 return SURF_ACTION_NOT_IN_THE_SYSTEM;
804 void Action::setState(e_surf_action_state_t state)
806 //surf_action_state_t action_state = &(action->model_type->states);
807 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
808 xbt_swag_remove(this, p_stateSet);
810 if (state == SURF_ACTION_READY)
811 p_stateSet = p_model->p_readyActionSet;
812 else if (state == SURF_ACTION_RUNNING)
813 p_stateSet = p_model->p_runningActionSet;
814 else if (state == SURF_ACTION_FAILED)
815 p_stateSet = p_model->p_failedActionSet;
816 else if (state == SURF_ACTION_DONE)
817 p_stateSet = p_model->p_doneActionSet;
822 xbt_swag_insert(this, p_stateSet);
826 double Action::getStartTime()
831 double Action::getFinishTime()
833 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
834 return m_remains == 0 ? m_finish : -1;
837 double Action::getRemains()
839 XBT_IN("(%p)", this);
844 void Action::setData(void* data)
850 void Action::setCategory(const char *category)
852 XBT_IN("(%p,%s)", this, category);
853 p_category = xbt_strdup(category);
862 void ActionLmm::setMaxDuration(double duration)
864 XBT_IN("(%p,%g)", this, duration);
865 m_maxDuration = duration;
866 if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
867 heapRemove(p_model->p_actionHeap);
871 void ActionLmm::gapRemove() {}
873 void ActionLmm::setPriority(double priority)
875 XBT_IN("(%p,%g)", this, priority);
876 m_priority = priority;
877 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
879 if (p_model->p_updateMechanism == UM_LAZY)
880 heapRemove(p_model->p_actionHeap);
884 void ActionLmm::cancel(){
885 setState(SURF_ACTION_FAILED);
886 if (p_model->p_updateMechanism == UM_LAZY) {
887 xbt_swag_remove(this, p_model->p_modifiedSet);
888 heapRemove(p_model->p_actionHeap);
892 int ActionLmm::unref(){
895 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
897 lmm_variable_free(p_model->p_maxminSystem, p_variable);
898 if (p_model->p_updateMechanism == UM_LAZY) {
899 /* remove from heap */
900 heapRemove(p_model->p_actionHeap);
901 xbt_swag_remove(this, p_model->p_modifiedSet);
904 xbt_free(p_category);
912 void ActionLmm::suspend()
914 XBT_IN("(%p)", this);
915 if (m_suspended != 2) {
916 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
918 if (p_model->p_updateMechanism == UM_LAZY)
919 heapRemove(p_model->p_actionHeap);
924 void ActionLmm::resume()
926 XBT_IN("(%p)", this);
927 if (m_suspended != 2) {
928 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
930 if (p_model->p_updateMechanism == UM_LAZY)
931 heapRemove(p_model->p_actionHeap);
936 bool ActionLmm::isSuspended()
938 return m_suspended == 1;
940 /* insert action on heap using a given key and a hat (heap_action_type)
941 * a hat can be of three types for communications:
943 * NORMAL = this is a normal heap entry stating the date to finish transmitting
944 * LATENCY = this is a heap entry to warn us when the latency is payed
945 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
947 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
950 xbt_heap_push(heap, this, key);
953 void ActionLmm::heapRemove(xbt_heap_t heap)
956 if (m_indexHeap >= 0) {
957 xbt_heap_remove(heap, m_indexHeap);
961 /* added to manage the communication action's heap */
962 void surf_action_lmm_update_index_heap(void *action, int i) {
963 ((ActionLmmPtr)action)->updateIndexHeap(i);
966 void ActionLmm::updateIndexHeap(int i) {
970 double ActionLmm::getRemains()
972 XBT_IN("(%p)", this);
973 /* update remains before return it */
974 if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
975 updateRemainingLazy(surf_get_clock());
980 //FIXME split code in the right places
981 void ActionLmm::updateRemainingLazy(double now)
985 if(p_model == static_cast<ModelPtr>(surf_network_model))
987 if (m_suspended != 0)
992 xbt_assert(p_stateSet == p_model->p_runningActionSet,
993 "You're updating an action that is not running.");
995 /* bogus priority, skip it */
996 xbt_assert(m_priority > 0,
997 "You're updating an action that seems suspended.");
1000 delta = now - m_lastUpdate;
1002 if (m_remains > 0) {
1003 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1004 double_update(&m_remains, m_lastValue * delta);
1007 if (p_model == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
1008 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
1009 TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
1012 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1015 if(p_model == static_cast<ModelPtr>(surf_network_model))
1017 if (m_maxDuration != NO_MAX_DURATION)
1018 double_update(&m_maxDuration, delta);
1020 //FIXME: duplicated code
1021 if ((m_remains <= 0) &&
1022 (lmm_get_variable_weight(p_variable) > 0)) {
1023 m_finish = surf_get_clock();
1024 setState(SURF_ACTION_DONE);
1025 heapRemove(p_model->p_actionHeap);
1026 } else if (((m_maxDuration != NO_MAX_DURATION)
1027 && (m_maxDuration <= 0))) {
1028 m_finish = surf_get_clock();
1029 setState(SURF_ACTION_DONE);
1030 heapRemove(p_model->p_actionHeap);
1035 m_lastValue = lmm_variable_getvalue(p_variable);
1038 /*void Action::cancel()
1040 p_model->notifyActionCancel(this);
1043 void Action::suspend()
1045 p_model->notifyActionSuspend(this);
1048 void Action::resume()
1050 p_model->notifyActionResume(this);
1053 bool Action::isSuspended()