1 #include "surf_private.h"
5 #include "workstation.hpp"
6 #include "vm_workstation.hpp"
7 #include "simix/smx_host_private.h"
8 #include "surf_routing.hpp"
9 #include "simgrid/sg_config.h"
13 XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
15 "Logging specific to SURF (kernel)");
22 /* This function is a pimple that we ought to fix. But it won't be easy.
24 * The surf_solve() function does properly return the set of actions that changed.
25 * Instead, each model change a global data, and then the caller of surf_solve must
26 * pick into these sets of action_failed and action_done.
28 * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
29 * We worked by putting sentinel actions on every resources we are interested in,
30 * so that surf informs us if/when the corresponding resource fails.
32 * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
33 * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
34 * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
35 * that was turned back up in the meanwhile. This is UGLY and slow.
37 * The proper solution would be to not rely on globals for the action_failed and action_done swags.
38 * They must be passed as parameter by the caller (the handling of these actions in simix may let you
39 * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
40 * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
43 * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
44 * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
45 * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
46 * sees it and react accordingly. This would kill that need for surf to call simix.
50 static void remove_watched_host(void *key)
52 xbt_dict_remove(watched_hosts_lib, *(char**)key);
55 /*void surf_watched_hosts(void)
59 xbt_dict_cursor_t cursor;
60 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
62 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
63 xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
65 if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
66 XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
67 SIMIX_host_autorestart((smx_host_t)host);
68 xbt_dynar_push_as(hosts, char*, key);
71 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
73 xbt_dynar_map(hosts, remove_watched_host);
74 xbt_dynar_free(&hosts);
77 /* model_list_invoke contains only surf_workstation and surf_vm_workstation.
78 * The callback functions of cpu_model and network_model will be called from
79 * those of these workstation models. */
80 xbt_dynar_t model_list = NULL; /* for destroying all models correctly */
81 xbt_dynar_t model_list_invoke = NULL; /* for invoking callbacks */
83 tmgr_history_t history = NULL;
84 lmm_system_t maxmin_system = NULL;
85 xbt_dynar_t surf_path = NULL;
86 xbt_dynar_t host_that_restart = NULL;
87 xbt_dict_t watched_hosts_lib;
89 /* Don't forget to update the option description in smx_config when you change this */
90 s_surf_model_description_t surf_network_model_description[] = {
92 "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). ",
93 surf_network_model_init_LegrandVelho},
95 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
96 surf_network_model_init_Constant},
98 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
99 surf_network_model_init_SMPI},
101 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
102 surf_network_model_init_CM02},
105 "Network pseudo-model using the GTNets simulator instead of an analytic model",
106 surf_network_model_init_GTNETS},
110 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
111 surf_network_model_init_NS3},
114 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
115 surf_network_model_init_Reno},
117 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
118 surf_network_model_init_Reno2},
120 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
121 surf_network_model_init_Vegas},
122 {NULL, NULL, NULL} /* this array must be NULL terminated */
125 s_surf_model_description_t surf_cpu_model_description[] = {
127 "Simplistic CPU model (time=size/power).",
128 surf_cpu_model_init_Cas01},
129 {NULL, NULL, NULL} /* this array must be NULL terminated */
132 s_surf_model_description_t surf_workstation_model_description[] = {
134 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
135 surf_workstation_model_init_current_default},
137 "Workstation model that is automatically chosen if you change the network and CPU models",
138 surf_workstation_model_init_compound},
139 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
140 surf_workstation_model_init_ptask_L07},
141 {NULL, NULL, NULL} /* this array must be NULL terminated */
144 s_surf_model_description_t surf_vm_workstation_model_description[] = {
146 "Default vm workstation model.)",
147 surf_vm_workstation_model_init_current_default},
148 {NULL, NULL, NULL} /* this array must be NULL terminated */
151 s_surf_model_description_t surf_optimization_mode_description[] = {
153 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
156 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
159 "Full update of remaining and variables. Slow but may be useful when debugging.",
161 {NULL, NULL, NULL} /* this array must be NULL terminated */
164 s_surf_model_description_t surf_storage_model_description[] = {
166 "Simplistic storage model.",
167 surf_storage_model_init_default},
168 {NULL, NULL, NULL} /* this array must be NULL terminated */
171 #ifdef CONTEXT_THREADS
172 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
175 static double *surf_mins = NULL; /* return value of share_resources for each model */
176 static int surf_min_index; /* current index in surf_mins */
177 static double min; /* duration determined by surf_solve */
181 double surf_get_clock(void)
187 # define FILE_DELIM "\\"
189 # define FILE_DELIM "/" /* FIXME: move to better location */
192 FILE *surf_fopen(const char *name, const char *mode)
195 char *path_elm = NULL;
201 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
202 return fopen(name, mode);
204 /* search relative files in the path */
205 xbt_dynar_foreach(surf_path, cpt, path_elm) {
206 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
207 file = fopen(buff, mode);
217 * Returns the initial path. On Windows the initial path is
218 * the current directory for the current process in the other
219 * case the function returns "./" that represents the current
220 * directory on Unix/Linux platforms.
223 const char *__surf_get_initial_path(void)
228 char current_directory[MAX_PATH + 1] = { 0 };
229 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
230 char root[4] = { 0 };
235 strncpy(root, current_directory, 3);
237 for (i = 0; i < MAX_DRIVE; i++) {
238 if (toupper(root[0]) == disk_drives_letter_table[i][0])
239 return disk_drives_letter_table[i];
248 /* The __surf_is_absolute_file_path() returns 1 if
249 * file_path is a absolute file path, in the other
250 * case the function returns 0.
252 int __surf_is_absolute_file_path(const char *file_path)
255 WIN32_FIND_DATA wfd = { 0 };
256 HANDLE hFile = FindFirstFile(file_path, &wfd);
258 if (INVALID_HANDLE_VALUE == hFile)
264 return (file_path[0] == '/');
268 /** Displays the long description of all registered models, and quit */
269 void model_help(const char *category, s_surf_model_description_t * table)
272 printf("Long description of the %s models accepted by this simulator:\n",
274 for (i = 0; table[i].name; i++)
275 printf(" %s: %s\n", table[i].name, table[i].description);
278 int find_model_description(s_surf_model_description_t * table,
282 char *name_list = NULL;
284 for (i = 0; table[i].name; i++)
285 if (!strcmp(name, table[i].name)) {
288 name_list = strdup(table[0].name);
289 for (i = 1; table[i].name; i++) {
290 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
291 strcat(name_list, ", ");
292 strcat(name_list, table[i].name);
294 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
298 static XBT_INLINE void routing_asr_host_free(void *p)
300 delete ((RoutingEdgePtr) p);
303 static XBT_INLINE void routing_asr_prop_free(void *p)
305 xbt_dict_t elm = (xbt_dict_t) p;
309 static XBT_INLINE void surf_cpu_free(void *r)
311 delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
314 static XBT_INLINE void surf_link_free(void *r)
316 delete dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(r));
319 static XBT_INLINE void surf_workstation_free(void *r)
321 delete dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(r));
325 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
326 *ver_major = SIMGRID_VERSION_MAJOR;
327 *ver_minor = SIMGRID_VERSION_MINOR;
328 *ver_patch = SIMGRID_VERSION_PATCH;
331 void surf_init(int *argc, char **argv)
333 XBT_DEBUG("Create all Libs");
334 host_lib = xbt_lib_new();
335 link_lib = xbt_lib_new();
336 as_router_lib = xbt_lib_new();
337 storage_lib = xbt_lib_new();
338 storage_type_lib = xbt_lib_new();
339 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
341 XBT_DEBUG("Add routing levels");
342 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
343 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
344 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
346 XBT_DEBUG("Add SURF levels");
347 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
348 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
349 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
351 xbt_init(argc, argv);
353 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
354 if (!model_list_invoke)
355 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
357 history = tmgr_history_new();
360 TRACE_add_start_function(TRACE_surf_alloc);
361 TRACE_add_end_function(TRACE_surf_release);
364 sg_config_init(argc, argv);
373 ModelPtr model = NULL;
376 TRACE_end(); /* Just in case it was not called by the upper
377 * layer (or there is no upper layer) */
380 sg_config_finalize();
382 xbt_dynar_foreach(model_list, iter, model)
384 xbt_dynar_free(&model_list);
385 xbt_dynar_free(&model_list_invoke);
389 lmm_system_free(maxmin_system);
390 maxmin_system = NULL;
393 tmgr_history_free(history);
397 #ifdef CONTEXT_THREADS
398 xbt_parmap_destroy(surf_parmap);
402 xbt_dynar_free(&host_that_restart);
403 xbt_dynar_free(&surf_path);
405 xbt_lib_free(&host_lib);
406 xbt_lib_free(&link_lib);
407 xbt_lib_free(&as_router_lib);
408 xbt_lib_free(&storage_lib);
409 xbt_lib_free(&storage_type_lib);
411 xbt_dict_free(&watched_hosts_lib);
414 surf_parse_lex_destroy();
415 surf_parse_free_callbacks();
417 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
423 Model::Model(string name)
424 : m_name(name), m_resOnCB(0), m_resOffCB(0),
425 m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0),
429 p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
430 p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
431 p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
432 p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
434 p_modifiedSet = NULL;
436 p_updateMechanism = UM_UNDEFINED;
437 m_selectiveUpdate = 0;
441 xbt_swag_free(p_readyActionSet);
442 xbt_swag_free(p_runningActionSet);
443 xbt_swag_free(p_failedActionSet);
444 xbt_swag_free(p_doneActionSet);
447 double Model::shareResources(double now)
449 //FIXME: set the good function once and for all
450 if (p_updateMechanism == UM_LAZY)
451 return shareResourcesLazy(now);
452 else if (p_updateMechanism == UM_FULL)
453 return shareResourcesFull(now);
455 xbt_die("Invalid cpu update mechanism!");
458 double Model::shareResourcesLazy(double now)
460 ActionLmmPtr action = NULL;
465 ("Before share resources, the size of modified actions set is %d",
466 xbt_swag_size(p_modifiedSet));
468 lmm_solve(p_maxminSystem);
471 ("After share resources, The size of modified actions set is %d",
472 xbt_swag_size(p_modifiedSet));
474 while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
475 int max_dur_flag = 0;
477 if (action->p_stateSet != p_runningActionSet)
480 /* bogus priority, skip it */
481 if (action->m_priority <= 0)
484 action->updateRemainingLazy(now);
487 value = lmm_variable_getvalue(action->p_variable);
489 if (action->m_remains > 0) {
490 value = action->m_remains / value;
498 if ((action->m_maxDuration != NO_MAX_DURATION)
501 action->m_maxDuration < min)) {
502 min = action->m_start +
503 action->m_maxDuration;
507 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
508 action->m_start, now + value,
509 action->m_maxDuration);
512 action->heapRemove(p_actionHeap);
513 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
514 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
516 } else DIE_IMPOSSIBLE;
519 //hereafter must have already the min value for this resource model
520 if (xbt_heap_size(p_actionHeap) > 0)
521 min = xbt_heap_maxkey(p_actionHeap) - now;
525 XBT_DEBUG("The minimum with the HEAP %lf", min);
530 double Model::shareResourcesFull(double now) {
535 double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
537 void (*solve) (lmm_system_t))
539 void *_action = NULL;
540 ActionLmmPtr action = NULL;
546 xbt_swag_foreach(_action, running_actions) {
547 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
548 value = lmm_variable_getvalue(action->p_variable);
549 if ((value > 0) || (action->m_maxDuration >= 0))
557 if (action->m_remains > 0)
558 min = action->m_remains / value;
561 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
562 min = action->m_maxDuration;
564 min = action->m_maxDuration;
567 for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
569 _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
570 action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
571 value = lmm_variable_getvalue(action->p_variable);
573 if (action->m_remains > 0)
574 value = action->m_remains / value;
579 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
582 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
583 min = action->m_maxDuration;
584 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
587 XBT_DEBUG("min value : %f", min);
592 void Model::updateActionsState(double now, double delta)
594 if (p_updateMechanism == UM_FULL)
595 updateActionsStateFull(now, delta);
596 else if (p_updateMechanism == UM_LAZY)
597 updateActionsStateLazy(now, delta);
599 xbt_die("Invalid cpu update mechanism!");
602 void Model::updateActionsStateLazy(double now, double delta)
607 void Model::updateActionsStateFull(double now, double delta)
613 void Model::addTurnedOnCallback(ResourceCallback rc)
618 void Model::notifyResourceTurnedOn(ResourcePtr r)
623 void Model::addTurnedOffCallback(ResourceCallback rc)
628 void Model::notifyResourceTurnedOff(ResourcePtr r)
633 void Model::addActionCancelCallback(ActionCallback ac)
638 void Model::notifyActionCancel(ActionPtr a)
643 void Model::addActionResumeCallback(ActionCallback ac)
648 void Model::notifyActionResume(ActionPtr a)
653 void Model::addActionSuspendCallback(ActionCallback ac)
658 void Model::notifyActionSuspend(ActionPtr a)
668 Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
669 : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props)
672 Resource::Resource(){
673 //FIXME:free(m_name);
674 //FIXME:xbt_dict_free(&m_properties);
677 const char *Resource::getName()
682 xbt_dict_t Resource::getProperties()
687 e_surf_resource_state_t Resource::getState()
689 return p_stateCurrent;
692 void Resource::setState(e_surf_resource_state_t state)
694 p_stateCurrent = state;
697 bool Resource::isOn()
702 void Resource::turnOn()
706 p_model->notifyResourceTurnedOn(this);
710 void Resource::turnOff()
714 p_model->notifyResourceTurnedOff(this);
718 ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
720 double constraint_value,
721 tmgr_history_t history,
722 e_surf_resource_state_t state_init,
723 tmgr_trace_t state_trace,
725 tmgr_trace_t metric_trace)
726 : Resource(model, name, props)
728 p_constraint = lmm_constraint_new(system, this, constraint_value);
729 p_stateCurrent = state_init;
731 p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
733 p_power.peak = metric_peak;
735 p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
742 const char *surf_action_state_names[6] = {
744 "SURF_ACTION_RUNNING",
745 "SURF_ACTION_FAILED",
747 "SURF_ACTION_TO_FREE",
748 "SURF_ACTION_NOT_IN_THE_SYSTEM"
753 Action::Action(ModelPtr model, double cost, bool failed):
754 m_cost(cost), p_model(model), m_failed(failed), m_remains(cost),
755 m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
756 m_start(surf_get_clock()), m_finish(-1.0)
761 p_stateHookup.prev = 0;
762 p_stateHookup.next = 0;
764 p_stateSet = p_model->p_failedActionSet;
766 p_stateSet = p_model->p_runningActionSet;
768 xbt_swag_insert(this, p_stateSet);
777 void Action::cancel(){
781 void Action::recycle(){
785 e_surf_action_state_t Action::getState()
787 if (p_stateSet == p_model->p_readyActionSet)
788 return SURF_ACTION_READY;
789 if (p_stateSet == p_model->p_runningActionSet)
790 return SURF_ACTION_RUNNING;
791 if (p_stateSet == p_model->p_failedActionSet)
792 return SURF_ACTION_FAILED;
793 if (p_stateSet == p_model->p_doneActionSet)
794 return SURF_ACTION_DONE;
795 return SURF_ACTION_NOT_IN_THE_SYSTEM;
798 void Action::setState(e_surf_action_state_t state)
800 //surf_action_state_t action_state = &(action->model_type->states);
801 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
802 xbt_swag_remove(this, p_stateSet);
804 if (state == SURF_ACTION_READY)
805 p_stateSet = p_model->p_readyActionSet;
806 else if (state == SURF_ACTION_RUNNING)
807 p_stateSet = p_model->p_runningActionSet;
808 else if (state == SURF_ACTION_FAILED)
809 p_stateSet = p_model->p_failedActionSet;
810 else if (state == SURF_ACTION_DONE)
811 p_stateSet = p_model->p_doneActionSet;
816 xbt_swag_insert(this, p_stateSet);
820 double Action::getStartTime()
825 double Action::getFinishTime()
827 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
828 return m_remains == 0 ? m_finish : -1;
831 double Action::getRemains()
833 XBT_IN("(%p)", this);
838 void Action::setData(void* data)
844 void Action::setCategory(const char *category)
846 XBT_IN("(%p,%s)", this, category);
847 p_category = xbt_strdup(category);
856 void ActionLmm::setMaxDuration(double duration)
858 XBT_IN("(%p,%g)", this, duration);
859 m_maxDuration = duration;
860 if (p_model->p_updateMechanism == UM_LAZY) // remove action from the heap
861 heapRemove(p_model->p_actionHeap);
865 void ActionLmm::gapRemove() {}
867 void ActionLmm::setPriority(double priority)
869 XBT_IN("(%p,%g)", this, priority);
870 m_priority = priority;
871 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
873 if (p_model->p_updateMechanism == UM_LAZY)
874 heapRemove(p_model->p_actionHeap);
878 void ActionLmm::cancel(){
879 setState(SURF_ACTION_FAILED);
880 if (p_model->p_updateMechanism == UM_LAZY) {
881 xbt_swag_remove(this, p_model->p_modifiedSet);
882 heapRemove(p_model->p_actionHeap);
886 int ActionLmm::unref(){
889 xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
891 lmm_variable_free(p_model->p_maxminSystem, p_variable);
892 if (p_model->p_updateMechanism == UM_LAZY) {
893 /* remove from heap */
894 heapRemove(p_model->p_actionHeap);
895 xbt_swag_remove(this, p_model->p_modifiedSet);
898 xbt_free(p_category);
906 void ActionLmm::suspend()
908 XBT_IN("(%p)", this);
909 if (m_suspended != 2) {
910 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
912 if (p_model->p_updateMechanism == UM_LAZY)
913 heapRemove(p_model->p_actionHeap);
918 void ActionLmm::resume()
920 XBT_IN("(%p)", this);
921 if (m_suspended != 2) {
922 lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
924 if (p_model->p_updateMechanism == UM_LAZY)
925 heapRemove(p_model->p_actionHeap);
930 bool ActionLmm::isSuspended()
932 return m_suspended == 1;
934 /* insert action on heap using a given key and a hat (heap_action_type)
935 * a hat can be of three types for communications:
937 * NORMAL = this is a normal heap entry stating the date to finish transmitting
938 * LATENCY = this is a heap entry to warn us when the latency is payed
939 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
941 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
944 xbt_heap_push(heap, this, key);
947 void ActionLmm::heapRemove(xbt_heap_t heap)
950 if (m_indexHeap >= 0) {
951 xbt_heap_remove(heap, m_indexHeap);
955 /* added to manage the communication action's heap */
956 void surf_action_lmm_update_index_heap(void *action, int i) {
957 ((ActionLmmPtr)action)->updateIndexHeap(i);
960 void ActionLmm::updateIndexHeap(int i) {
964 double ActionLmm::getRemains()
966 XBT_IN("(%p)", this);
967 /* update remains before return it */
968 if (p_model->p_updateMechanism == UM_LAZY) /* update remains before return it */
969 updateRemainingLazy(surf_get_clock());
974 //FIXME split code in the right places
975 void ActionLmm::updateRemainingLazy(double now)
979 if(p_model == static_cast<ModelPtr>(surf_network_model))
981 if (m_suspended != 0)
986 xbt_assert(p_stateSet == p_model->p_runningActionSet,
987 "You're updating an action that is not running.");
989 /* bogus priority, skip it */
990 xbt_assert(m_priority > 0,
991 "You're updating an action that seems suspended.");
994 delta = now - m_lastUpdate;
997 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
998 double_update(&m_remains, m_lastValue * delta);
1001 if (p_model == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
1002 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
1003 TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
1006 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1009 if(p_model == static_cast<ModelPtr>(surf_network_model))
1011 if (m_maxDuration != NO_MAX_DURATION)
1012 double_update(&m_maxDuration, delta);
1014 //FIXME: duplicated code
1015 if ((m_remains <= 0) &&
1016 (lmm_get_variable_weight(p_variable) > 0)) {
1017 m_finish = surf_get_clock();
1018 setState(SURF_ACTION_DONE);
1019 heapRemove(p_model->p_actionHeap);
1020 } else if (((m_maxDuration != NO_MAX_DURATION)
1021 && (m_maxDuration <= 0))) {
1022 m_finish = surf_get_clock();
1023 setState(SURF_ACTION_DONE);
1024 heapRemove(p_model->p_actionHeap);
1029 m_lastValue = lmm_variable_getvalue(p_variable);
1032 /*void Action::cancel()
1034 p_model->notifyActionCancel(this);
1037 void Action::suspend()
1039 p_model->notifyActionSuspend(this);
1042 void Action::resume()
1044 p_model->notifyActionResume(this);
1047 bool Action::isSuspended()