Logo AND Algorithmique Numérique Distribuée

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