1 /* Copyright (c) 2004-2014. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
7 #include "surf_private.h"
8 #include "surf_interface.hpp"
9 #include "network_interface.hpp"
10 #include "cpu_interface.hpp"
11 #include "workstation_interface.hpp"
12 #include "vm_workstation_interface.hpp"
13 #include "simix/smx_host_private.h"
14 #include "surf_routing.hpp"
15 #include "simgrid/sg_config.h"
18 XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
19 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
20 "Logging specific to SURF (kernel)");
26 /* This function is a pimple that we ought to fix. But it won't be easy.
28 * The surf_solve() function does properly return the set of actions that changed.
29 * Instead, each model change a global data, and then the caller of surf_solve must
30 * pick into these sets of action_failed and action_done.
32 * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
33 * We worked by putting sentinel actions on every resources we are interested in,
34 * so that surf informs us if/when the corresponding resource fails.
36 * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
37 * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
38 * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
39 * that was turned back up in the meanwhile. This is UGLY and slow.
41 * The proper solution would be to not rely on globals for the action_failed and action_done swags.
42 * They must be passed as parameter by the caller (the handling of these actions in simix may let you
43 * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
44 * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
47 * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
48 * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
49 * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
50 * sees it and react accordingly. This would kill that need for surf to call simix.
54 /*static void remove_watched_host(void *key)
56 xbt_dict_remove(watched_hosts_lib, *(char**)key);
59 /*void surf_watched_hosts(void)
63 xbt_dict_cursor_t cursor;
64 xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
66 XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
67 xbt_dict_foreach(watched_hosts_lib, cursor, key, host)
69 if(SIMIX_host_get_state((smx_host_t)host) == SURF_RESOURCE_ON){
70 XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
71 SIMIX_host_autorestart((smx_host_t)host);
72 xbt_dynar_push_as(hosts, char*, key);
75 XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
77 xbt_dynar_map(hosts, remove_watched_host);
78 xbt_dynar_free(&hosts);
81 /* model_list_invoke contains only surf_workstation and surf_vm_workstation.
82 * The callback functions of cpu_model and network_model will be called from
83 * those of these workstation models. */
84 xbt_dynar_t model_list = NULL; /* for destroying all models correctly */
85 xbt_dynar_t model_list_invoke = NULL; /* for invoking callbacks */
87 tmgr_history_t history = NULL;
88 lmm_system_t maxmin_system = NULL;
89 xbt_dynar_t surf_path = NULL;
90 xbt_dynar_t host_that_restart = NULL;
91 xbt_dict_t watched_hosts_lib;
93 surf_callback(void, void) surfExitCallbacks;
95 s_surf_model_description_t surf_plugin_description[] = {
97 "Cpu energy consumption.",
98 sg_energy_plugin_init},
99 {NULL, NULL, NULL} /* this array must be NULL terminated */
102 /* Don't forget to update the option description in smx_config when you change this */
103 s_surf_model_description_t surf_network_model_description[] = {
105 "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). ",
106 surf_network_model_init_LegrandVelho},
108 "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
109 surf_network_model_init_Constant},
111 "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
112 surf_network_model_init_SMPI},
114 "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
115 surf_network_model_init_CM02},
118 "Network pseudo-model using the GTNets simulator instead of an analytic model",
119 surf_network_model_init_GTNETS},
123 "Network pseudo-model using the NS3 tcp model instead of an analytic model",
124 surf_network_model_init_NS3},
127 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
128 surf_network_model_init_Reno},
130 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
131 surf_network_model_init_Reno2},
133 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
134 surf_network_model_init_Vegas},
135 {NULL, NULL, NULL} /* this array must be NULL terminated */
138 s_surf_model_description_t surf_cpu_model_description[] = {
140 "Simplistic CPU model (time=size/power).",
141 surf_cpu_model_init_Cas01},
142 {NULL, NULL, NULL} /* this array must be NULL terminated */
145 s_surf_model_description_t surf_workstation_model_description[] = {
147 "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
148 surf_workstation_model_init_current_default},
150 "Workstation model that is automatically chosen if you change the network and CPU models",
151 surf_workstation_model_init_compound},
152 {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
153 surf_workstation_model_init_ptask_L07},
154 {NULL, NULL, NULL} /* this array must be NULL terminated */
157 s_surf_model_description_t surf_vm_workstation_model_description[] = {
159 "Default vm workstation model.",
160 surf_vm_workstation_model_init_current_default},
161 {NULL, NULL, NULL} /* this array must be NULL terminated */
164 s_surf_model_description_t surf_optimization_mode_description[] = {
166 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
169 "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
172 "Full update of remaining and variables. Slow but may be useful when debugging.",
174 {NULL, NULL, NULL} /* this array must be NULL terminated */
177 s_surf_model_description_t surf_storage_model_description[] = {
179 "Simplistic storage model.",
180 surf_storage_model_init_default},
181 {NULL, NULL, NULL} /* this array must be NULL terminated */
184 #ifdef CONTEXT_THREADS
185 static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
189 double *surf_mins = NULL; /* return value of share_resources for each model */
190 int surf_min_index; /* current index in surf_mins */
191 double surf_min; /* duration determined by surf_solve */
193 double surf_get_clock(void)
199 # define FILE_DELIM "\\"
201 # define FILE_DELIM "/" /* FIXME: move to better location */
204 FILE *surf_fopen(const char *name, const char *mode)
207 char *path_elm = NULL;
213 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
214 return fopen(name, mode);
216 /* search relative files in the path */
217 xbt_dynar_foreach(surf_path, cpt, path_elm) {
218 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
219 file = fopen(buff, mode);
235 static const char *disk_drives_letter_table[MAX_DRIVE] = {
266 * Returns the initial path. On Windows the initial path is
267 * the current directory for the current process in the other
268 * case the function returns "./" that represents the current
269 * directory on Unix/Linux platforms.
272 const char *__surf_get_initial_path(void)
277 char current_directory[MAX_PATH + 1] = { 0 };
278 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
279 char root[4] = { 0 };
284 strncpy(root, current_directory, 3);
286 for (i = 0; i < MAX_DRIVE; i++) {
287 if (toupper(root[0]) == disk_drives_letter_table[i][0])
288 return disk_drives_letter_table[i];
297 /* The __surf_is_absolute_file_path() returns 1 if
298 * file_path is a absolute file path, in the other
299 * case the function returns 0.
301 int __surf_is_absolute_file_path(const char *file_path)
304 WIN32_FIND_DATA wfd = { 0 };
305 HANDLE hFile = FindFirstFile(file_path, &wfd);
307 if (INVALID_HANDLE_VALUE == hFile)
313 return (file_path[0] == '/');
317 /** Displays the long description of all registered models, and quit */
318 void model_help(const char *category, s_surf_model_description_t * table)
321 printf("Long description of the %s models accepted by this simulator:\n",
323 for (i = 0; table[i].name; i++)
324 printf(" %s: %s\n", table[i].name, table[i].description);
327 int find_model_description(s_surf_model_description_t * table,
331 char *name_list = NULL;
333 for (i = 0; table[i].name; i++)
334 if (!strcmp(name, table[i].name)) {
338 xbt_die("No model is valid! This is a bug.");
339 name_list = xbt_strdup(table[0].name);
340 for (i = 1; table[i].name; i++) {
341 name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
342 strcat(name_list, ", ");
343 strcat(name_list, table[i].name);
345 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
349 static XBT_INLINE void routing_asr_host_free(void *p)
351 delete ((RoutingEdgePtr) p);
354 static XBT_INLINE void routing_asr_prop_free(void *p)
356 xbt_dict_t elm = (xbt_dict_t) p;
360 static XBT_INLINE void surf_cpu_free(void *r)
362 delete static_cast<CpuPtr>(r);
365 static XBT_INLINE void surf_link_free(void *r)
367 delete static_cast<NetworkLinkPtr>(r);
370 static XBT_INLINE void surf_workstation_free(void *r)
372 delete static_cast<WorkstationPtr>(r);
375 static XBT_INLINE void surf_storage_free(void *r)
377 delete static_cast<StoragePtr>(r);
381 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
382 *ver_major = SIMGRID_VERSION_MAJOR;
383 *ver_minor = SIMGRID_VERSION_MINOR;
384 *ver_patch = SIMGRID_VERSION_PATCH;
387 void surf_init(int *argc, char **argv)
389 XBT_DEBUG("Create all Libs");
390 host_lib = xbt_lib_new();
391 link_lib = xbt_lib_new();
392 as_router_lib = xbt_lib_new();
393 storage_lib = xbt_lib_new();
394 storage_type_lib = xbt_lib_new();
395 file_lib = xbt_lib_new();
396 watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
398 XBT_DEBUG("Add routing levels");
399 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
400 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
401 ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
403 XBT_DEBUG("Add SURF levels");
404 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
405 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
406 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
407 SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,surf_storage_free);
409 xbt_init(argc, argv);
411 model_list = xbt_dynar_new(sizeof(ModelPtr), NULL);
412 if (!model_list_invoke)
413 model_list_invoke = xbt_dynar_new(sizeof(ModelPtr), NULL);
415 history = tmgr_history_new();
418 TRACE_add_start_function(TRACE_surf_alloc);
419 TRACE_add_end_function(TRACE_surf_release);
422 sg_config_init(argc, argv);
431 ModelPtr model = NULL;
434 TRACE_end(); /* Just in case it was not called by the upper
435 * layer (or there is no upper layer) */
438 sg_config_finalize();
440 xbt_dynar_free(&host_that_restart);
441 xbt_dynar_free(&surf_path);
443 xbt_lib_free(&host_lib);
444 xbt_lib_free(&link_lib);
445 xbt_lib_free(&as_router_lib);
446 xbt_lib_free(&storage_lib);
447 xbt_lib_free(&storage_type_lib);
448 xbt_lib_free(&file_lib);
449 xbt_dict_free(&watched_hosts_lib);
451 xbt_dynar_foreach(model_list, iter, model)
453 xbt_dynar_free(&model_list);
454 xbt_dynar_free(&model_list_invoke);
457 surf_callback_emit(surfExitCallbacks);
460 lmm_system_free(maxmin_system);
461 maxmin_system = NULL;
464 tmgr_history_free(history);
468 #ifdef CONTEXT_THREADS
469 xbt_parmap_destroy(surf_parmap);
476 surf_parse_lex_destroy();
477 surf_parse_free_callbacks();
479 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
486 Model::Model(const char *name)
487 : p_maxminSystem(NULL)
490 p_readyActionSet = new ActionList();
491 p_runningActionSet = new ActionList();
492 p_failedActionSet = new ActionList();
493 p_doneActionSet = new ActionList();
495 p_modifiedSet = NULL;
497 p_updateMechanism = UM_UNDEFINED;
498 m_selectiveUpdate = 0;
502 delete p_readyActionSet;
503 delete p_runningActionSet;
504 delete p_failedActionSet;
505 delete p_doneActionSet;
508 double Model::shareResources(double now)
510 //FIXME: set the good function once and for all
511 if (p_updateMechanism == UM_LAZY)
512 return shareResourcesLazy(now);
513 else if (p_updateMechanism == UM_FULL)
514 return shareResourcesFull(now);
516 xbt_die("Invalid cpu update mechanism!");
519 double Model::shareResourcesLazy(double now)
521 ActionPtr action = NULL;
523 double share, time_to_completion;
526 ("Before share resources, the size of modified actions set is %zd",
527 p_modifiedSet->size());
529 lmm_solve(p_maxminSystem);
532 ("After share resources, The size of modified actions set is %zd",
533 p_modifiedSet->size());
535 while(!p_modifiedSet->empty()) {
536 action = &(p_modifiedSet->front());
537 p_modifiedSet->pop_front();
538 int max_dur_flag = 0;
540 if (action->getStateSet() != p_runningActionSet)
543 /* bogus priority, skip it */
544 if (action->getPriority() <= 0 || action->getHat()==LATENCY)
547 action->updateRemainingLazy(now);
550 time_to_completion = -1;
551 share = lmm_variable_getvalue(action->getVariable());
554 if (action->getRemains() > 0) {
555 time_to_completion = action->getRemainsNoUpdate() / share;
557 time_to_completion = 0.0;
559 min = now + time_to_completion; // when the task will complete if nothing changes
562 if ((action->getMaxDuration() != NO_MAX_DURATION)
564 || action->getStartTime() +
565 action->getMaxDuration() < min)) {
566 min = action->getStartTime() +
567 action->getMaxDuration(); // when the task will complete anyway because of the deadline if any
572 XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
574 XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
575 action->getStartTime(), min, share,
576 action->getMaxDuration());
579 action->heapRemove(p_actionHeap);
580 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
581 XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
583 } else DIE_IMPOSSIBLE;
586 //hereafter must have already the min value for this resource model
587 if (xbt_heap_size(p_actionHeap) > 0)
588 min = xbt_heap_maxkey(p_actionHeap) - now;
592 XBT_DEBUG("The minimum with the HEAP %f", min);
597 double Model::shareResourcesFull(double /*now*/) {
601 double Model::shareResourcesMaxMin(ActionListPtr running_actions,
603 void (*solve) (lmm_system_t))
605 ActionPtr action = NULL;
611 ActionList::iterator it(running_actions->begin()), itend(running_actions->end());
612 for(; it != itend ; ++it) {
614 value = lmm_variable_getvalue(action->getVariable());
615 if ((value > 0) || (action->getMaxDuration() >= 0))
623 if (action->getRemains() > 0)
624 min = action->getRemainsNoUpdate() / value;
627 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min))
628 min = action->getMaxDuration();
630 min = action->getMaxDuration();
633 for (++it; it != itend; ++it) {
635 value = lmm_variable_getvalue(action->getVariable());
637 if (action->getRemains() > 0)
638 value = action->getRemainsNoUpdate() / value;
643 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
646 if ((action->getMaxDuration() >= 0) && (action->getMaxDuration() < min)) {
647 min = action->getMaxDuration();
648 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
651 XBT_DEBUG("min value : %f", min);
656 void Model::updateActionsState(double now, double delta)
658 if (p_updateMechanism == UM_FULL)
659 updateActionsStateFull(now, delta);
660 else if (p_updateMechanism == UM_LAZY)
661 updateActionsStateLazy(now, delta);
663 xbt_die("Invalid cpu update mechanism!");
666 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
670 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
679 : p_name(NULL), p_properties(NULL), p_model(NULL)
682 Resource::Resource(ModelPtr model, const char *name, xbt_dict_t props)
683 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
684 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON)
687 Resource::Resource(ModelPtr model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
688 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
689 , m_running(true), m_stateCurrent(SURF_RESOURCE_ON), p_constraint(constraint)
692 Resource::Resource(ModelPtr model, const char *name, xbt_dict_t props, e_surf_resource_state_t stateInit)
693 : p_name(xbt_strdup(name)), p_properties(props), p_model(model)
694 , m_running(true), m_stateCurrent(stateInit)
697 Resource::~Resource() {
698 xbt_free((void*)p_name);
699 xbt_dict_free(&p_properties);
702 e_surf_resource_state_t Resource::getState()
704 return m_stateCurrent;
707 void Resource::setState(e_surf_resource_state_t state)
709 m_stateCurrent = state;
712 bool Resource::isOn()
717 void Resource::turnOn()
724 void Resource::turnOff()
731 ModelPtr Resource::getModel() {
735 const char *Resource::getName() {
739 xbt_dict_t Resource::getProperties() {
740 if (p_properties==NULL)
741 p_properties = xbt_dict_new();
745 lmm_constraint_t Resource::getConstraint() {
753 const char *surf_action_state_names[6] = {
755 "SURF_ACTION_RUNNING",
756 "SURF_ACTION_FAILED",
758 "SURF_ACTION_TO_FREE",
759 "SURF_ACTION_NOT_IN_THE_SYSTEM"
766 Action::Action(ModelPtr model, double cost, bool failed)
770 , m_maxDuration(NO_MAX_DURATION)
773 , m_start(surf_get_clock())
785 p_stateHookup.prev = 0;
786 p_stateHookup.next = 0;
788 p_stateSet = getModel()->getFailedActionSet();
790 p_stateSet = getModel()->getRunningActionSet();
792 p_stateSet->push_back(*this);
795 Action::Action(ModelPtr model, double cost, bool failed, lmm_variable_t var)
799 , m_maxDuration(NO_MAX_DURATION)
802 , m_start(surf_get_clock())
814 p_stateHookup.prev = 0;
815 p_stateHookup.next = 0;
817 p_stateSet = getModel()->getFailedActionSet();
819 p_stateSet = getModel()->getRunningActionSet();
821 p_stateSet->push_back(*this);
826 xbt_free(p_category);
830 void Action::finish() {
831 m_finish = surf_get_clock();
834 e_surf_action_state_t Action::getState()
836 if (p_stateSet == getModel()->getReadyActionSet())
837 return SURF_ACTION_READY;
838 if (p_stateSet == getModel()->getRunningActionSet())
839 return SURF_ACTION_RUNNING;
840 if (p_stateSet == getModel()->getFailedActionSet())
841 return SURF_ACTION_FAILED;
842 if (p_stateSet == getModel()->getDoneActionSet())
843 return SURF_ACTION_DONE;
844 return SURF_ACTION_NOT_IN_THE_SYSTEM;
847 void Action::setState(e_surf_action_state_t state)
849 //surf_action_state_t action_state = &(action->model_type->states);
850 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
851 p_stateSet->erase(p_stateSet->iterator_to(*this));
852 if (state == SURF_ACTION_READY)
853 p_stateSet = getModel()->getReadyActionSet();
854 else if (state == SURF_ACTION_RUNNING)
855 p_stateSet = getModel()->getRunningActionSet();
856 else if (state == SURF_ACTION_FAILED)
857 p_stateSet = getModel()->getFailedActionSet();
858 else if (state == SURF_ACTION_DONE)
859 p_stateSet = getModel()->getDoneActionSet();
864 p_stateSet->push_back(*this);
868 double Action::getBound()
870 return (p_variable) ? lmm_variable_getbound(p_variable) : 0;
873 void Action::setBound(double bound)
875 XBT_IN("(%p,%g)", this, bound);
877 lmm_update_variable_bound(getModel()->getMaxminSystem(), getVariable(), bound);
879 if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate()!=surf_get_clock())
880 heapRemove(getModel()->getActionHeap());
884 double Action::getStartTime()
889 double Action::getFinishTime()
891 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
892 return m_remains == 0 ? m_finish : -1;
895 void Action::setData(void* data)
901 void Action::setCategory(const char *category)
903 XBT_IN("(%p,%s)", this, category);
904 p_category = xbt_strdup(category);
913 void Action::setMaxDuration(double duration)
915 XBT_IN("(%p,%g)", this, duration);
916 m_maxDuration = duration;
917 if (getModel()->getUpdateMechanism() == UM_LAZY) // remove action from the heap
918 heapRemove(getModel()->getActionHeap());
922 void Action::gapRemove() {}
924 void Action::setPriority(double priority)
926 XBT_IN("(%p,%g)", this, priority);
927 m_priority = priority;
928 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), priority);
930 if (getModel()->getUpdateMechanism() == UM_LAZY)
931 heapRemove(getModel()->getActionHeap());
935 void Action::cancel(){
936 setState(SURF_ACTION_FAILED);
937 if (getModel()->getUpdateMechanism() == UM_LAZY) {
938 if (actionLmmHook::is_linked())
939 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
940 heapRemove(getModel()->getActionHeap());
947 if (actionHook::is_linked())
948 p_stateSet->erase(p_stateSet->iterator_to(*this));
950 lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
951 if (getModel()->getUpdateMechanism() == UM_LAZY) {
952 /* remove from heap */
953 heapRemove(getModel()->getActionHeap());
954 if (actionLmmHook::is_linked())
955 getModel()->getModifiedSet()->erase(getModel()->getModifiedSet()->iterator_to(*this));
963 void Action::suspend()
965 XBT_IN("(%p)", this);
966 if (m_suspended != 2) {
967 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
969 if (getModel()->getUpdateMechanism() == UM_LAZY)
970 heapRemove(getModel()->getActionHeap());
975 void Action::resume()
977 XBT_IN("(%p)", this);
978 if (m_suspended != 2) {
979 lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), m_priority);
981 if (getModel()->getUpdateMechanism() == UM_LAZY)
982 heapRemove(getModel()->getActionHeap());
987 bool Action::isSuspended()
989 return m_suspended == 1;
991 /* insert action on heap using a given key and a hat (heap_action_type)
992 * a hat can be of three types for communications:
994 * NORMAL = this is a normal heap entry stating the date to finish transmitting
995 * LATENCY = this is a heap entry to warn us when the latency is payed
996 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
998 void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
1001 xbt_heap_push(heap, this, key);
1004 void Action::heapRemove(xbt_heap_t heap)
1007 if (m_indexHeap >= 0) {
1008 xbt_heap_remove(heap, m_indexHeap);
1012 /* added to manage the communication action's heap */
1013 void surf_action_lmm_update_index_heap(void *action, int i) {
1014 ((ActionPtr)action)->updateIndexHeap(i);
1017 void Action::updateIndexHeap(int i) {
1021 double Action::getRemains()
1023 XBT_IN("(%p)", this);
1024 /* update remains before return it */
1025 if (getModel()->getUpdateMechanism() == UM_LAZY) /* update remains before return it */
1026 updateRemainingLazy(surf_get_clock());
1031 double Action::getRemainsNoUpdate()
1036 //FIXME split code in the right places
1037 void Action::updateRemainingLazy(double now)
1041 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1043 if (m_suspended != 0)
1048 xbt_assert(p_stateSet == getModel()->getRunningActionSet(),
1049 "You're updating an action that is not running.");
1051 /* bogus priority, skip it */
1052 xbt_assert(m_priority > 0,
1053 "You're updating an action that seems suspended.");
1056 delta = now - m_lastUpdate;
1058 if (m_remains > 0) {
1059 XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
1060 double_update(&m_remains, m_lastValue * delta, sg_surf_precision*sg_maxmin_precision);
1063 if (getModel() == static_cast<ModelPtr>(surf_cpu_model_pm) && TRACE_is_enabled()) {
1064 ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
1065 TRACE_surf_host_set_utilization(cpu->getName(), getCategory(), m_lastValue, m_lastUpdate, now - m_lastUpdate);
1068 XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
1071 if(getModel() == static_cast<ModelPtr>(surf_network_model))
1073 if (m_maxDuration != NO_MAX_DURATION)
1074 double_update(&m_maxDuration, delta, sg_surf_precision);
1076 //FIXME: duplicated code
1077 if ((m_remains <= 0) &&
1078 (lmm_get_variable_weight(getVariable()) > 0)) {
1080 setState(SURF_ACTION_DONE);
1081 heapRemove(getModel()->getActionHeap());
1082 } else if (((m_maxDuration != NO_MAX_DURATION)
1083 && (m_maxDuration <= 0))) {
1085 setState(SURF_ACTION_DONE);
1086 heapRemove(getModel()->getActionHeap());
1091 m_lastValue = lmm_variable_getvalue(getVariable());