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);
359 ModelPtr model = NULL;
362 TRACE_end(); /* Just in case it was not called by the upper
363 * layer (or there is no upper layer) */
366 sg_config_finalize();
368 xbt_dynar_foreach(model_list, iter, model)
370 xbt_dynar_free(&model_list);
374 lmm_system_free(maxmin_system);
375 maxmin_system = NULL;
378 tmgr_history_free(history);
382 #ifdef CONTEXT_THREADS
383 xbt_parmap_destroy(surf_parmap);
387 xbt_dynar_free(&host_that_restart);
388 xbt_dynar_free(&surf_path);
390 xbt_lib_free(&host_lib);
391 xbt_lib_free(&link_lib);
392 xbt_lib_free(&as_router_lib);
393 xbt_lib_free(&storage_lib);
394 xbt_lib_free(&storage_type_lib);
396 xbt_dict_free(&watched_hosts_lib);
399 surf_parse_lex_destroy();
400 surf_parse_free_callbacks();
402 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
408 Model::Model(string name)
409 : m_name(name), m_resOnCB(0), m_resOffCB(0),
410 m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0),
414 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
415 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
416 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
417 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
419 p_modifiedSet = NULL;
421 p_updateMechanism = UM_UNDEFINED;
422 m_selectiveUpdate = 0;
426 xbt_swag_free(p_readyActionSet);
427 xbt_swag_free(p_runningActionSet);
428 xbt_swag_free(p_failedActionSet);
429 xbt_swag_free(p_doneActionSet);
432 double Model::shareResources(double now)
434 //FIXME: set the good function once and for all
435 if (p_updateMechanism == UM_LAZY)
436 return shareResourcesLazy(now);
437 else if (p_updateMechanism == UM_FULL)
438 return shareResourcesFull(now);
440 xbt_die("Invalid cpu update mechanism!");
443 double Model::shareResourcesLazy(double now)
445 ActionLmmPtr action = NULL;
450 ("Before share resources, the size of modified actions set is %d",
451 xbt_swag_size(p_modifiedSet));
453 lmm_solve(p_maxminSystem);
456 ("After share resources, The size of modified actions set is %d",
457 xbt_swag_size(p_modifiedSet));
459 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
460 int max_dur_flag = 0;
462 if (action->p_stateSet != p_runningActionSet)
465 /* bogus priority, skip it */
466 if (action->m_priority <= 0)
469 action->updateRemainingLazy(now);
472 value = lmm_variable_getvalue(action->p_variable);
474 if (action->m_remains > 0) {
475 value = action->m_remains / value;
483 if ((action->m_maxDuration != NO_MAX_DURATION)
486 action->m_maxDuration < min)) {
487 min = action->m_start +
488 action->m_maxDuration;
492 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
493 action->m_start, now + value,
494 action->m_maxDuration);
497 action->heapRemove(p_actionHeap);
498 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
499 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
501 } else DIE_IMPOSSIBLE;
504 //hereafter must have already the min value for this resource model
505 if (xbt_heap_size(p_actionHeap) > 0)
506 min = xbt_heap_maxkey(p_actionHeap) - now;
510 XBT_DEBUG("The minimum with the HEAP %lf", min);
515 double Model::shareResourcesFull(double now) {
520 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
522 void (*solve) (lmm_system_t))
524 void *_action = NULL;
525 ActionLmmPtr action = NULL;
531 xbt_swag_foreach(_action, running_actions) {
532 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
533 value = lmm_variable_getvalue(action->p_variable);
534 if ((value > 0) || (action->m_maxDuration >= 0))
542 if (action->m_remains > 0)
543 min = action->m_remains / value;
546 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
547 min = action->m_maxDuration;
549 min = action->m_maxDuration;
552 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
554 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
555 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
556 value = lmm_variable_getvalue(action->p_variable);
558 if (action->m_remains > 0)
559 value = action->m_remains / value;
564 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
567 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
568 min = action->m_maxDuration;
569 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
572 XBT_DEBUG("min value : %f", min);
577 void Model::updateActionsState(double now, double delta)
579 if (p_updateMechanism == UM_FULL)
580 updateActionsStateFull(now, delta);
581 else if (p_updateMechanism == UM_LAZY)
582 updateActionsStateLazy(now, delta);
584 xbt_die("Invalid cpu update mechanism!");
587 void Model::updateActionsStateLazy(double now, double delta)
592 void Model::updateActionsStateFull(double now, double delta)
598 void Model::addTurnedOnCallback(ResourceCallback rc)
603 void Model::notifyResourceTurnedOn(ResourcePtr r)
608 void Model::addTurnedOffCallback(ResourceCallback rc)
613 void Model::notifyResourceTurnedOff(ResourcePtr r)
618 void Model::addActionCancelCallback(ActionCallback ac)
623 void Model::notifyActionCancel(ActionPtr a)
628 void Model::addActionResumeCallback(ActionCallback ac)
633 void Model::notifyActionResume(ActionPtr a)
638 void Model::addActionSuspendCallback(ActionCallback ac)
643 void Model::notifyActionSuspend(ActionPtr a)
653 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
654 : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props)
657 Resource::Resource(){
658 //FIXME:free(m_name);
659 //FIXME:xbt_dict_free(&m_properties);
662 const char *Resource::getName()
667 xbt_dict_t Resource::getProperties()
672 e_surf_resource_state_t Resource::getState()
674 return p_stateCurrent;
677 bool Resource::isOn()
682 void Resource::turnOn()
686 p_model->notifyResourceTurnedOn(this);
690 void Resource::turnOff()
694 p_model->notifyResourceTurnedOff(this);
698 ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
700 double constraint_value,
701 tmgr_history_t history,
702 e_surf_resource_state_t state_init,
703 tmgr_trace_t state_trace,
705 tmgr_trace_t metric_trace)
706 : Resource(model, name, props)
708 p_constraint = lmm_constraint_new(system, this, constraint_value);
709 p_stateCurrent = state_init;
711 p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
713 p_power.peak = metric_peak;
715 p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
722 const char *surf_action_state_names[6] = {
724 "SURF_ACTION_RUNNING",
725 "SURF_ACTION_FAILED",
727 "SURF_ACTION_TO_FREE",
728 "SURF_ACTION_NOT_IN_THE_SYSTEM"
733 Action::Action(ModelPtr model, double cost, bool failed):
734 m_cost(cost), p_model(model), m_failed(failed), m_remains(cost),
735 m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
736 m_start(surf_get_clock()), m_finish(-1.0)
741 p_stateHookup.prev = 0;
742 p_stateHookup.next = 0;
744 p_stateSet = p_model->p_failedActionSet;
746 p_stateSet = p_model->p_runningActionSet;
748 xbt_swag_insert(this, p_stateSet);
757 void Action::cancel(){
761 void Action::recycle(){
765 e_surf_action_state_t Action::getState()
767 if (p_stateSet == p_model->p_readyActionSet)
768 return SURF_ACTION_READY;
769 if (p_stateSet == p_model->p_runningActionSet)
770 return SURF_ACTION_RUNNING;
771 if (p_stateSet == p_model->p_failedActionSet)
772 return SURF_ACTION_FAILED;
773 if (p_stateSet == p_model->p_doneActionSet)
774 return SURF_ACTION_DONE;
775 return SURF_ACTION_NOT_IN_THE_SYSTEM;
778 void Action::setState(e_surf_action_state_t state)
780 //surf_action_state_t action_state = &(action->model_type->states);
781 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
782 xbt_swag_remove(this, p_stateSet);
784 if (state == SURF_ACTION_READY)
785 p_stateSet = p_model->p_readyActionSet;
786 else if (state == SURF_ACTION_RUNNING)
787 p_stateSet = p_model->p_runningActionSet;
788 else if (state == SURF_ACTION_FAILED)
789 p_stateSet = p_model->p_failedActionSet;
790 else if (state == SURF_ACTION_DONE)
791 p_stateSet = p_model->p_doneActionSet;
796 xbt_swag_insert(this, p_stateSet);
800 double Action::getStartTime()
805 double Action::getFinishTime()
807 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
808 return m_remains == 0 ? m_finish : -1;
811 double Action::getRemains()
813 XBT_IN("(%p)", this);
818 void Action::setData(void* data)
824 void Action::setCategory(const char *category)
826 XBT_IN("(%p,%s)", this, category);
827 p_category = xbt_strdup(category);
836 void ActionLmm::setMaxDuration(double duration)
838 XBT_IN("(%p,%g)", this, duration);
839 m_maxDuration = duration;
840 if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
841 heapRemove(p_model->p_actionHeap);
845 void ActionLmm::gapRemove() {}
847 void ActionLmm::setPriority(double priority)
849 XBT_IN("(%p,%g)", this, priority);
850 m_priority = priority;
851 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
853 if (p_model->p_updateMechanism == UM_LAZY)
854 heapRemove(p_model->p_actionHeap);
858 void ActionLmm::cancel(){
859 setState(SURF_ACTION_FAILED);
860 if (p_model->p_updateMechanism == UM_LAZY) {
861 xbt_swag_remove(this, p_model->p_modifiedSet);
862 heapRemove(p_model->p_actionHeap);
866 int ActionLmm::unref(){
869 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
871 lmm_variable_free(p_model->p_maxminSystem, p_variable);
872 if (p_model->p_updateMechanism == UM_LAZY) {
873 /* remove from heap */
874 heapRemove(p_model->p_actionHeap);
875 xbt_swag_remove(this, p_model->p_modifiedSet);
878 xbt_free(p_category);
886 void ActionLmm::suspend()
888 XBT_IN("(%p)", this);
889 if (m_suspended != 2) {
890 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
892 if (p_model->p_updateMechanism == UM_LAZY)
893 heapRemove(p_model->p_actionHeap);
898 void ActionLmm::resume()
900 XBT_IN("(%p)", this);
901 if (m_suspended != 2) {
902 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
904 if (p_model->p_updateMechanism == UM_LAZY)
905 heapRemove(p_model->p_actionHeap);
910 bool ActionLmm::isSuspended()
912 return m_suspended == 1;
914 /* insert action on heap using a given key and a hat (heap_action_type)
915 * a hat can be of three types for communications:
917 * NORMAL = this is a normal heap entry stating the date to finish transmitting
918 * LATENCY = this is a heap entry to warn us when the latency is payed
919 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
921 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
924 xbt_heap_push(heap, this, key);
927 void ActionLmm::heapRemove(xbt_heap_t heap)
930 if (m_indexHeap >= 0) {
931 xbt_heap_remove(heap, m_indexHeap);
935 /* added to manage the communication action's heap */
936 void surf_action_lmm_update_index_heap(void *action, int i) {
937 ((ActionLmmPtr)action)->updateIndexHeap(i);
940 void ActionLmm::updateIndexHeap(int i) {
944 double ActionLmm::getRemains()
946 XBT_IN("(%p)", this);
947 /* update remains before return it */
948 if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
949 updateRemainingLazy(surf_get_clock());
954 //FIXME split code in the right places
955 void ActionLmm::updateRemainingLazy(double now)
959 if(p_model == static_cast<ModelPtr>(surf_network_model))
961 if (m_suspended != 0)
966 xbt_assert(p_stateSet == p_model->p_runningActionSet,
967 "You're updating an action that is not running.");
969 /* bogus priority, skip it */
970 xbt_assert(m_priority > 0,
971 "You're updating an action that seems suspended.");
974 delta = now - m_lastUpdate;
977 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
978 double_update(&m_remains, m_lastValue * delta);
981 if (p_model == static_cast<ModelPtr>(surf_cpu_model) && TRACE_is_enabled()) {
982 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
983 TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
986 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
989 if(p_model == static_cast<ModelPtr>(surf_network_model))
991 if (m_maxDuration != NO_MAX_DURATION)
992 double_update(&m_maxDuration, delta);
994 //FIXME: duplicated code
995 if ((m_remains <= 0) &&
996 (lmm_get_variable_weight(p_variable) > 0)) {
997 m_finish = surf_get_clock();
998 setState(SURF_ACTION_DONE);
999 heapRemove(p_model->p_actionHeap);
1000 } else if (((m_maxDuration != NO_MAX_DURATION)
1001 && (m_maxDuration <= 0))) {
1002 m_finish = surf_get_clock();
1003 setState(SURF_ACTION_DONE);
1004 heapRemove(p_model->p_actionHeap);
1009 m_lastValue = lmm_variable_getvalue(p_variable);
1012 /*void Action::cancel()
1014 p_model->notifyActionCancel(this);
1017 void Action::suspend()
1019 p_model->notifyActionSuspend(this);
1022 void Action::resume()
1024 p_model->notifyActionResume(this);
1027 bool Action::isSuspended()