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"
25 namespace WorkloadManager
27 void DefaultAlgorithm::addTask(Task* t)
29 // put the tasks which need more cores in front.
30 float newNeedCores = t->type().neededCores;
31 if(_waitingTasks.empty())
32 _waitingTasks.push_back(t);
33 else if(_waitingTasks.back()->type().neededCores >= newNeedCores)
34 _waitingTasks.push_back(t);
37 std::list<Task*>::iterator it = _waitingTasks.begin();
38 while(it != _waitingTasks.end() && (*it)->type().neededCores >= newNeedCores)
40 _waitingTasks.insert(it, t);
44 bool DefaultAlgorithm::empty()const
46 return _waitingTasks.empty();
49 void DefaultAlgorithm::addResource(const Resource& r)
51 _resources.emplace_back(r);
54 WorkloadAlgorithm::LaunchInfo DefaultAlgorithm::chooseTask()
57 std::list<Task*>::iterator chosenTaskIt;
58 for( std::list<Task*>::iterator itTask = _waitingTasks.begin();
59 !result.taskFound && itTask != _waitingTasks.end();
62 const ContainerType& ctype = (*itTask)->type();
63 std::list<ResourceLoadInfo>::iterator best_resource;
64 best_resource = _resources.end();
65 float best_cost = std::numeric_limits<float>::max();
66 bool isSupported = false;
67 for(auto itResource = _resources.begin();
68 itResource != _resources.end();
70 if(itResource->isSupported(ctype))
72 if(itResource->isAllocPossible(ctype))
74 float thisCost = itResource->cost(ctype);
75 if( best_cost > thisCost)
78 best_resource = itResource;
82 if(best_resource != _resources.end())
84 chosenTaskIt = itTask;
85 result.task = (*itTask);
86 result.taskFound = true;
87 result.worker.resource = best_resource->resource();
88 result.worker.type = ctype;
89 result.worker.index = best_resource->alloc(ctype);
93 // TODO: This task can never be run by any available resource.
97 _waitingTasks.erase(chosenTaskIt);
101 void DefaultAlgorithm::liberate(const LaunchInfo& info)
103 const Resource& r = info.worker.resource;
104 unsigned int index = info.worker.index;
105 const ContainerType& ctype = info.worker.type;
106 std::list<ResourceLoadInfo>::iterator it = std::find(_resources.begin(),
109 it->free(ctype, index); // we are sure to find it
112 // ResourceInfoForContainer
114 DefaultAlgorithm::ResourceInfoForContainer::ResourceInfoForContainer
115 (const Resource& r, const ContainerType& ctype)
118 , _runningContainers()
119 , _firstFreeContainer(0)
123 unsigned int DefaultAlgorithm::ResourceInfoForContainer::maxContainers()const
125 return float(_resource.nbCores) / _ctype.neededCores;
128 unsigned int DefaultAlgorithm::ResourceInfoForContainer::alloc()
130 unsigned int result = _firstFreeContainer;
131 _runningContainers.insert(result);
132 _firstFreeContainer++;
133 while(isContainerRunning(_firstFreeContainer))
134 _firstFreeContainer++;
138 void DefaultAlgorithm::ResourceInfoForContainer::free(unsigned int index)
140 _runningContainers.erase(index);
141 if(index < _firstFreeContainer)
142 _firstFreeContainer = index;
145 unsigned int DefaultAlgorithm::ResourceInfoForContainer::nbRunningContainers()const
147 return _runningContainers.size();
150 bool DefaultAlgorithm::ResourceInfoForContainer::isContainerRunning
151 (unsigned int index)const
153 return _runningContainers.find(index)!=_runningContainers.end();
158 DefaultAlgorithm::ResourceLoadInfo::ResourceLoadInfo(const Resource& r)
165 bool DefaultAlgorithm::ResourceLoadInfo::isSupported
166 (const ContainerType& ctype)const
168 return ctype.neededCores <= _resource.nbCores ;
171 bool DefaultAlgorithm::ResourceLoadInfo::isAllocPossible
172 (const ContainerType& ctype)const
174 return ctype.neededCores + _load <= _resource.nbCores;
177 float DefaultAlgorithm::ResourceLoadInfo::cost
178 (const ContainerType& ctype)const
180 return _load * 100.0 / float(_resource.nbCores);
183 unsigned int DefaultAlgorithm::ResourceLoadInfo::alloc
184 (const ContainerType& ctype)
186 std::list<ResourceInfoForContainer>::iterator it = std::find(_ctypes.begin(),
189 // add the type if not found
190 if(it == _ctypes.end())
192 _ctypes.emplace_back(_resource, ctype);
196 _load += ctype.neededCores;
200 void DefaultAlgorithm::ResourceLoadInfo::free
201 (const ContainerType& ctype, int index)
203 _load -= ctype.neededCores;
204 std::list<ResourceInfoForContainer>::iterator it = std::find(_ctypes.begin(),