1 // Copyright (C) 2020 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "DefaultAlgorithm.hxx"
24 namespace WorkloadManager
26 void DefaultAlgorithm::addTask(Task* t)
28 // put the tasks which need more cores in front.
29 float newNeedCores = t->type()->neededCores;
30 if(_waitingTasks.empty())
31 _waitingTasks.push_back(t);
32 else if(_waitingTasks.back()->type()->neededCores >= newNeedCores)
33 _waitingTasks.push_back(t);
36 std::list<Task*>::iterator it = _waitingTasks.begin();
37 while(it != _waitingTasks.end() && (*it)->type()->neededCores >= newNeedCores)
39 _waitingTasks.insert(it, t);
43 bool DefaultAlgorithm::empty()const
45 return _waitingTasks.empty();
48 void DefaultAlgorithm::addResource(Resource* r)
50 // add the resource. The operation is ignored if the resource already exists.
51 _resources.emplace(std::piecewise_construct,
52 std::forward_as_tuple(r),
53 std::forward_as_tuple(r)
57 WorkloadAlgorithm::LaunchInfo DefaultAlgorithm::chooseTask()
60 std::list<Task*>::iterator chosenTaskIt;
61 for( std::list<Task*>::iterator itTask = _waitingTasks.begin();
62 !result.taskFound && itTask != _waitingTasks.end();
65 const ContainerType* ctype = (*itTask)->type();
66 std::map<const Resource *, ResourceLoadInfo>::iterator best_resource;
67 best_resource = _resources.end();
68 float best_cost = std::numeric_limits<float>::max();
69 for(auto itResource = _resources.begin();
70 itResource != _resources.end();
72 if(itResource->second.isSupported(ctype))
74 if(itResource->second.isAllocPossible(ctype))
76 float thisCost = itResource->second.cost(ctype);
77 if( best_cost > thisCost)
80 best_resource = itResource;
84 if(best_resource != _resources.end())
86 chosenTaskIt = itTask;
87 result.task = (*itTask);
88 result.taskFound = true;
89 result.worker.resource = best_resource->first;
90 result.worker.type = ctype;
91 result.worker.index = best_resource->second.alloc(ctype);
95 _waitingTasks.erase(chosenTaskIt);
99 void DefaultAlgorithm::liberate(const LaunchInfo& info)
101 const Resource* r = info.worker.resource;
102 unsigned int index = info.worker.index;
103 const ContainerType* ctype = info.worker.type;
104 std::map<const Resource* ,ResourceLoadInfo>::iterator it = _resources.find(r);
105 it->second.free(ctype, index);
108 // ResourceInfoForContainer
110 DefaultAlgorithm::ResourceInfoForContainer::ResourceInfoForContainer
111 (const Resource * r, const ContainerType* ctype)
114 , _runningContainers()
115 , _firstFreeContainer(0)
119 unsigned int DefaultAlgorithm::ResourceInfoForContainer::maxContainers()const
121 return float(_resource->nbCores) / _ctype->neededCores;
124 unsigned int DefaultAlgorithm::ResourceInfoForContainer::alloc()
126 unsigned int result = _firstFreeContainer;
127 _runningContainers.insert(result);
128 _firstFreeContainer++;
129 while(isContainerRunning(_firstFreeContainer))
130 _firstFreeContainer++;
134 void DefaultAlgorithm::ResourceInfoForContainer::free(unsigned int index)
136 _runningContainers.erase(index);
137 if(index < _firstFreeContainer)
138 _firstFreeContainer = index;
141 unsigned int DefaultAlgorithm::ResourceInfoForContainer::nbRunningContainers()const
143 return _runningContainers.size();
146 bool DefaultAlgorithm::ResourceInfoForContainer::isContainerRunning
147 (unsigned int index)const
149 return _runningContainers.find(index)!=_runningContainers.end();
154 DefaultAlgorithm::ResourceLoadInfo::ResourceLoadInfo(const Resource * r)
161 bool DefaultAlgorithm::ResourceLoadInfo::isSupported
162 (const ContainerType* ctype)const
164 return ctype->neededCores <= _resource->nbCores ;
167 bool DefaultAlgorithm::ResourceLoadInfo::isAllocPossible
168 (const ContainerType* ctype)const
170 return ctype->neededCores + _load <= _resource->nbCores;
173 float DefaultAlgorithm::ResourceLoadInfo::cost
174 (const ContainerType* ctype)const
176 return _load * 100.0 / float(_resource->nbCores);
179 unsigned int DefaultAlgorithm::ResourceLoadInfo::alloc
180 (const ContainerType* ctype)
182 std::map<const ContainerType*, ResourceInfoForContainer>::iterator it;
183 it = _ctypes.find(ctype);
184 if(it == _ctypes.end())
186 // add the type if not found
187 it = _ctypes.emplace(std::piecewise_construct,
188 std::forward_as_tuple(ctype),
189 std::forward_as_tuple(_resource, ctype)
192 _load += ctype->neededCores;
193 return it->second.alloc();
196 void DefaultAlgorithm::ResourceLoadInfo::free
197 (const ContainerType* ctype, int index)
199 _load -= ctype->neededCores;
200 std::map<const ContainerType*, ResourceInfoForContainer>::iterator it;
201 it = _ctypes.find(ctype);
202 it->second.free(index);