1 #include "surf_private.h"
5 #include "workstation.hpp"
6 #include "simix/smx_host_private.h"
7 #include "surf_routing.hpp"
8 #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)");
21 /* This function is a pimple that we ought to fix. But it won't be easy.
23 * The surf_solve() function does properly return the set of actions that changed.
24 * Instead, each model change a global data, and then the caller of surf_solve must
25 * pick into these sets of action_failed and action_done.
27 * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
28 * We worked by putting sentinel actions on every resources we are interested in,
29 * so that surf informs us if/when the corresponding resource fails.
31 * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
32 * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
33 * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
34 * that was turned back up in the meanwhile. This is UGLY and slow.
36 * The proper solution would be to not rely on globals for the action_failed and action_done swags.
37 * They must be passed as parameter by the caller (the handling of these actions in simix may let you
38 * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
39 * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
42 * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
43 * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
44 * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
45 * sees it and react accordingly. This would kill that need for surf to call simix.
49 static void remove_watched_host(void *key)
51 xbt_dict_remove(watched_hosts_lib, *(char**)key);
54 /*void surf_watched_hosts(void)
58 xbt_dict_cursor_t cursor;
59 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
61 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
62 xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
64 if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
65 XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
66 SIMIX_host_autorestart((smx_host_t)host);
67 xbt_dynar_push_as(hosts, char*, key);
70 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
72 xbt_dynar_map(hosts, remove_watched_host);
73 xbt_dynar_free(&hosts);
77 xbt_dynar_t model_list = NULL;
78 tmgr_history_t history = NULL;
79 lmm_system_t maxmin_system = NULL;
80 xbt_dynar_t surf_path = NULL;
81 xbt_dynar_t host_that_restart = NULL;
82 xbt_dict_t watched_hosts_lib;
84 /* Don't forget to update the option description in smx_config when you change this */
85 s_surf_model_description_t surf_network_model_description[] = {
87 "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). ",
88 surf_network_model_init_LegrandVelho},
90 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
91 surf_network_model_init_Constant},
93 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
94 surf_network_model_init_SMPI},
96 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
97 surf_network_model_init_CM02},
100 "Network pseudo-model using the GTNets simulator instead of an analytic model",
101 surf_network_model_init_GTNETS},
105 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
106 surf_network_model_init_NS3},
109 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
110 surf_network_model_init_Reno},
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_Reno2},
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_Vegas},
117 {NULL, NULL, NULL} /* this array must be NULL terminated */
120 s_surf_model_description_t surf_cpu_model_description[] = {
122 "Simplistic CPU model (time=size/power).",
123 surf_cpu_model_init_Cas01},
124 {NULL, NULL, NULL} /* this array must be NULL terminated */
127 s_surf_model_description_t surf_workstation_model_description[] = {
129 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
130 surf_workstation_model_init_current_default},
132 "Workstation model that is automatically chosen if you change the network and CPU models",
133 surf_workstation_model_init_compound},
134 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
135 surf_workstation_model_init_ptask_L07},
136 {NULL, NULL, NULL} /* this array must be NULL terminated */
139 s_surf_model_description_t surf_optimization_mode_description[] = {
141 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
144 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
147 "Full update of remaining and variables. Slow but may be useful when debugging.",
149 {NULL, NULL, NULL} /* this array must be NULL terminated */
152 s_surf_model_description_t surf_storage_model_description[] = {
154 "Simplistic storage model.",
155 surf_storage_model_init_default},
156 {NULL, NULL, NULL} /* this array must be NULL terminated */
159 #ifdef CONTEXT_THREADS
160 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
163 static double *surf_mins = NULL; /* return value of share_resources for each model */
164 static int surf_min_index; /* current index in surf_mins */
165 static double min; /* duration determined by surf_solve */
169 double surf_get_clock(void)
175 # define FILE_DELIM "\\"
177 # define FILE_DELIM "/" /* FIXME: move to better location */
180 FILE *surf_fopen(const char *name, const char *mode)
183 char *path_elm = NULL;
189 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
190 return fopen(name, mode);
192 /* search relative files in the path */
193 xbt_dynar_foreach(surf_path, cpt, path_elm) {
194 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
195 file = fopen(buff, mode);
205 * Returns the initial path. On Windows the initial path is
206 * the current directory for the current process in the other
207 * case the function returns "./" that represents the current
208 * directory on Unix/Linux platforms.
211 const char *__surf_get_initial_path(void)
216 char current_directory[MAX_PATH + 1] = { 0 };
217 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
218 char root[4] = { 0 };
223 strncpy(root, current_directory, 3);
225 for (i = 0; i < MAX_DRIVE; i++) {
226 if (toupper(root[0]) == disk_drives_letter_table[i][0])
227 return disk_drives_letter_table[i];
236 /* The __surf_is_absolute_file_path() returns 1 if
237 * file_path is a absolute file path, in the other
238 * case the function returns 0.
240 int __surf_is_absolute_file_path(const char *file_path)
243 WIN32_FIND_DATA wfd = { 0 };
244 HANDLE hFile = FindFirstFile(file_path, &wfd);
246 if (INVALID_HANDLE_VALUE == hFile)
252 return (file_path[0] == '/');
256 /** Displays the long description of all registered models, and quit */
257 void model_help(const char *category, s_surf_model_description_t * table)
260 printf("Long description of the %s models accepted by this simulator:\n",
262 for (i = 0; table[i].name; i++)
263 printf(" %s: %s\n", table[i].name, table[i].description);
266 int find_model_description(s_surf_model_description_t * table,
270 char *name_list = NULL;
272 for (i = 0; table[i].name; i++)
273 if (!strcmp(name, table[i].name)) {
276 name_list = strdup(table[0].name);
277 for (i = 1; table[i].name; i++) {
278 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
279 strcat(name_list, ", ");
280 strcat(name_list, table[i].name);
282 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
286 static XBT_INLINE void routing_asr_host_free(void *p)
288 delete ((RoutingEdgePtr) p);
291 static XBT_INLINE void routing_asr_prop_free(void *p)
293 xbt_dict_t elm = (xbt_dict_t) p;
297 static XBT_INLINE void surf_cpu_free(void *r)
299 delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
302 static XBT_INLINE void surf_link_free(void *r)
304 delete dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(r));
307 static XBT_INLINE void surf_workstation_free(void *r)
309 delete dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(r));
313 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
314 *ver_major = SIMGRID_VERSION_MAJOR;
315 *ver_minor = SIMGRID_VERSION_MINOR;
316 *ver_patch = SIMGRID_VERSION_PATCH;
319 void surf_init(int *argc, char **argv)
321 XBT_DEBUG("Create all Libs");
322 host_lib = xbt_lib_new();
323 link_lib = xbt_lib_new();
324 as_router_lib = xbt_lib_new();
325 storage_lib = xbt_lib_new();
326 storage_type_lib = xbt_lib_new();
327 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
329 XBT_DEBUG("Add routing levels");
330 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
331 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
332 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
334 XBT_DEBUG("Add SURF levels");
335 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
336 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
337 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
339 xbt_init(argc, argv);
341 model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
343 history = tmgr_history_new();
346 TRACE_add_start_function(TRACE_surf_alloc);
347 TRACE_add_end_function(TRACE_surf_release);
350 sg_config_init(argc, argv);
360 ModelPtr model = NULL;
363 TRACE_end(); /* Just in case it was not called by the upper
364 * layer (or there is no upper layer) */
367 sg_config_finalize();
369 xbt_dynar_foreach(model_list, iter, model)
371 xbt_dynar_free(&model_list);
375 lmm_system_free(maxmin_system);
376 maxmin_system = NULL;
379 tmgr_history_free(history);
384 #ifdef CONTEXT_THREADS
385 xbt_parmap_destroy(surf_parmap);
389 xbt_dynar_free(&host_that_restart);
390 xbt_dynar_free(&surf_path);
392 xbt_lib_free(&host_lib);
393 xbt_lib_free(&link_lib);
394 xbt_lib_free(&as_router_lib);
395 xbt_lib_free(&storage_lib);
396 xbt_lib_free(&storage_type_lib);
398 xbt_dict_free(&watched_hosts_lib);
401 surf_parse_lex_destroy();
402 surf_parse_free_callbacks();
404 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
410 Model::Model(string name)
411 : m_name(name), m_resOnCB(0), m_resOffCB(0),
412 m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0),
416 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
417 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
418 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
419 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
421 p_modifiedSet = NULL;
423 p_updateMechanism = UM_UNDEFINED;
424 m_selectiveUpdate = 0;
428 xbt_swag_free(p_readyActionSet);
429 xbt_swag_free(p_runningActionSet);
430 xbt_swag_free(p_failedActionSet);
431 xbt_swag_free(p_doneActionSet);
434 double Model::shareResources(double now)
436 //FIXME: set the good function once and for all
437 if (p_updateMechanism == UM_LAZY)
438 return shareResourcesLazy(now);
439 else if (p_updateMechanism == UM_FULL)
440 return shareResourcesFull(now);
442 xbt_die("Invalid cpu update mechanism!");
445 double Model::shareResourcesLazy(double now)
447 ActionLmmPtr action = NULL;
452 ("Before share resources, the size of modified actions set is %d",
453 xbt_swag_size(p_modifiedSet));
455 lmm_solve(p_maxminSystem);
458 ("After share resources, The size of modified actions set is %d",
459 xbt_swag_size(p_modifiedSet));
461 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
462 int max_dur_flag = 0;
464 if (action->p_stateSet != p_runningActionSet)
467 /* bogus priority, skip it */
468 if (action->m_priority <= 0)
471 action->updateRemainingLazy(now);
474 value = lmm_variable_getvalue(action->p_variable);
476 if (action->m_remains > 0) {
477 value = action->m_remains / value;
485 if ((action->m_maxDuration != NO_MAX_DURATION)
488 action->m_maxDuration < min)) {
489 min = action->m_start +
490 action->m_maxDuration;
494 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
495 action->m_start, now + value,
496 action->m_maxDuration);
499 action->heapRemove(p_actionHeap);
500 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
501 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
503 } else DIE_IMPOSSIBLE;
506 //hereafter must have already the min value for this resource model
507 if (xbt_heap_size(p_actionHeap) > 0)
508 min = xbt_heap_maxkey(p_actionHeap) - now;
512 XBT_DEBUG("The minimum with the HEAP %lf", min);
517 double Model::shareResourcesFull(double now) {
522 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
524 void (*solve) (lmm_system_t))
526 void *_action = NULL;
527 ActionLmmPtr action = NULL;
533 xbt_swag_foreach(_action, running_actions) {
534 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
535 value = lmm_variable_getvalue(action->p_variable);
536 if ((value > 0) || (action->m_maxDuration >= 0))
544 if (action->m_remains > 0)
545 min = action->m_remains / value;
548 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
549 min = action->m_maxDuration;
551 min = action->m_maxDuration;
554 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
556 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
557 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
558 value = lmm_variable_getvalue(action->p_variable);
560 if (action->m_remains > 0)
561 value = action->m_remains / value;
566 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
569 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
570 min = action->m_maxDuration;
571 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
574 XBT_DEBUG("min value : %f", min);
579 void Model::updateActionsState(double now, double delta)
581 if (p_updateMechanism == UM_FULL)
582 updateActionsStateFull(now, delta);
583 else if (p_updateMechanism == UM_LAZY)
584 updateActionsStateLazy(now, delta);
586 xbt_die("Invalid cpu update mechanism!");
589 void Model::updateActionsStateLazy(double now, double delta)
594 void Model::updateActionsStateFull(double now, double delta)
600 void Model::addTurnedOnCallback(ResourceCallback rc)
605 void Model::notifyResourceTurnedOn(ResourcePtr r)
610 void Model::addTurnedOffCallback(ResourceCallback rc)
615 void Model::notifyResourceTurnedOff(ResourcePtr r)
620 void Model::addActionCancelCallback(ActionCallback ac)
625 void Model::notifyActionCancel(ActionPtr a)
630 void Model::addActionResumeCallback(ActionCallback ac)
635 void Model::notifyActionResume(ActionPtr a)
640 void Model::addActionSuspendCallback(ActionCallback ac)
645 void Model::notifyActionSuspend(ActionPtr a)
655 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
656 : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props)
659 Resource::Resource(){
660 //FIXME:free(m_name);
661 //FIXME:xbt_dict_free(&m_properties);
664 const char *Resource::getName()
669 xbt_dict_t Resource::getProperties()
674 e_surf_resource_state_t Resource::getState()
676 return p_stateCurrent;
679 bool Resource::isOn()
684 void Resource::turnOn()
688 p_model->notifyResourceTurnedOn(this);
692 void Resource::turnOff()
696 p_model->notifyResourceTurnedOff(this);
700 ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
702 double constraint_value,
703 tmgr_history_t history,
704 e_surf_resource_state_t state_init,
705 tmgr_trace_t state_trace,
707 tmgr_trace_t metric_trace)
708 : Resource(model, name, props)
710 p_constraint = lmm_constraint_new(system, this, constraint_value);
711 p_stateCurrent = state_init;
713 p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
715 p_power.peak = metric_peak;
717 p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
724 const char *surf_action_state_names[6] = {
726 "SURF_ACTION_RUNNING",
727 "SURF_ACTION_FAILED",
729 "SURF_ACTION_TO_FREE",
730 "SURF_ACTION_NOT_IN_THE_SYSTEM"
734 * \brief Initializes the action module of Surf.
736 void surf_action_init(void) {
738 /* the action mallocator will always provide actions of the following size,
739 * so this size should be set to the maximum size of the surf action structures
741 /*FIXME:action_mallocator_allocated_size = sizeof(s_surf_action_network_CM02_t);
742 action_mallocator = xbt_mallocator_new(65536, surf_action_mallocator_new_f,
743 surf_action_mallocator_free_f, surf_action_mallocator_reset_f);*/
747 * \brief Uninitializes the action module of Surf.
749 void surf_action_exit(void) {
750 //FIXME:xbt_mallocator_free(action_mallocator);
755 Action::Action(ModelPtr model, double cost, bool failed):
756 m_cost(cost), p_model(model), m_failed(failed), m_remains(cost),
757 m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
758 m_start(surf_get_clock()), m_finish(-1.0)
763 p_stateHookup.prev = 0;
764 p_stateHookup.next = 0;
766 p_stateSet = p_model->p_failedActionSet;
768 p_stateSet = p_model->p_runningActionSet;
770 xbt_swag_insert(this, p_stateSet);
779 void Action::cancel(){
783 void Action::recycle(){
787 e_surf_action_state_t Action::getState()
789 if (p_stateSet == p_model->p_readyActionSet)
790 return SURF_ACTION_READY;
791 if (p_stateSet == p_model->p_runningActionSet)
792 return SURF_ACTION_RUNNING;
793 if (p_stateSet == p_model->p_failedActionSet)
794 return SURF_ACTION_FAILED;
795 if (p_stateSet == p_model->p_doneActionSet)
796 return SURF_ACTION_DONE;
797 return SURF_ACTION_NOT_IN_THE_SYSTEM;
800 void Action::setState(e_surf_action_state_t state)
802 //surf_action_state_t action_state = &(action->model_type->states);
803 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
804 xbt_swag_remove(this, p_stateSet);
806 if (state == SURF_ACTION_READY)
807 p_stateSet = p_model->p_readyActionSet;
808 else if (state == SURF_ACTION_RUNNING)
809 p_stateSet = p_model->p_runningActionSet;
810 else if (state == SURF_ACTION_FAILED)
811 p_stateSet = p_model->p_failedActionSet;
812 else if (state == SURF_ACTION_DONE)
813 p_stateSet = p_model->p_doneActionSet;
818 xbt_swag_insert(this, p_stateSet);
822 double Action::getStartTime()
827 double Action::getFinishTime()
829 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
830 return m_remains == 0 ? m_finish : -1;
833 double Action::getRemains()
835 XBT_IN("(%p)", this);
840 void Action::setData(void* data)
846 void Action::setCategory(const char *category)
848 XBT_IN("(%p,%s)", this, category);
849 p_category = xbt_strdup(category);
858 void ActionLmm::setMaxDuration(double duration)
860 XBT_IN("(%p,%g)", this, duration);
861 m_maxDuration = duration;
862 if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
863 heapRemove(p_model->p_actionHeap);
867 void ActionLmm::gapRemove() {}
869 void ActionLmm::setPriority(double priority)
871 XBT_IN("(%p,%g)", this, priority);
872 m_priority = priority;
873 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
875 if (p_model->p_updateMechanism == UM_LAZY)
876 heapRemove(p_model->p_actionHeap);
880 void ActionLmm::cancel(){
881 setState(SURF_ACTION_FAILED);
882 if (p_model->p_updateMechanism == UM_LAZY) {
883 xbt_swag_remove(this, p_model->p_modifiedSet);
884 heapRemove(p_model->p_actionHeap);
888 int ActionLmm::unref(){
891 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
893 lmm_variable_free(p_model->p_maxminSystem, p_variable);
894 if (p_model->p_updateMechanism == UM_LAZY) {
895 /* remove from heap */
896 heapRemove(p_model->p_actionHeap);
897 xbt_swag_remove(this, p_model->p_modifiedSet);
900 xbt_free(p_category);
908 void ActionLmm::suspend()
910 XBT_IN("(%p)", this);
911 if (m_suspended != 2) {
912 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
914 if (p_model->p_updateMechanism == UM_LAZY)
915 heapRemove(p_model->p_actionHeap);
920 void ActionLmm::resume()
922 XBT_IN("(%p)", this);
923 if (m_suspended != 2) {
924 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
926 if (p_model->p_updateMechanism == UM_LAZY)
927 heapRemove(p_model->p_actionHeap);
932 bool ActionLmm::isSuspended()
934 return m_suspended == 1;
936 /* insert action on heap using a given key and a hat (heap_action_type)
937 * a hat can be of three types for communications:
939 * NORMAL = this is a normal heap entry stating the date to finish transmitting
940 * LATENCY = this is a heap entry to warn us when the latency is payed
941 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
943 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
946 xbt_heap_push(heap, this, key);
949 void ActionLmm::heapRemove(xbt_heap_t heap)
952 if (m_indexHeap >= 0) {
953 xbt_heap_remove(heap, m_indexHeap);
957 /* added to manage the communication action's heap */
958 void surf_action_lmm_update_index_heap(void *action, int i) {
959 ((ActionLmmPtr)action)->updateIndexHeap(i);
962 void ActionLmm::updateIndexHeap(int i) {
966 double ActionLmm::getRemains()
968 XBT_IN("(%p)", this);
969 /* update remains before return it */
970 if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
971 updateRemainingLazy(surf_get_clock());
976 //FIXME split code in the right places
977 void ActionLmm::updateRemainingLazy(double now)
981 if(p_model == static_cast<ModelPtr>(surf_network_model))
983 if (m_suspended != 0)
988 xbt_assert(p_stateSet == p_model->p_runningActionSet,
989 "You're updating an action that is not running.");
991 /* bogus priority, skip it */
992 xbt_assert(m_priority > 0,
993 "You're updating an action that seems suspended.");
996 delta = now - m_lastUpdate;
999 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1000 double_update(&m_remains, m_lastValue * delta);
1003 if (p_model == static_cast<ModelPtr>(surf_cpu_model) && TRACE_is_enabled()) {
1004 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
1005 TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
1008 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1011 if(p_model == static_cast<ModelPtr>(surf_network_model))
1013 if (m_maxDuration != NO_MAX_DURATION)
1014 double_update(&m_maxDuration, delta);
1016 //FIXME: duplicated code
1017 if ((m_remains <= 0) &&
1018 (lmm_get_variable_weight(p_variable) > 0)) {
1019 m_finish = surf_get_clock();
1020 setState(SURF_ACTION_DONE);
1021 heapRemove(p_model->p_actionHeap);
1022 } else if (((m_maxDuration != NO_MAX_DURATION)
1023 && (m_maxDuration <= 0))) {
1024 m_finish = surf_get_clock();
1025 setState(SURF_ACTION_DONE);
1026 heapRemove(p_model->p_actionHeap);
1031 m_lastValue = lmm_variable_getvalue(p_variable);
1034 /*void Action::cancel()
1036 p_model->notifyActionCancel(this);
1039 void Action::suspend()
1041 p_model->notifyActionSuspend(this);
1044 void Action::resume()
1046 p_model->notifyActionResume(this);
1049 bool Action::isSuspended()