blob: 363b4590b3df5302b6a19ade04b5d1ff406fbe88 [file] [log] [blame]
//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//
#include "IMemoryPool.hpp"
#include "PoolManager.hpp"
#include <boost/assert.hpp>
#include <boost/polymorphic_cast.hpp>
#include <algorithm>
namespace armnn
{
PoolManager::PoolManager()
: m_FreePools()
, m_OccupiedPools()
, m_Semaphore()
, m_Mutex()
{}
arm_compute::IMemoryPool *PoolManager::lock_pool()
{
BOOST_ASSERT_MSG(!(m_FreePools.empty() && m_OccupiedPools.empty()), "Haven't setup any pools");
m_Semaphore->wait();
std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
BOOST_ASSERT_MSG(!m_FreePools.empty(), "Empty pool must exist as semaphore has been signalled");
m_OccupiedPools.splice(std::begin(m_OccupiedPools), m_FreePools, std::begin(m_FreePools));
return m_OccupiedPools.front().get();
}
void PoolManager::unlock_pool(arm_compute::IMemoryPool *pool)
{
BOOST_ASSERT_MSG(!(m_FreePools.empty() && m_OccupiedPools.empty()), "Haven't setup any pools!");
std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
auto it = std::find_if(
std::begin(m_OccupiedPools),
std::end(m_OccupiedPools),
[pool](const std::unique_ptr<arm_compute::IMemoryPool> &poolIterator)
{
return poolIterator.get() == pool;
}
);
BOOST_ASSERT_MSG(it != std::end(m_OccupiedPools), "Pool to be unlocked couldn't be found");
m_FreePools.splice(std::begin(m_FreePools), m_OccupiedPools, it);
m_Semaphore->signal();
}
void PoolManager::register_pool(std::unique_ptr<arm_compute::IMemoryPool> pool)
{
std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
BOOST_ASSERT_MSG(m_OccupiedPools.empty(), "All pools should be free in order to register a new one");
// Set pool
m_FreePools.push_front(std::move(pool));
// Update semaphore
m_Semaphore = std::make_unique<arm_compute::Semaphore>(m_FreePools.size());
}
size_t PoolManager::num_pools() const
{
std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
return m_FreePools.size() + m_OccupiedPools.size();
}
void PoolManager::AllocatePools()
{
std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
for (auto& pool : m_FreePools)
{
boost::polymorphic_downcast<IMemoryPool*>(pool.get())->AllocatePool();
}
for (auto& pool : m_OccupiedPools)
{
boost::polymorphic_downcast<IMemoryPool*>(pool.get())->AllocatePool();
}
}
void PoolManager::ReleasePools()
{
std::lock_guard<arm_compute::Mutex> lock(m_Mutex);
for (auto& pool : m_FreePools)
{
boost::polymorphic_downcast<IMemoryPool*>(pool.get())->ReleasePool();
}
for (auto& pool : m_OccupiedPools)
{
boost::polymorphic_downcast<IMemoryPool*>(pool.get())->ReleasePool();
}
}
} //namespace armnn