Commit adad3400 authored by Samuel Debionne's avatar Samuel Debionne

Use priority_queue instead of multimap

parent ae30a4bb
Pipeline #8668 passed with stages
in 6 minutes and 23 seconds
......@@ -57,8 +57,8 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(PROCESSLIB_MASTER_PROJECT ON)
endif()
# Enable C++11 and later
set(CMAKE_CXX_STANDARD 11)
# Enable C++14
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(MSVC AND MSVC_VERSION GREATER 1500)
......
......@@ -30,6 +30,7 @@
#pragma warning(disable : 4251)
#endif
#include <algorithm>
#include <condition_variable>
#include <map>
#include <mutex>
......@@ -42,11 +43,44 @@
class TaskMgr;
struct Data;
class PROCESSLIB_EXPORT PoolThreadMgr
namespace detail {
// Add a remove method to std::priority_queue
template <typename T, typename Container = std::vector<T>, typename Compare = std::less<typename Container::value_type>>
class priority_queue : public std::priority_queue<T, Container, Compare>
{
public:
typedef std::pair<int, int> TaskPriority;
bool remove(const T &value)
{
auto it = std::find(this->c.cbegin(), this->c.cend(), value);
if (it != this->c.cend())
{
this->c.erase(it);
std::make_heap(this->c.begin(), this->c.end(), this->comp);
return true;
} else
return false;
}
auto begin() noexcept { return this->c.begin(); }
auto end() noexcept { return this->c.end(); }
void clear() noexcept { return this->c.clear(); }
};
} // namespace detail
/// Task priority is set with two levels (first = major and second = minor)
using TaskPriority = std::pair<int, int>;
inline bool operator<(const TaskPriority &a, const TaskPriority &b)
{
if (a.first == b.first)
return b.second < a.second;
else
return b.first < a.first;
}
class PROCESSLIB_EXPORT PoolThreadMgr
{
public:
static PoolThreadMgr &get();
void addProcess(TaskMgr *aProcess, bool lock = true);
......@@ -67,17 +101,17 @@ class PROCESSLIB_EXPORT PoolThreadMgr
PoolThreadMgr(const PoolThreadMgr&)= delete;
PoolThreadMgr& operator=(const PoolThreadMgr&)= delete;
struct cmp
/// Compare two Process by priority
struct less_than
{
bool operator()(const TaskPriority &a, const TaskPriority &b)
template <typename Process>
bool operator()(Process const *const lhs, Process const *const rhs) const
{
if (a.first == b.first)
return b.second < a.second;
else
return b.first < a.first;
return lhs->priority() < rhs->priority();
}
};
typedef std::multimap<TaskPriority, TaskMgr *, cmp> QueueType;
using QueueType = detail::priority_queue<TaskMgr *, std::vector<TaskMgr *>, less_than>;
std::mutex m_mutex;
std::condition_variable m_cond;
......
......@@ -41,7 +41,7 @@ std::once_flag PoolThreadMgr::init_flag;
void PoolThreadMgr::addProcess(TaskMgr *aProcess, bool aFlag)
{
std::lock_guard<std::mutex> lock(m_mutex);
_processQueue.insert(QueueType::value_type(aProcess->priority(), aProcess));
_processQueue.push(aProcess);
aProcess->_pool = this;
m_cond.notify_all();
}
......@@ -49,14 +49,7 @@ void PoolThreadMgr::addProcess(TaskMgr *aProcess, bool aFlag)
void PoolThreadMgr::removeProcess(TaskMgr *aProcess, bool aFlag)
{
std::lock_guard<std::mutex> lock(m_mutex);
for (QueueType::iterator i = _processQueue.begin(); i != _processQueue.end(); ++i)
{
if (i->second == aProcess)
{
_processQueue.erase(i);
break;
}
}
_processQueue.remove(aProcess);
}
/** @brief change the number of thread in the pool
......@@ -115,8 +108,9 @@ void PoolThreadMgr::abort()
m_cond.wait(lock, [&] { return _runningThread; });
for (QueueType::iterator i = _processQueue.begin(); i != _processQueue.end(); ++i)
delete i->second;
for (auto &&proc : _processQueue)
delete proc;
_processQueue.clear();
_suspendFlag = false;
}
......@@ -164,8 +158,7 @@ void *PoolThreadMgr::_run(void *arg)
if (!that->_processQueue.empty())
{
QueueType::iterator i = that->_processQueue.begin();
TaskMgr *processPt = i->second;
TaskMgr *processPt = that->_processQueue.top();
TaskMgr::TaskWrap *aNextTask = processPt->next();
// aLock.unLock();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment