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 if(ctype.ignoreResources)
64 result.taskFound = true;
67 std::list<ResourceLoadInfo>::iterator best_resource;
68 best_resource = _resources.end();
69 float best_cost = std::numeric_limits<float>::max();
70 bool isSupported = false;
71 for(auto itResource = _resources.begin();
72 itResource != _resources.end();
74 if(itResource->isSupported(ctype)
75 && (*itTask)->isAccepted(itResource->resource()))
77 if(itResource->isAllocPossible(ctype))
79 float thisCost = itResource->cost(ctype);
80 if( best_cost > thisCost)
83 best_resource = itResource;
87 if(best_resource != _resources.end())
89 result.taskFound = true;
90 result.worker.resource = best_resource->resource();
91 result.worker.index = best_resource->alloc(ctype);
95 // TODO: This task can never be run by any available resource.
100 chosenTaskIt = itTask;
101 result.task = (*itTask);
102 result.worker.type = ctype;
106 _waitingTasks.erase(chosenTaskIt);
110 void DefaultAlgorithm::liberate(const LaunchInfo& info)
112 const ContainerType& ctype = info.worker.type;
113 if(!ctype.ignoreResources)
115 const Resource& r = info.worker.resource;
116 unsigned int index = info.worker.index;
117 std::list<ResourceLoadInfo>::iterator it = std::find(_resources.begin(),
120 it->free(ctype, index); // we are sure to find it
124 // ResourceInfoForContainer
126 DefaultAlgorithm::ResourceInfoForContainer::ResourceInfoForContainer
127 (const Resource& r, const ContainerType& ctype)
130 , _runningContainers()
131 , _firstFreeContainer(0)
135 unsigned int DefaultAlgorithm::ResourceInfoForContainer::maxContainers()const
137 return float(_resource.nbCores) / _ctype.neededCores;
140 unsigned int DefaultAlgorithm::ResourceInfoForContainer::alloc()
142 unsigned int result = _firstFreeContainer;
143 _runningContainers.insert(result);
144 _firstFreeContainer++;
145 while(isContainerRunning(_firstFreeContainer))
146 _firstFreeContainer++;
150 void DefaultAlgorithm::ResourceInfoForContainer::free(unsigned int index)
152 _runningContainers.erase(index);
153 if(index < _firstFreeContainer)
154 _firstFreeContainer = index;
157 unsigned int DefaultAlgorithm::ResourceInfoForContainer::nbRunningContainers()const
159 return _runningContainers.size();
162 bool DefaultAlgorithm::ResourceInfoForContainer::isContainerRunning
163 (unsigned int index)const
165 return _runningContainers.find(index)!=_runningContainers.end();
170 DefaultAlgorithm::ResourceLoadInfo::ResourceLoadInfo(const Resource& r)
178 bool DefaultAlgorithm::ResourceLoadInfo::isSupported
179 (const ContainerType& ctype)const
181 return ctype.neededCores <= _resource.nbCores ;
184 bool DefaultAlgorithm::ResourceLoadInfo::isAllocPossible
185 (const ContainerType& ctype)const
187 return ctype.neededCores + _load <= _resource.nbCores;
190 float DefaultAlgorithm::ResourceLoadInfo::cost
191 (const ContainerType& ctype)const
193 return _loadCost * 100.0 / float(_resource.nbCores);
196 unsigned int DefaultAlgorithm::ResourceLoadInfo::alloc
197 (const ContainerType& ctype)
199 std::list<ResourceInfoForContainer>::iterator it = std::find(_ctypes.begin(),
202 // add the type if not found
203 if(it == _ctypes.end())
205 _ctypes.emplace_back(_resource, ctype);
209 _load += ctype.neededCores;
210 if(ctype.neededCores == 0)
211 _loadCost += COST_FOR_0_CORE_TASKS;
213 _loadCost += ctype.neededCores;
217 void DefaultAlgorithm::ResourceLoadInfo::free
218 (const ContainerType& ctype, int index)
220 _load -= ctype.neededCores;
221 if(ctype.neededCores == 0)
222 _loadCost -= COST_FOR_0_CORE_TASKS;
224 _loadCost -= ctype.neededCores;
225 std::list<ResourceInfoForContainer>::iterator it = std::find(_ctypes.begin(),