Logo AND Algorithmique Numérique Distribuée

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