Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
54b03920ca027644d16245b9ff6829f8c1417e07
[simgrid.git] / src / kernel / resource / Model.cpp
1 /* Copyright (c) 2004-2018. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "simgrid/kernel/resource/Model.hpp"
7 #include "src/kernel/lmm/maxmin.hpp"
8
9 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(resource);
10
11 namespace simgrid {
12 namespace kernel {
13 namespace resource {
14
15 Model::Model() = default;
16
17 Model::~Model()
18 {
19   delete readyActionSet_;
20   delete runningActionSet_;
21   delete failedActionSet_;
22   delete doneActionSet_;
23   delete modifiedSet_;
24   delete maxminSystem_;
25 }
26
27 Action* Model::actionHeapPop()
28 {
29   Action* action = actionHeap_.top().second;
30   actionHeap_.pop();
31   action->clearHeapHandle();
32   return action;
33 }
34
35 double Model::nextOccuringEvent(double now)
36 {
37   // FIXME: set the good function once and for all
38   if (updateMechanism_ == UM_LAZY)
39     return nextOccuringEventLazy(now);
40   else if (updateMechanism_ == UM_FULL)
41     return nextOccuringEventFull(now);
42   else
43     xbt_die("Invalid cpu update mechanism!");
44 }
45
46 double Model::nextOccuringEventLazy(double now)
47 {
48   XBT_DEBUG("Before share resources, the size of modified actions set is %zu", modifiedSet_->size());
49   lmm_solve(maxminSystem_);
50   XBT_DEBUG("After share resources, The size of modified actions set is %zu", modifiedSet_->size());
51
52   while (not modifiedSet_->empty()) {
53     Action* action = &(modifiedSet_->front());
54     modifiedSet_->pop_front();
55     bool max_dur_flag = false;
56
57     if (action->getStateSet() != runningActionSet_)
58       continue;
59
60     /* bogus priority, skip it */
61     if (action->getPriority() <= 0 || action->getType() == Action::Type::LATENCY)
62       continue;
63
64     action->updateRemainingLazy(now);
65
66     double min   = -1;
67     double share = action->getVariable()->get_value();
68
69     if (share > 0) {
70       double time_to_completion;
71       if (action->getRemains() > 0) {
72         time_to_completion = action->getRemainsNoUpdate() / share;
73       } else {
74         time_to_completion = 0.0;
75       }
76       min = now + time_to_completion; // when the task will complete if nothing changes
77     }
78
79     if ((action->getMaxDuration() > NO_MAX_DURATION) &&
80         (min <= -1 || action->getStartTime() + action->getMaxDuration() < min)) {
81       // when the task will complete anyway because of the deadline if any
82       min          = action->getStartTime() + action->getMaxDuration();
83       max_dur_flag = true;
84     }
85
86     XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->getVariable()->id_int);
87
88     XBT_DEBUG("Action(%p) Start %f. May finish at %f (got a share of %f). Max_duration %f", action,
89               action->getStartTime(), min, share, action->getMaxDuration());
90
91     if (min > -1) {
92       action->heapUpdate(actionHeap_, min, max_dur_flag ? Action::Type::MAX_DURATION : Action::Type::NORMAL);
93       XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min, now);
94     } else
95       DIE_IMPOSSIBLE;
96   }
97
98   // hereafter must have already the min value for this resource model
99   if (not actionHeapIsEmpty()) {
100     double min = actionHeapTopDate() - now;
101     XBT_DEBUG("minimum with the HEAP %f", min);
102     return min;
103   } else {
104     XBT_DEBUG("The HEAP is empty, thus returning -1");
105     return -1;
106   }
107 }
108
109 double Model::nextOccuringEventFull(double /*now*/)
110 {
111   maxminSystem_->solve_fun(maxminSystem_);
112
113   double min = -1;
114
115   for (Action& action : *getRunningActionSet()) {
116     double value = action.getVariable()->get_value();
117     if (value > 0) {
118       if (action.getRemains() > 0)
119         value = action.getRemainsNoUpdate() / value;
120       else
121         value = 0.0;
122       if (min < 0 || value < min) {
123         min = value;
124         XBT_DEBUG("Updating min (value) with %p: %f", &action, min);
125       }
126     }
127     if ((action.getMaxDuration() >= 0) && (min < 0 || action.getMaxDuration() < min)) {
128       min = action.getMaxDuration();
129       XBT_DEBUG("Updating min (duration) with %p: %f", &action, min);
130     }
131   }
132   XBT_DEBUG("min value : %f", min);
133
134   return min;
135 }
136
137 void Model::updateActionsState(double now, double delta)
138 {
139   if (updateMechanism_ == UM_FULL)
140     updateActionsStateFull(now, delta);
141   else if (updateMechanism_ == UM_LAZY)
142     updateActionsStateLazy(now, delta);
143   else
144     xbt_die("Invalid cpu update mechanism!");
145 }
146
147 void Model::updateActionsStateLazy(double /*now*/, double /*delta*/)
148 {
149   THROW_UNIMPLEMENTED;
150 }
151
152 void Model::updateActionsStateFull(double /*now*/, double /*delta*/)
153 {
154   THROW_UNIMPLEMENTED;
155 }
156
157 } // namespace surf
158 } // namespace simgrid
159 } // namespace simgrid