3 #include "simix/smx_host_private.h"
5 XBT_LOG_NEW_CATEGORY(surfpp, "All SURF categories");
6 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surfpp_kernel, surfpp,
7 "Logging specific to SURF (kernel)");
15 XBT_INLINE double surf_get_clock(void)
20 /* This function is a pimple that we ought to fix. But it won't be easy.
22 * The surf_solve() function does properly return the set of actions that changed.
23 * Instead, each model change a global data, and then the caller of surf_solve must
24 * pick into these sets of action_failed and action_done.
26 * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
27 * We worked by putting sentinel actions on every resources we are interested in,
28 * so that surf informs us if/when the corresponding resource fails.
30 * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
31 * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
32 * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
33 * that was turned back up in the meanwhile. This is UGLY and slow.
35 * The proper solution would be to not rely on globals for the action_failed and action_done swags.
36 * They must be passed as parameter by the caller (the handling of these actions in simix may let you
37 * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
38 * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
41 * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
42 * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
43 * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
44 * sees it and react accordingly. This would kill that need for surf to call simix.
48 static void remove_watched_host(void *key)
50 xbt_dict_remove(watched_hosts_lib, *(char**)key);
53 /*TODO: keepit 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 host = (smx_host_t) host;
65 if(SIMIX_host_get_state(host) == SURF_RESOURCE_ON){
66 XBT_INFO("Restart processes on host: %s",SIMIX_host_get_name(host));
67 SIMIX_host_autorestart(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);
81 double Model::shareResourcesLazy(double now)
83 ActionLmmPtr action = NULL;
88 ("Before share resources, the size of modified actions set is %d",
89 xbt_swag_size(p_modifiedSet));
91 lmm_solve(p_maxminSystem);
94 ("After share resources, The size of modified actions set is %d",
95 xbt_swag_size(p_modifiedSet));
97 while((action = (ActionLmmPtr) xbt_swag_extract(p_modifiedSet))) {
100 if (action->p_stateSet != p_runningActionSet)
103 /* bogus priority, skip it */
104 if (action->m_priority <= 0)
107 action->updateRemainingLazy(now);
110 value = lmm_variable_getvalue(action->p_variable);
112 if (action->m_remains > 0) {
113 value = action->m_remains / value;
121 if ((action->m_maxDuration != NO_MAX_DURATION)
124 action->m_maxDuration < min)) {
125 min = action->m_start +
126 action->m_maxDuration;
130 XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
131 action->m_start, now + value,
132 action->m_maxDuration);
135 action->heapRemove(p_actionHeap);
136 action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
137 XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
139 } else DIE_IMPOSSIBLE;
142 //hereafter must have already the min value for this resource model
143 if (xbt_heap_size(p_actionHeap) > 0)
144 min = xbt_heap_maxkey(p_actionHeap) - now;
148 XBT_DEBUG("The minimum with the HEAP %lf", min);
153 double Model::shareResourcesFull(xbt_swag_t running_actions,
156 void (*solve) (lmm_system_t))
158 void *_action = NULL;
159 ActionPtr action = NULL;
162 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + (offset))))
166 xbt_swag_foreach(_action, running_actions) {
167 action = (ActionPtr)_action;
168 value = lmm_variable_getvalue(VARIABLE(action));
169 if ((value > 0) || (action->m_maxDuration >= 0))
177 if (action->m_remains > 0)
178 min = action->m_remains / value;
181 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
182 min = action->m_maxDuration;
184 min = action->m_maxDuration;
187 for (action = (ActionPtr) xbt_swag_getNext(action, running_actions->offset);
189 action = (ActionPtr) xbt_swag_getNext(action, running_actions->offset)) {
190 value = lmm_variable_getvalue(VARIABLE(action));
192 if (action->m_remains > 0)
193 value = action->m_remains / value;
198 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
201 if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
202 min = action->m_maxDuration;
203 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
206 XBT_DEBUG("min value : %f", min);
212 void Model::gapRemove(ActionLmmPtr action) {}
215 void Model::updateActionsStateLazy(double now, double delta)
220 void Model::updateActionsStateFull(double now, double delta)
226 void Model::addTurnedOnCallback(ResourceCallback rc)
231 void Model::notifyResourceTurnedOn(ResourcePtr r)
236 void Model::addTurnedOffCallback(ResourceCallback rc)
241 void Model::notifyResourceTurnedOff(ResourcePtr r)
246 void Model::addActionCancelCallback(ActionCallback ac)
251 void Model::notifyActionCancel(ActionPtr a)
256 void Model::addActionResumeCallback(ActionCallback ac)
261 void Model::notifyActionResume(ActionPtr a)
266 void Model::addActionSuspendCallback(ActionCallback ac)
271 void Model::notifyActionSuspend(ActionPtr a)
281 string Resource::getName() {
285 e_surf_resource_state_t Resource::getState()
287 return m_stateCurrent;
290 bool Resource::isOn()
295 void Resource::turnOn()
299 p_model->notifyResourceTurnedOn(this);
303 void Resource::turnOff()
307 p_model->notifyResourceTurnedOff(this);
314 /* added to manage the communication action's heap */
315 void surf_action_lmm_update_index_heap(void *action, int i) {
316 ((ActionLmmPtr)action)->updateIndexHeap(i);
319 void ActionLmm::updateIndexHeap(int i)
324 /*TODO/const char *surf_action_state_names[6] = {
326 "SURF_ACTION_RUNNING",
327 "SURF_ACTION_FAILED",
329 "SURF_ACTION_TO_FREE",
330 "SURF_ACTION_NOT_IN_THE_SYSTEM"
333 e_surf_action_state_t Action::getState()
335 if (p_stateSet == p_model->p_readyActionSet)
336 return SURF_ACTION_READY;
337 if (p_stateSet == p_model->p_runningActionSet)
338 return SURF_ACTION_RUNNING;
339 if (p_stateSet == p_model->p_failedActionSet)
340 return SURF_ACTION_FAILED;
341 if (p_stateSet == p_model->p_doneActionSet)
342 return SURF_ACTION_DONE;
343 return SURF_ACTION_NOT_IN_THE_SYSTEM;
346 void Action::setState(e_surf_action_state_t state)
348 //surf_action_state_t action_state = &(action->model_type->states);
349 XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
350 xbt_swag_remove(this, p_stateSet);
352 if (state == SURF_ACTION_READY)
353 p_stateSet = p_model->p_readyActionSet;
354 else if (state == SURF_ACTION_RUNNING)
355 p_stateSet = p_model->p_runningActionSet;
356 else if (state == SURF_ACTION_FAILED)
357 p_stateSet = p_model->p_failedActionSet;
358 else if (state == SURF_ACTION_DONE)
359 p_stateSet = p_model->p_doneActionSet;
364 xbt_swag_insert(this, p_stateSet);
368 double Action::getStartTime()
373 double Action::getFinishTime()
375 /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
376 return m_remains == 0 ? m_finish : -1;
379 void Action::setData(void* data)
385 void Action::setCategory(const char *category)
387 XBT_IN("(%p,%s)", this, category);
388 p_category = xbt_strdup(category);
393 /* insert action on heap using a given key and a hat (heap_action_type)
394 * a hat can be of three types for communications:
396 * NORMAL = this is a normal heap entry stating the date to finish transmitting
397 * LATENCY = this is a heap entry to warn us when the latency is payed
398 * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
400 void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
403 xbt_heap_push(heap, this, key);
406 void ActionLmm::heapRemove(xbt_heap_t heap)
409 if (m_indexHeap >= 0) {
410 xbt_heap_remove(heap, m_indexHeap);
414 double ActionLmm::getRemains()
416 XBT_IN("(%p)", this);
417 /* update remains before return it */
418 if (p_updateMechanism == UM_LAZY) /* update remains before return it */
419 updateRemainingLazy(surf_get_clock());
424 /*void Action::cancel()
426 p_model->notifyActionCancel(this);
429 void Action::suspend()
431 p_model->notifyActionSuspend(this);
434 void Action::resume()
436 p_model->notifyActionResume(this);
439 bool Action::isSuspended()