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 #ifdef CONTEXT_THREADS
158 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
161 static double *surf_mins = NULL; /* return value of share_resources for each model */
162 static int surf_min_index; /* current index in surf_mins */
163 static double min; /* duration determined by surf_solve */
167 double surf_get_clock(void)
172 /*TODO: keepit void surf_watched_hosts(void)
177 xbt_dict_cursor_t cursor;
178 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
180 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
181 xbt_dict_foreach(watched_hosts_lib,cursor,key,_host)
183 host = (smx_host_t) host;
184 if(SIMIX_host_get_state(host) == SURF_RESOURCE_ON){
185 XBT_INFO("Restart processes on host: %s",SIMIX_host_get_name(host));
186 SIMIX_host_autorestart(host);
187 xbt_dynar_push_as(hosts, char*, key);
190 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
192 xbt_dynar_map(hosts, remove_watched_host);
193 xbt_dynar_free(&hosts);
197 # define FILE_DELIM "\\"
199 # define FILE_DELIM "/" /* FIXME: move to better location */
202 FILE *surf_fopen(const char *name, const char *mode)
205 char *path_elm = NULL;
211 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
212 return fopen(name, mode);
214 /* search relative files in the path */
215 xbt_dynar_foreach(surf_path, cpt, path_elm) {
216 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
217 file = fopen(buff, mode);
227 * Returns the initial path. On Windows the initial path is
228 * the current directory for the current process in the other
229 * case the function returns "./" that represents the current
230 * directory on Unix/Linux platforms.
233 const char *__surf_get_initial_path(void)
238 char current_directory[MAX_PATH + 1] = { 0 };
239 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
240 char root[4] = { 0 };
245 strncpy(root, current_directory, 3);
247 for (i = 0; i < MAX_DRIVE; i++) {
248 if (toupper(root[0]) == disk_drives_letter_table[i][0])
249 return disk_drives_letter_table[i];
258 /* The __surf_is_absolute_file_path() returns 1 if
259 * file_path is a absolute file path, in the other
260 * case the function returns 0.
262 int __surf_is_absolute_file_path(const char *file_path)
265 WIN32_FIND_DATA wfd = { 0 };
266 HANDLE hFile = FindFirstFile(file_path, &wfd);
268 if (INVALID_HANDLE_VALUE == hFile)
274 return (file_path[0] == '/');
278 /** Displays the long description of all registered models, and quit */
279 void model_help(const char *category, s_surf_model_description_t * table)
282 printf("Long description of the %s models accepted by this simulator:\n",
284 for (i = 0; table[i].name; i++)
285 printf(" %s: %s\n", table[i].name, table[i].description);
288 int find_model_description(s_surf_model_description_t * table,
292 char *name_list = NULL;
294 for (i = 0; table[i].name; i++)
295 if (!strcmp(name, table[i].name)) {
298 name_list = strdup(table[0].name);
299 for (i = 1; table[i].name; i++) {
300 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
301 strcat(name_list, ", ");
302 strcat(name_list, table[i].name);
304 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
308 static XBT_INLINE void routing_asr_host_free(void *p)
310 delete ((RoutingEdgePtr) p);
313 static XBT_INLINE void routing_asr_prop_free(void *p)
315 xbt_dict_t elm = (xbt_dict_t) p;
319 static XBT_INLINE void surf_cpu_free(void *r)
321 delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
324 static XBT_INLINE void surf_link_free(void *r)
326 delete dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(r));
329 static XBT_INLINE void surf_workstation_free(void *r)
331 delete dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(r));
335 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
336 *ver_major = SIMGRID_VERSION_MAJOR;
337 *ver_minor = SIMGRID_VERSION_MINOR;
338 *ver_patch = SIMGRID_VERSION_PATCH;
341 void surf_init(int *argc, char **argv)
343 XBT_DEBUG("Create all Libs");
344 host_lib = xbt_lib_new();
345 link_lib = xbt_lib_new();
346 as_router_lib = xbt_lib_new();
347 storage_lib = xbt_lib_new();
348 storage_type_lib = xbt_lib_new();
349 watched_hosts_lib = xbt_dict_new();
351 XBT_DEBUG("Add routing levels");
352 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
353 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
354 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
356 XBT_DEBUG("Add SURF levels");
357 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
358 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
359 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
361 xbt_init(argc, argv);
363 model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
365 history = tmgr_history_new();
368 TRACE_add_start_function(TRACE_surf_alloc);
369 TRACE_add_end_function(TRACE_surf_release);
372 sg_config_init(argc, argv);
382 ModelPtr model = NULL;
384 sg_config_finalize();
386 xbt_dynar_foreach(model_list, iter, model)
388 xbt_dynar_free(&model_list);
392 lmm_system_free(maxmin_system);
393 maxmin_system = NULL;
396 tmgr_history_free(history);
401 #ifdef CONTEXT_THREADS
402 xbt_parmap_destroy(surf_parmap);
407 xbt_dynar_free(&surf_path);
409 xbt_lib_free(&host_lib);
410 xbt_lib_free(&link_lib);
411 xbt_lib_free(&as_router_lib);
412 xbt_lib_free(&storage_lib);
413 xbt_lib_free(&storage_type_lib);
415 xbt_dict_free(&watched_hosts_lib);
418 surf_parse_lex_destroy();
419 surf_parse_free_callbacks();
421 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
427 Model::Model(string name)
428 : m_name(name), m_resOnCB(0), m_resOffCB(0),
429 m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0),
433 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
434 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
435 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
436 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
438 p_modifiedSet = NULL;
440 p_updateMechanism = UM_UNDEFINED;
441 m_selectiveUpdate = 0;
445 xbt_swag_free(p_readyActionSet);
446 xbt_swag_free(p_runningActionSet);
447 xbt_swag_free(p_failedActionSet);
448 xbt_swag_free(p_doneActionSet);
451 double Model::shareResources(double now)
453 //FIXME: set the good function once and for all
454 if (p_updateMechanism == UM_LAZY)
455 return shareResourcesLazy(now);
456 else if (p_updateMechanism == UM_FULL)
457 return shareResourcesFull(now);
459 xbt_die("Invalid cpu update mechanism!");
462 double Model::shareResourcesLazy(double now)
464 ActionLmmPtr action = NULL;
469 ("Before share resources, the size of modified actions set is %d",
470 xbt_swag_size(p_modifiedSet));
472 lmm_solve(p_maxminSystem);
475 ("After share resources, The size of modified actions set is %d",
476 xbt_swag_size(p_modifiedSet));
478 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
479 int max_dur_flag = 0;
481 if (action->p_stateSet != p_runningActionSet)
484 /* bogus priority, skip it */
485 if (action->m_priority <= 0)
488 action->updateRemainingLazy(now);
491 value = lmm_variable_getvalue(action->p_variable);
493 if (action->m_remains > 0) {
494 value = action->m_remains / value;
502 if ((action->m_maxDuration != NO_MAX_DURATION)
505 action->m_maxDuration < min)) {
506 min = action->m_start +
507 action->m_maxDuration;
511 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
512 action->m_start, now + value,
513 action->m_maxDuration);
516 action->heapRemove(p_actionHeap);
517 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
518 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
520 } else DIE_IMPOSSIBLE;
523 //hereafter must have already the min value for this resource model
524 if (xbt_heap_size(p_actionHeap) > 0)
525 min = xbt_heap_maxkey(p_actionHeap) - now;
529 XBT_DEBUG("The minimum with the HEAP %lf", min);
534 double Model::shareResourcesFull(double now) {
539 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
541 void (*solve) (lmm_system_t))
543 void *_action = NULL;
544 ActionLmmPtr action = NULL;
550 xbt_swag_foreach(_action, running_actions) {
551 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
552 value = lmm_variable_getvalue(action->p_variable);
553 if ((value > 0) || (action->m_maxDuration >= 0))
561 if (action->m_remains > 0)
562 min = action->m_remains / value;
565 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
566 min = action->m_maxDuration;
568 min = action->m_maxDuration;
571 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
573 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
574 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
575 value = lmm_variable_getvalue(action->p_variable);
577 if (action->m_remains > 0)
578 value = action->m_remains / value;
583 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
586 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
587 min = action->m_maxDuration;
588 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
591 XBT_DEBUG("min value : %f", min);
596 void Model::updateActionsState(double now, double delta)
598 if (p_updateMechanism == UM_FULL)
599 updateActionsStateFull(now, delta);
600 else if (p_updateMechanism == UM_LAZY)
601 updateActionsStateLazy(now, delta);
603 xbt_die("Invalid cpu update mechanism!");
606 void Model::updateActionsStateLazy(double now, double delta)
611 void Model::updateActionsStateFull(double now, double delta)
617 void Model::addTurnedOnCallback(ResourceCallback rc)
622 void Model::notifyResourceTurnedOn(ResourcePtr r)
627 void Model::addTurnedOffCallback(ResourceCallback rc)
632 void Model::notifyResourceTurnedOff(ResourcePtr r)
637 void Model::addActionCancelCallback(ActionCallback ac)
642 void Model::notifyActionCancel(ActionPtr a)
647 void Model::addActionResumeCallback(ActionCallback ac)
652 void Model::notifyActionResume(ActionPtr a)
657 void Model::addActionSuspendCallback(ActionCallback ac)
662 void Model::notifyActionSuspend(ActionPtr a)
672 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
673 : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props)
676 Resource::Resource(){
677 //FIXME:free(m_name);
678 //FIXME:xbt_dict_free(&m_properties);
681 const char *Resource::getName()
686 xbt_dict_t Resource::getProperties()
691 e_surf_resource_state_t Resource::getState()
693 return p_stateCurrent;
696 bool Resource::isOn()
701 void Resource::turnOn()
705 p_model->notifyResourceTurnedOn(this);
709 void Resource::turnOff()
713 p_model->notifyResourceTurnedOff(this);
717 ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
719 double constraint_value,
720 tmgr_history_t history,
721 e_surf_resource_state_t state_init,
722 tmgr_trace_t state_trace,
724 tmgr_trace_t metric_trace)
725 : Resource(model, name, props)
727 p_constraint = lmm_constraint_new(system, this, constraint_value);
728 p_stateCurrent = state_init;
730 p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
732 p_power.peak = metric_peak;
734 p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
741 const char *surf_action_state_names[6] = {
743 "SURF_ACTION_RUNNING",
744 "SURF_ACTION_FAILED",
746 "SURF_ACTION_TO_FREE",
747 "SURF_ACTION_NOT_IN_THE_SYSTEM"
751 * \brief Initializes the action module of Surf.
753 void surf_action_init(void) {
755 /* the action mallocator will always provide actions of the following size,
756 * so this size should be set to the maximum size of the surf action structures
758 /*FIXME:action_mallocator_allocated_size = sizeof(s_surf_action_network_CM02_t);
759 action_mallocator = xbt_mallocator_new(65536, surf_action_mallocator_new_f,
760 surf_action_mallocator_free_f, surf_action_mallocator_reset_f);*/
764 * \brief Uninitializes the action module of Surf.
766 void surf_action_exit(void) {
767 //FIXME:xbt_mallocator_free(action_mallocator);
772 Action::Action(ModelPtr model, double cost, bool failed):
773 m_cost(cost), p_model(model), m_failed(failed), m_remains(cost),
774 m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
775 m_start(surf_get_clock()), m_finish(-1.0)
780 p_stateHookup.prev = 0;
781 p_stateHookup.next = 0;
783 p_stateSet = p_model->p_failedActionSet;
785 p_stateSet = p_model->p_runningActionSet;
787 xbt_swag_insert(this, p_stateSet);
796 void Action::cancel(){
800 void Action::recycle(){
804 e_surf_action_state_t Action::getState()
806 if (p_stateSet == p_model->p_readyActionSet)
807 return SURF_ACTION_READY;
808 if (p_stateSet == p_model->p_runningActionSet)
809 return SURF_ACTION_RUNNING;
810 if (p_stateSet == p_model->p_failedActionSet)
811 return SURF_ACTION_FAILED;
812 if (p_stateSet == p_model->p_doneActionSet)
813 return SURF_ACTION_DONE;
814 return SURF_ACTION_NOT_IN_THE_SYSTEM;
817 void Action::setState(e_surf_action_state_t state)
819 //surf_action_state_t action_state = &(action->model_type->states);
820 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
821 xbt_swag_remove(this, p_stateSet);
823 if (state == SURF_ACTION_READY)
824 p_stateSet = p_model->p_readyActionSet;
825 else if (state == SURF_ACTION_RUNNING)
826 p_stateSet = p_model->p_runningActionSet;
827 else if (state == SURF_ACTION_FAILED)
828 p_stateSet = p_model->p_failedActionSet;
829 else if (state == SURF_ACTION_DONE)
830 p_stateSet = p_model->p_doneActionSet;
835 xbt_swag_insert(this, p_stateSet);
839 double Action::getStartTime()
844 double Action::getFinishTime()
846 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
847 return m_remains == 0 ? m_finish : -1;
850 double Action::getRemains()
852 XBT_IN("(%p)", this);
857 void Action::setData(void* data)
863 void Action::setCategory(const char *category)
865 XBT_IN("(%p,%s)", this, category);
866 p_category = xbt_strdup(category);
875 void ActionLmm::setMaxDuration(double duration)
877 XBT_IN("(%p,%g)", this, duration);
878 m_maxDuration = duration;
879 if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
880 heapRemove(p_model->p_actionHeap);
884 void ActionLmm::gapRemove() {}
886 void ActionLmm::setPriority(double priority)
888 XBT_IN("(%p,%g)", this, priority);
889 m_priority = priority;
890 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
892 if (p_model->p_updateMechanism == UM_LAZY)
893 heapRemove(p_model->p_actionHeap);
897 void ActionLmm::cancel(){
898 setState(SURF_ACTION_FAILED);
899 if (p_model->p_updateMechanism == UM_LAZY) {
900 xbt_swag_remove(this, p_model->p_modifiedSet);
901 heapRemove(p_model->p_actionHeap);
905 int ActionLmm::unref(){
908 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
910 lmm_variable_free(p_model->p_maxminSystem, p_variable);
911 if (p_model->p_updateMechanism == UM_LAZY) {
912 /* remove from heap */
913 heapRemove(p_model->p_actionHeap);
914 xbt_swag_remove(this, p_model->p_modifiedSet);
917 xbt_free(p_category);
925 void ActionLmm::suspend()
927 XBT_IN("(%p)", this);
928 if (m_suspended != 2) {
929 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
931 if (p_model->p_updateMechanism == UM_LAZY)
932 heapRemove(p_model->p_actionHeap);
937 void ActionLmm::resume()
939 XBT_IN("(%p)", this);
940 if (m_suspended != 2) {
941 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
943 if (p_model->p_updateMechanism == UM_LAZY)
944 heapRemove(p_model->p_actionHeap);
949 bool ActionLmm::isSuspended()
951 return m_suspended == 1;
953 /* insert action on heap using a given key and a hat (heap_action_type)
954 * a hat can be of three types for communications:
956 * NORMAL = this is a normal heap entry stating the date to finish transmitting
957 * LATENCY = this is a heap entry to warn us when the latency is payed
958 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
960 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
963 xbt_heap_push(heap, this, key);
966 void ActionLmm::heapRemove(xbt_heap_t heap)
969 if (m_indexHeap >= 0) {
970 xbt_heap_remove(heap, m_indexHeap);
974 /* added to manage the communication action's heap */
975 void surf_action_lmm_update_index_heap(void *action, int i) {
976 ((ActionLmmPtr)action)->updateIndexHeap(i);
979 void ActionLmm::updateIndexHeap(int i) {
983 double ActionLmm::getRemains()
985 XBT_IN("(%p)", this);
986 /* update remains before return it */
987 if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
988 updateRemainingLazy(surf_get_clock());
993 //FIXME split code in the right places
994 void ActionLmm::updateRemainingLazy(double now)
998 if(p_model == static_cast<ModelPtr>(surf_network_model))
1000 if (m_suspended != 0)
1005 xbt_assert(p_stateSet == p_model->p_runningActionSet,
1006 "You're updating an action that is not running.");
1008 /* bogus priority, skip it */
1009 xbt_assert(m_priority > 0,
1010 "You're updating an action that seems suspended.");
1013 delta = now - m_lastUpdate;
1015 if (m_remains > 0) {
1016 XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate);
1017 double_update(&m_remains, m_lastValue * delta);
1020 if (p_model == static_cast<ModelPtr>(surf_cpu_model) && TRACE_is_enabled()) {
1021 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
1022 TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
1025 XBT_DEBUG("Updating action(%p): remains is now %lf", this, m_remains);
1028 if(p_model == static_cast<ModelPtr>(surf_network_model))
1030 if (m_maxDuration != NO_MAX_DURATION)
1031 double_update(&m_maxDuration, delta);
1033 //FIXME: duplicated code
1034 if ((m_remains <= 0) &&
1035 (lmm_get_variable_weight(p_variable) > 0)) {
1036 m_finish = surf_get_clock();
1037 setState(SURF_ACTION_DONE);
1038 heapRemove(p_model->p_actionHeap);
1039 } else if (((m_maxDuration != NO_MAX_DURATION)
1040 && (m_maxDuration <= 0))) {
1041 m_finish = surf_get_clock();
1042 setState(SURF_ACTION_DONE);
1043 heapRemove(p_model->p_actionHeap);
1048 m_lastValue = lmm_variable_getvalue(p_variable);
1051 /*void Action::cancel()
1053 p_model->notifyActionCancel(this);
1056 void Action::suspend()
1058 p_model->notifyActionSuspend(this);
1061 void Action::resume()
1063 p_model->notifyActionResume(this);
1066 bool Action::isSuspended()