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;
82 /* Don't forget to update the option description in smx_config when you change this */
83 s_surf_model_description_t surf_network_model_description[] = {
85 "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). ",
86 surf_network_model_init_LegrandVelho},
88 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
89 surf_network_model_init_Constant},
91 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
92 surf_network_model_init_SMPI},
94 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
95 surf_network_model_init_CM02},
98 "Network pseudo-model using the GTNets simulator instead of an analytic model",
99 surf_network_model_init_GTNETS},
103 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
104 surf_network_model_init_NS3},
107 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
108 surf_network_model_init_Reno},
110 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
111 surf_network_model_init_Reno2},
113 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
114 surf_network_model_init_Vegas},
115 {NULL, NULL, NULL} /* this array must be NULL terminated */
118 s_surf_model_description_t surf_cpu_model_description[] = {
120 "Simplistic CPU model (time=size/power).",
121 surf_cpu_model_init_Cas01},
122 {NULL, NULL, NULL} /* this array must be NULL terminated */
125 s_surf_model_description_t surf_workstation_model_description[] = {
127 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
128 surf_workstation_model_init_current_default},
130 "Workstation model that is automatically chosen if you change the network and CPU models",
131 surf_workstation_model_init_compound},
132 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
133 surf_workstation_model_init_ptask_L07},
134 {NULL, NULL, NULL} /* this array must be NULL terminated */
137 s_surf_model_description_t surf_optimization_mode_description[] = {
139 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
142 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
145 "Full update of remaining and variables. Slow but may be useful when debugging.",
147 {NULL, NULL, NULL} /* this array must be NULL terminated */
150 s_surf_model_description_t surf_storage_model_description[] = {
152 "Simplistic storage model.",
153 surf_storage_model_init_default},
154 {NULL, NULL, NULL} /* this array must be NULL terminated */
157 /* ********************************************************************* */
158 /* TUTORIAL: New model */
159 s_surf_model_description_t surf_new_model_description[] = {
162 surf_new_model_init_default},
163 {NULL, NULL, NULL} /* this array must be NULL terminated */
165 /* ********************************************************************* */
167 #ifdef CONTEXT_THREADS
168 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
171 static double *surf_mins = NULL; /* return value of share_resources for each model */
172 static int surf_min_index; /* current index in surf_mins */
173 static double min; /* duration determined by surf_solve */
177 XBT_INLINE double surf_get_clock(void)
182 /*TODO: keepit void surf_watched_hosts(void)
187 xbt_dict_cursor_t cursor;
188 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
190 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
191 xbt_dict_foreach(watched_hosts_lib,cursor,key,_host)
193 host = (smx_host_t) host;
194 if(SIMIX_host_get_state(host) == SURF_RESOURCE_ON){
195 XBT_INFO("Restart processes on host: %s",SIMIX_host_get_name(host));
196 SIMIX_host_autorestart(host);
197 xbt_dynar_push_as(hosts, char*, key);
200 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
202 xbt_dynar_map(hosts, remove_watched_host);
203 xbt_dynar_free(&hosts);
207 # define FILE_DELIM "\\"
209 # define FILE_DELIM "/" /* FIXME: move to better location */
212 FILE *surf_fopen(const char *name, const char *mode)
215 char *path_elm = NULL;
221 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
222 return fopen(name, mode);
224 /* search relative files in the path */
225 xbt_dynar_foreach(surf_path, cpt, path_elm) {
226 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
227 file = fopen(buff, mode);
237 * Returns the initial path. On Windows the initial path is
238 * the current directory for the current process in the other
239 * case the function returns "./" that represents the current
240 * directory on Unix/Linux platforms.
243 const char *__surf_get_initial_path(void)
248 char current_directory[MAX_PATH + 1] = { 0 };
249 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
250 char root[4] = { 0 };
255 strncpy(root, current_directory, 3);
257 for (i = 0; i < MAX_DRIVE; i++) {
258 if (toupper(root[0]) == disk_drives_letter_table[i][0])
259 return disk_drives_letter_table[i];
268 /* The __surf_is_absolute_file_path() returns 1 if
269 * file_path is a absolute file path, in the other
270 * case the function returns 0.
272 int __surf_is_absolute_file_path(const char *file_path)
275 WIN32_FIND_DATA wfd = { 0 };
276 HANDLE hFile = FindFirstFile(file_path, &wfd);
278 if (INVALID_HANDLE_VALUE == hFile)
284 return (file_path[0] == '/');
288 /** Displays the long description of all registered models, and quit */
289 void model_help(const char *category, s_surf_model_description_t * table)
292 printf("Long description of the %s models accepted by this simulator:\n",
294 for (i = 0; table[i].name; i++)
295 printf(" %s: %s\n", table[i].name, table[i].description);
298 int find_model_description(s_surf_model_description_t * table,
302 char *name_list = NULL;
304 for (i = 0; table[i].name; i++)
305 if (!strcmp(name, table[i].name)) {
308 name_list = strdup(table[0].name);
309 for (i = 1; table[i].name; i++) {
310 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
311 strcat(name_list, ", ");
312 strcat(name_list, table[i].name);
314 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
318 static XBT_INLINE void routing_asr_host_free(void *p)
320 delete ((RoutingEdgePtr) p);
323 static XBT_INLINE void routing_asr_prop_free(void *p)
325 xbt_dict_t elm = (xbt_dict_t) p;
329 static XBT_INLINE void surf_cpu_free(void *r)
331 delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
334 static XBT_INLINE void surf_link_free(void *r)
336 delete static_cast<NetworkCm02LinkPtr>(r);
339 static XBT_INLINE void surf_workstation_free(void *r)
341 delete dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(r));
345 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
346 *ver_major = SIMGRID_VERSION_MAJOR;
347 *ver_minor = SIMGRID_VERSION_MINOR;
348 *ver_patch = SIMGRID_VERSION_PATCH;
351 void surf_init(int *argc, char **argv)
353 XBT_DEBUG("Create all Libs");
354 host_lib = xbt_lib_new();
355 link_lib = xbt_lib_new();
356 as_router_lib = xbt_lib_new();
357 storage_lib = xbt_lib_new();
358 storage_type_lib = xbt_lib_new();
359 watched_hosts_lib = xbt_dict_new();
361 XBT_DEBUG("Add routing levels");
362 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
363 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
364 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
366 XBT_DEBUG("Add SURF levels");
367 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
368 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
369 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
371 xbt_init(argc, argv);
373 model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
375 history = tmgr_history_new();
378 TRACE_add_start_function(TRACE_surf_alloc);
379 TRACE_add_end_function(TRACE_surf_release);
382 sg_config_init(argc, argv);
392 ModelPtr model = NULL;
394 sg_config_finalize();
396 xbt_dynar_foreach(model_list, iter, model)
398 xbt_dynar_free(&model_list);
402 lmm_system_free(maxmin_system);
403 maxmin_system = NULL;
406 tmgr_history_free(history);
411 #ifdef CONTEXT_THREADS
412 xbt_parmap_destroy(surf_parmap);
417 xbt_dynar_free(&surf_path);
419 xbt_lib_free(&host_lib);
420 xbt_lib_free(&link_lib);
421 xbt_lib_free(&as_router_lib);
422 xbt_lib_free(&storage_lib);
423 xbt_lib_free(&storage_type_lib);
425 xbt_dict_free(&watched_hosts_lib);
428 surf_parse_lex_destroy();
429 surf_parse_free_callbacks();
431 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
437 Model::Model(string name)
438 : m_name(name), m_resOnCB(0), m_resOffCB(0),
439 m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0),
443 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
444 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
445 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
446 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
448 p_modifiedSet = NULL;
450 p_updateMechanism = UM_UNDEFINED;
451 m_selectiveUpdate = 0;
455 xbt_swag_free(p_readyActionSet);
456 xbt_swag_free(p_runningActionSet);
457 xbt_swag_free(p_failedActionSet);
458 xbt_swag_free(p_doneActionSet);
461 double Model::shareResources(double now)
463 //FIXME: set the good function once and for all
464 if (p_updateMechanism == UM_LAZY)
465 return shareResourcesLazy(now);
466 else if (p_updateMechanism == UM_FULL)
467 return shareResourcesFull(now);
469 xbt_die("Invalid cpu update mechanism!");
472 double Model::shareResourcesLazy(double now)
474 ActionLmmPtr action = NULL;
479 ("Before share resources, the size of modified actions set is %d",
480 xbt_swag_size(p_modifiedSet));
482 lmm_solve(p_maxminSystem);
485 ("After share resources, The size of modified actions set is %d",
486 xbt_swag_size(p_modifiedSet));
488 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
489 int max_dur_flag = 0;
491 if (action->p_stateSet != p_runningActionSet)
494 /* bogus priority, skip it */
495 if (action->m_priority <= 0)
498 action->updateRemainingLazy(now);
501 value = lmm_variable_getvalue(action->p_variable);
503 if (action->m_remains > 0) {
504 value = action->m_remains / value;
512 if ((action->m_maxDuration != NO_MAX_DURATION)
515 action->m_maxDuration < min)) {
516 min = action->m_start +
517 action->m_maxDuration;
521 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
522 action->m_start, now + value,
523 action->m_maxDuration);
526 action->heapRemove(p_actionHeap);
527 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
528 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
530 } else DIE_IMPOSSIBLE;
533 //hereafter must have already the min value for this resource model
534 if (xbt_heap_size(p_actionHeap) > 0)
535 min = xbt_heap_maxkey(p_actionHeap) - now;
539 XBT_DEBUG("The minimum with the HEAP %lf", min);
544 double Model::shareResourcesFull(double now) {
549 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
551 void (*solve) (lmm_system_t))
553 void *_action = NULL;
554 ActionLmmPtr action = NULL;
560 xbt_swag_foreach(_action, running_actions) {
561 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
562 value = lmm_variable_getvalue(action->p_variable);
563 if ((value > 0) || (action->m_maxDuration >= 0))
571 if (action->m_remains > 0)
572 min = action->m_remains / value;
575 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
576 min = action->m_maxDuration;
578 min = action->m_maxDuration;
581 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
583 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
584 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
585 value = lmm_variable_getvalue(action->p_variable);
587 if (action->m_remains > 0)
588 value = action->m_remains / value;
593 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
596 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
597 min = action->m_maxDuration;
598 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
601 XBT_DEBUG("min value : %f", min);
606 void Model::updateActionsState(double now, double delta)
608 if (p_updateMechanism == UM_FULL)
609 updateActionsStateFull(now, delta);
610 else if (p_updateMechanism == UM_LAZY)
611 updateActionsStateLazy(now, delta);
613 xbt_die("Invalid cpu update mechanism!");
616 void Model::updateActionsStateLazy(double now, double delta)
621 void Model::updateActionsStateFull(double now, double delta)
627 void Model::addTurnedOnCallback(ResourceCallback rc)
632 void Model::notifyResourceTurnedOn(ResourcePtr r)
637 void Model::addTurnedOffCallback(ResourceCallback rc)
642 void Model::notifyResourceTurnedOff(ResourcePtr r)
647 void Model::addActionCancelCallback(ActionCallback ac)
652 void Model::notifyActionCancel(ActionPtr a)
657 void Model::addActionResumeCallback(ActionCallback ac)
662 void Model::notifyActionResume(ActionPtr a)
667 void Model::addActionSuspendCallback(ActionCallback ac)
672 void Model::notifyActionSuspend(ActionPtr a)
682 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
683 : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props)
686 Resource::Resource(){
687 //FIXME:free(m_name);
688 //FIXME:xbt_dict_free(&m_properties);
691 const char *Resource::getName()
696 xbt_dict_t Resource::getProperties()
701 e_surf_resource_state_t Resource::getState()
703 return p_stateCurrent;
706 bool Resource::isOn()
711 void Resource::turnOn()
715 p_model->notifyResourceTurnedOn(this);
719 void Resource::turnOff()
723 p_model->notifyResourceTurnedOff(this);
727 ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
729 double constraint_value,
730 tmgr_history_t history,
731 e_surf_resource_state_t state_init,
732 tmgr_trace_t state_trace,
734 tmgr_trace_t metric_trace)
735 : Resource(model, name, props)
737 p_constraint = lmm_constraint_new(system, this, constraint_value);
738 p_stateCurrent = state_init;
740 p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
742 p_power.peak = metric_peak;
744 p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
751 const char *surf_action_state_names[6] = {
753 "SURF_ACTION_RUNNING",
754 "SURF_ACTION_FAILED",
756 "SURF_ACTION_TO_FREE",
757 "SURF_ACTION_NOT_IN_THE_SYSTEM"
761 * \brief Initializes the action module of Surf.
763 void surf_action_init(void) {
765 /* the action mallocator will always provide actions of the following size,
766 * so this size should be set to the maximum size of the surf action structures
768 /*FIXME:action_mallocator_allocated_size = sizeof(s_surf_action_network_CM02_t);
769 action_mallocator = xbt_mallocator_new(65536, surf_action_mallocator_new_f,
770 surf_action_mallocator_free_f, surf_action_mallocator_reset_f);*/
774 * \brief Uninitializes the action module of Surf.
776 void surf_action_exit(void) {
777 //FIXME:xbt_mallocator_free(action_mallocator);
782 Action::Action(ModelPtr model, double cost, bool failed):
783 m_cost(cost), p_model(model), m_failed(failed), m_remains(cost),
784 m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
785 m_start(surf_get_clock()), m_finish(-1.0)
790 p_stateHookup.prev = 0;
791 p_stateHookup.next = 0;
793 p_stateSet = p_model->p_failedActionSet;
795 p_stateSet = p_model->p_runningActionSet;
797 xbt_swag_insert(this, p_stateSet);
806 void Action::cancel(){
810 void Action::recycle(){
814 e_surf_action_state_t Action::getState()
816 if (p_stateSet == p_model->p_readyActionSet)
817 return SURF_ACTION_READY;
818 if (p_stateSet == p_model->p_runningActionSet)
819 return SURF_ACTION_RUNNING;
820 if (p_stateSet == p_model->p_failedActionSet)
821 return SURF_ACTION_FAILED;
822 if (p_stateSet == p_model->p_doneActionSet)
823 return SURF_ACTION_DONE;
824 return SURF_ACTION_NOT_IN_THE_SYSTEM;
827 void Action::setState(e_surf_action_state_t state)
829 //surf_action_state_t action_state = &(action->model_type->states);
830 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
831 xbt_swag_remove(this, p_stateSet);
833 if (state == SURF_ACTION_READY)
834 p_stateSet = p_model->p_readyActionSet;
835 else if (state == SURF_ACTION_RUNNING)
836 p_stateSet = p_model->p_runningActionSet;
837 else if (state == SURF_ACTION_FAILED)
838 p_stateSet = p_model->p_failedActionSet;
839 else if (state == SURF_ACTION_DONE)
840 p_stateSet = p_model->p_doneActionSet;
845 xbt_swag_insert(this, p_stateSet);
849 double Action::getStartTime()
854 double Action::getFinishTime()
856 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
857 return m_remains == 0 ? m_finish : -1;
860 double Action::getRemains()
862 XBT_IN("(%p)", this);
867 void Action::setData(void* data)
873 void Action::setCategory(const char *category)
875 XBT_IN("(%p,%s)", this, category);
876 p_category = xbt_strdup(category);
885 void ActionLmm::setMaxDuration(double duration)
887 XBT_IN("(%p,%g)", this, duration);
888 m_maxDuration = duration;
889 if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
890 heapRemove(p_model->p_actionHeap);
894 void ActionLmm::gapRemove() {}
896 void ActionLmm::setPriority(double priority)
898 XBT_IN("(%p,%g)", this, priority);
899 m_priority = priority;
900 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
902 if (p_model->p_updateMechanism == UM_LAZY)
903 heapRemove(p_model->p_actionHeap);
907 void ActionLmm::cancel(){
908 setState(SURF_ACTION_FAILED);
909 if (p_model->p_updateMechanism == UM_LAZY) {
910 xbt_swag_remove(this, p_model->p_modifiedSet);
911 heapRemove(p_model->p_actionHeap);
915 int ActionLmm::unref(){
918 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
920 lmm_variable_free(p_model->p_maxminSystem, p_variable);
921 if (p_model->p_updateMechanism == UM_LAZY) {
922 /* remove from heap */
923 heapRemove(p_model->p_actionHeap);
924 xbt_swag_remove(this, p_model->p_modifiedSet);
927 xbt_free(p_category);
935 void ActionLmm::suspend()
937 XBT_IN("(%p)", this);
938 if (m_suspended != 2) {
939 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
941 if (p_model->p_updateMechanism == UM_LAZY)
942 heapRemove(p_model->p_actionHeap);
947 void ActionLmm::resume()
949 XBT_IN("(%p)", this);
950 if (m_suspended != 2) {
951 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
953 if (p_model->p_updateMechanism == UM_LAZY)
954 heapRemove(p_model->p_actionHeap);
959 bool ActionLmm::isSuspended()
961 return m_suspended == 1;
963 /* insert action on heap using a given key and a hat (heap_action_type)
964 * a hat can be of three types for communications:
966 * NORMAL = this is a normal heap entry stating the date to finish transmitting
967 * LATENCY = this is a heap entry to warn us when the latency is payed
968 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
970 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
973 xbt_heap_push(heap, this, key);
976 void ActionLmm::heapRemove(xbt_heap_t heap)
979 if (m_indexHeap >= 0) {
980 xbt_heap_remove(heap, m_indexHeap);
984 /* added to manage the communication action's heap */
985 void surf_action_lmm_update_index_heap(void *action, int i) {
986 ((ActionLmmPtr)action)->updateIndexHeap(i);
989 void ActionLmm::updateIndexHeap(int i) {
993 double ActionLmm::getRemains()
995 XBT_IN("(%p)", this);
996 /* update remains before return it */
997 if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
998 updateRemainingLazy(surf_get_clock());
1003 //FIXME split code in the right places
1004 void ActionLmm::updateRemainingLazy(double now)
1008 if(p_model == static_cast<ModelPtr>(surf_network_model))
1010 if (m_suspended != 0)
1015 xbt_assert(p_stateSet == p_model->p_runningActionSet,
1016 "You're updating an action that is not running.");
1018 /* bogus priority, skip it */
1019 xbt_assert(m_priority > 0,
1020 "You're updating an action that seems suspended.");
1023 delta = now - m_lastUpdate;
1025 if (m_remains > 0) {
1026 XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate);
1027 double_update(&m_remains, m_lastValue * delta);
1030 if (p_model == static_cast<ModelPtr>(surf_cpu_model) && TRACE_is_enabled()) {
1031 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
1032 TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
1035 XBT_DEBUG("Updating action(%p): remains is now %lf", this, m_remains);
1038 if(p_model == static_cast<ModelPtr>(surf_network_model))
1040 if (m_maxDuration != NO_MAX_DURATION)
1041 double_update(&m_maxDuration, delta);
1043 //FIXME: duplicated code
1044 if ((m_remains <= 0) &&
1045 (lmm_get_variable_weight(p_variable) > 0)) {
1046 m_finish = surf_get_clock();
1047 setState(SURF_ACTION_DONE);
1048 heapRemove(p_model->p_actionHeap);
1049 } else if (((m_maxDuration != NO_MAX_DURATION)
1050 && (m_maxDuration <= 0))) {
1051 m_finish = surf_get_clock();
1052 setState(SURF_ACTION_DONE);
1053 heapRemove(p_model->p_actionHeap);
1058 m_lastValue = lmm_variable_getvalue(p_variable);
1061 /*void Action::cancel()
1063 p_model->notifyActionCancel(this);
1066 void Action::suspend()
1068 p_model->notifyActionSuspend(this);
1071 void Action::resume()
1073 p_model->notifyActionResume(this);
1076 bool Action::isSuspended()