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);
220 static const char *disk_drives_letter_table[MAX_DRIVE] = {
251 * Returns the initial path. On Windows the initial path is
252 * the current directory for the current process in the other
253 * case the function returns "./" that represents the current
254 * directory on Unix/Linux platforms.
257 const char *__surf_get_initial_path(void)
262 char current_directory[MAX_PATH + 1] = { 0 };
263 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
264 char root[4] = { 0 };
269 strncpy(root, current_directory, 3);
271 for (i = 0; i < MAX_DRIVE; i++) {
272 if (toupper(root[0]) == disk_drives_letter_table[i][0])
273 return disk_drives_letter_table[i];
282 /* The __surf_is_absolute_file_path() returns 1 if
283 * file_path is a absolute file path, in the other
284 * case the function returns 0.
286 int __surf_is_absolute_file_path(const char *file_path)
289 WIN32_FIND_DATA wfd = { 0 };
290 HANDLE hFile = FindFirstFile(file_path, &wfd);
292 if (INVALID_HANDLE_VALUE == hFile)
298 return (file_path[0] == '/');
302 /** Displays the long description of all registered models, and quit */
303 void model_help(const char *category, s_surf_model_description_t * table)
306 printf("Long description of the %s models accepted by this simulator:\n",
308 for (i = 0; table[i].name; i++)
309 printf(" %s: %s\n", table[i].name, table[i].description);
312 int find_model_description(s_surf_model_description_t * table,
316 char *name_list = NULL;
318 for (i = 0; table[i].name; i++)
319 if (!strcmp(name, table[i].name)) {
322 name_list = strdup(table[0].name);
323 for (i = 1; table[i].name; i++) {
324 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
325 strcat(name_list, ", ");
326 strcat(name_list, table[i].name);
328 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
332 static XBT_INLINE void routing_asr_host_free(void *p)
334 delete ((RoutingEdgePtr) p);
337 static XBT_INLINE void routing_asr_prop_free(void *p)
339 xbt_dict_t elm = (xbt_dict_t) p;
343 static XBT_INLINE void surf_cpu_free(void *r)
345 delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
348 static XBT_INLINE void surf_link_free(void *r)
350 delete dynamic_cast<NetworkLinkPtr>(static_cast<ResourcePtr>(r));
353 static XBT_INLINE void surf_workstation_free(void *r)
355 delete dynamic_cast<WorkstationPtr>(static_cast<ResourcePtr>(r));
359 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
360 *ver_major = SIMGRID_VERSION_MAJOR;
361 *ver_minor = SIMGRID_VERSION_MINOR;
362 *ver_patch = SIMGRID_VERSION_PATCH;
365 void surf_init(int *argc, char **argv)
367 XBT_DEBUG("Create all Libs");
368 host_lib = xbt_lib_new();
369 link_lib = xbt_lib_new();
370 as_router_lib = xbt_lib_new();
371 storage_lib = xbt_lib_new();
372 storage_type_lib = xbt_lib_new();
373 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
375 XBT_DEBUG("Add routing levels");
376 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
377 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
378 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
380 XBT_DEBUG("Add SURF levels");
381 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
382 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
383 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
385 xbt_init(argc, argv);
387 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
388 if (!model_list_invoke)
389 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
391 history = tmgr_history_new();
394 TRACE_add_start_function(TRACE_surf_alloc);
395 TRACE_add_end_function(TRACE_surf_release);
398 sg_config_init(argc, argv);
407 ModelPtr model = NULL;
410 TRACE_end(); /* Just in case it was not called by the upper
411 * layer (or there is no upper layer) */
414 sg_config_finalize();
416 xbt_dynar_foreach(model_list, iter, model)
418 xbt_dynar_free(&model_list);
419 xbt_dynar_free(&model_list_invoke);
423 lmm_system_free(maxmin_system);
424 maxmin_system = NULL;
427 tmgr_history_free(history);
431 #ifdef CONTEXT_THREADS
432 xbt_parmap_destroy(surf_parmap);
438 xbt_dynar_free(&host_that_restart);
439 xbt_dynar_free(&surf_path);
441 xbt_lib_free(&host_lib);
442 xbt_lib_free(&link_lib);
443 xbt_lib_free(&as_router_lib);
444 xbt_lib_free(&storage_lib);
445 xbt_lib_free(&storage_type_lib);
447 xbt_dict_free(&watched_hosts_lib);
450 surf_parse_lex_destroy();
451 surf_parse_free_callbacks();
453 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
459 Model::Model(const char *name)
460 : p_maxminSystem(0), p_name(name),
461 m_resOnCB(0), m_resOffCB(0),
462 m_actCancelCB(0), m_actSuspendCB(0), m_actResumeCB(0)
464 ActionPtr action = NULL;
465 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
466 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
467 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
468 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
470 p_modifiedSet = NULL;
472 p_updateMechanism = UM_UNDEFINED;
473 m_selectiveUpdate = 0;
477 xbt_swag_free(p_readyActionSet);
478 xbt_swag_free(p_runningActionSet);
479 xbt_swag_free(p_failedActionSet);
480 xbt_swag_free(p_doneActionSet);
483 double Model::shareResources(double now)
485 //FIXME: set the good function once and for all
486 if (p_updateMechanism == UM_LAZY)
487 return shareResourcesLazy(now);
488 else if (p_updateMechanism == UM_FULL)
489 return shareResourcesFull(now);
491 xbt_die("Invalid cpu update mechanism!");
494 double Model::shareResourcesLazy(double now)
496 ActionLmmPtr action = NULL;
501 ("Before share resources, the size of modified actions set is %d",
502 xbt_swag_size(p_modifiedSet));
504 lmm_solve(p_maxminSystem);
507 ("After share resources, The size of modified actions set is %d",
508 xbt_swag_size(p_modifiedSet));
510 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
511 int max_dur_flag = 0;
513 if (action->getStateSet() != p_runningActionSet)
516 /* bogus priority, skip it */
517 if (action->getPriority() <= 0)
520 action->updateRemainingLazy(now);
523 value = lmm_variable_getvalue(action->getVariable());
525 if (action->getRemains() > 0) {
526 value = action->getRemains() / value;
534 if ((action->getMaxDuration() != NO_MAX_DURATION)
536 || action->getStartTime() +
537 action->getMaxDuration() < min)) {
538 min = action->getStartTime() +
539 action->getMaxDuration();
543 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
544 action->getStartTime(), now + value,
545 action->getMaxDuration());
548 action->heapRemove(p_actionHeap);
549 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
550 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
552 } else DIE_IMPOSSIBLE;
555 //hereafter must have already the min value for this resource model
556 if (xbt_heap_size(p_actionHeap) > 0)
557 min = xbt_heap_maxkey(p_actionHeap) - now;
561 XBT_DEBUG("The minimum with the HEAP %lf", min);
566 double Model::shareResourcesFull(double /*now*/) {
571 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
573 void (*solve) (lmm_system_t))
575 void *_action = NULL;
576 ActionLmmPtr action = NULL;
582 xbt_swag_foreach(_action, running_actions) {
583 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
584 value = lmm_variable_getvalue(action->getVariable());
585 if ((value > 0) || (action->getMaxDuration() >= 0))
593 if (action->getRemains() > 0)
594 min = action->getRemains() / value;
597 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
598 min = action->getMaxDuration();
600 min = action->getMaxDuration();
603 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
605 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
606 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
607 value = lmm_variable_getvalue(action->getVariable());
609 if (action->getRemains() > 0)
610 value = action->getRemains() / value;
615 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
618 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
619 min = action->getMaxDuration();
620 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
623 XBT_DEBUG("min value : %f", min);
628 void Model::updateActionsState(double now, double delta)
630 if (p_updateMechanism == UM_FULL)
631 updateActionsStateFull(now, delta);
632 else if (p_updateMechanism == UM_LAZY)
633 updateActionsStateLazy(now, delta);
635 xbt_die("Invalid cpu update mechanism!");
638 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
643 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
649 void Model::addTurnedOnCallback(ResourceCallback rc)
654 void Model::notifyResourceTurnedOn(ResourcePtr r)
659 void Model::addTurnedOffCallback(ResourceCallback rc)
664 void Model::notifyResourceTurnedOff(ResourcePtr r)
669 void Model::addActionCancelCallback(ActionCallback ac)
674 void Model::notifyActionCancel(ActionPtr a)
679 void Model::addActionResumeCallback(ActionCallback ac)
684 void Model::notifyActionResume(ActionPtr a)
689 void Model::addActionSuspendCallback(ActionCallback ac)
694 void Model::notifyActionSuspend(ActionPtr a)
705 : p_name(NULL), p_properties(NULL), p_model(NULL)
708 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
709 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
710 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
713 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
714 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
715 , m_running(true), m_stateCurrent(stateInit)
718 e_surf_resource_state_t Resource::getState()
720 return m_stateCurrent;
723 void Resource::setState(e_surf_resource_state_t state)
725 m_stateCurrent = state;
728 bool Resource::isOn()
733 void Resource::turnOn()
737 getModel()->notifyResourceTurnedOn(this);
741 void Resource::turnOff()
745 getModel()->notifyResourceTurnedOff(this);
749 ResourceLmm::ResourceLmm()
753 ResourceLmm::ResourceLmm(lmm_constraint_t constraint)
754 : p_constraint(constraint)
761 const char *surf_action_state_names[6] = {
763 "SURF_ACTION_RUNNING",
764 "SURF_ACTION_FAILED",
766 "SURF_ACTION_TO_FREE",
767 "SURF_ACTION_NOT_IN_THE_SYSTEM"
774 Action::Action(ModelPtr model, double cost, bool failed)
777 , m_start(surf_get_clock()), m_finish(-1.0)
779 , m_maxDuration(NO_MAX_DURATION)
788 p_stateHookup.prev = 0;
789 p_stateHookup.next = 0;
791 p_stateSet = getModel()->getFailedActionSet();
793 p_stateSet = getModel()->getRunningActionSet();
795 xbt_swag_insert(this, p_stateSet);
800 xbt_free(p_category);
804 void Action::finish() {
805 m_finish = surf_get_clock();
812 void Action::cancel(){
816 void Action::recycle(){
820 e_surf_action_state_t Action::getState()
822 if (p_stateSet == getModel()->getReadyActionSet())
823 return SURF_ACTION_READY;
824 if (p_stateSet == getModel()->getRunningActionSet())
825 return SURF_ACTION_RUNNING;
826 if (p_stateSet == getModel()->getFailedActionSet())
827 return SURF_ACTION_FAILED;
828 if (p_stateSet == getModel()->getDoneActionSet())
829 return SURF_ACTION_DONE;
830 return SURF_ACTION_NOT_IN_THE_SYSTEM;
833 void Action::setState(e_surf_action_state_t state)
835 //surf_action_state_t action_state = &(action->model_type->states);
836 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
837 xbt_swag_remove(this, p_stateSet);
839 if (state == SURF_ACTION_READY)
840 p_stateSet = getModel()->getReadyActionSet();
841 else if (state == SURF_ACTION_RUNNING)
842 p_stateSet = getModel()->getRunningActionSet();
843 else if (state == SURF_ACTION_FAILED)
844 p_stateSet = getModel()->getFailedActionSet();
845 else if (state == SURF_ACTION_DONE)
846 p_stateSet = getModel()->getDoneActionSet();
851 xbt_swag_insert(this, p_stateSet);
855 double Action::getStartTime()
860 double Action::getFinishTime()
862 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
863 return m_remains == 0 ? m_finish : -1;
866 double Action::getRemains()
868 XBT_IN("(%p)", this);
873 void Action::setData(void* data)
879 void Action::setCategory(const char *category)
881 XBT_IN("(%p,%s)", this, category);
882 p_category = xbt_strdup(category);
891 void ActionLmm::setMaxDuration(double duration)
893 XBT_IN("(%p,%g)", this, duration);
894 m_maxDuration = duration;
895 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
896 heapRemove(getModel()->getActionHeap());
900 void ActionLmm::gapRemove() {}
902 void ActionLmm::setPriority(double priority)
904 XBT_IN("(%p,%g)", this, priority);
905 m_priority = priority;
906 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
908 if (getModel()->getUpdateMechanism() == UM_LAZY)
909 heapRemove(getModel()->getActionHeap());
913 void ActionLmm::cancel(){
914 setState(SURF_ACTION_FAILED);
915 if (getModel()->getUpdateMechanism() == UM_LAZY) {
916 xbt_swag_remove(this, getModel()->getModifiedSet());
917 heapRemove(getModel()->getActionHeap());
921 int ActionLmm::unref(){
924 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
926 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
927 if (getModel()->getUpdateMechanism() == UM_LAZY) {
928 /* remove from heap */
929 heapRemove(getModel()->getActionHeap());
930 xbt_swag_remove(this, getModel()->getModifiedSet());
938 void ActionLmm::suspend()
940 XBT_IN("(%p)", this);
941 if (m_suspended != 2) {
942 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
944 if (getModel()->getUpdateMechanism() == UM_LAZY)
945 heapRemove(getModel()->getActionHeap());
950 void ActionLmm::resume()
952 XBT_IN("(%p)", this);
953 if (m_suspended != 2) {
954 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
956 if (getModel()->getUpdateMechanism() == UM_LAZY)
957 heapRemove(getModel()->getActionHeap());
962 bool ActionLmm::isSuspended()
964 return m_suspended == 1;
966 /* insert action on heap using a given key and a hat (heap_action_type)
967 * a hat can be of three types for communications:
969 * NORMAL = this is a normal heap entry stating the date to finish transmitting
970 * LATENCY = this is a heap entry to warn us when the latency is payed
971 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
973 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
976 xbt_heap_push(heap, this, key);
979 void ActionLmm::heapRemove(xbt_heap_t heap)
982 if (m_indexHeap >= 0) {
983 xbt_heap_remove(heap, m_indexHeap);
987 /* added to manage the communication action's heap */
988 void surf_action_lmm_update_index_heap(void *action, int i) {
989 ((ActionLmmPtr)action)->updateIndexHeap(i);
992 void ActionLmm::updateIndexHeap(int i) {
996 double ActionLmm::getRemains()
998 XBT_IN("(%p)", this);
999 /* update remains before return it */
1000 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
1001 updateRemainingLazy(surf_get_clock());
1006 //FIXME split code in the right places
1007 void ActionLmm::updateRemainingLazy(double now)
1011 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1013 if (m_suspended != 0)
1018 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
1019 "You're updating an action that is not running.");
1021 /* bogus priority, skip it */
1022 xbt_assert(m_priority > 0,
1023 "You're updating an action that seems suspended.");
1026 delta = now - m_lastUpdate;
1028 if (m_remains > 0) {
1029 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1030 double_update(&m_remains, m_lastValue * delta);
1033 if (getModel() == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
1034 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
1035 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1038 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1041 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1043 if (m_maxDuration != NO_MAX_DURATION)
1044 double_update(&m_maxDuration, delta);
1046 //FIXME: duplicated code
1047 if ((m_remains <= 0) &&
1048 (lmm_get_variable_weight(getVariable()) > 0)) {
1050 setState(SURF_ACTION_DONE);
1051 heapRemove(getModel()->getActionHeap());
1052 } else if (((m_maxDuration != NO_MAX_DURATION)
1053 && (m_maxDuration <= 0))) {
1055 setState(SURF_ACTION_DONE);
1056 heapRemove(getModel()->getActionHeap());
1061 m_lastValue = lmm_variable_getvalue(getVariable());
1064 /*void Action::cancel()
1066 p_model->notifyActionCancel(this);
1069 void Action::suspend()
1071 p_model->notifyActionSuspend(this);
1074 void Action::resume()
1076 p_model->notifyActionResume(this);
1079 bool Action::isSuspended()