Program Listing for File MixedPool.cpp¶
↰ Return to documentation for file (umpire/strategy/MixedPool.cpp
)
//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016-20, Lawrence Livermore National Security, LLC and Umpire
// project contributors. See the COPYRIGHT file for details.
//
// SPDX-License-Identifier: (MIT)
//////////////////////////////////////////////////////////////////////////////
#include "umpire/util/Macros.hpp"
#include "umpire/strategy/MixedPool.hpp"
#include "umpire/util/make_unique.hpp"
#include <cstdint>
#include <algorithm>
namespace umpire {
namespace strategy {
MixedPool::MixedPool(const std::string& name, int id,
Allocator allocator,
std::size_t smallest_fixed_obj_size,
std::size_t largest_fixed_obj_size,
std::size_t max_initial_fixed_pool_size,
std::size_t fixed_size_multiplier,
const std::size_t dynamic_initial_alloc_size,
const std::size_t dynamic_min_alloc_size,
const std::size_t dynamic_align_bytes,
DynamicPoolMap::CoalesceHeuristic dynamic_coalesce_heuristic) noexcept :
AllocationStrategy{name, id},
m_map{},
m_fixed_pool_map{},
m_fixed_pool{},
m_dynamic_pool{"internal_dynamic_pool", -1, allocator,
dynamic_initial_alloc_size,
dynamic_min_alloc_size,
dynamic_align_bytes,
dynamic_coalesce_heuristic},
m_allocator{allocator.getAllocationStrategy()}
{
std::size_t obj_size{smallest_fixed_obj_size};
while (obj_size <= largest_fixed_obj_size) {
const std::size_t obj_per_pool{
std::min(64 * sizeof(int) * 8, max_initial_fixed_pool_size / obj_size)};
if (obj_per_pool > 1) {
m_fixed_pool.emplace_back(util::make_unique<FixedPool>("internal_fixed_pool", -1, allocator, obj_size, obj_per_pool));
m_fixed_pool_map.emplace_back(obj_size);
} else {
break;
}
obj_size *= fixed_size_multiplier;
}
if (m_fixed_pool.size() == 0) {
UMPIRE_LOG(Debug, "Mixed Pool is reverting to a dynamic pool");
}
}
void* MixedPool::allocate(std::size_t bytes)
{
// Find pool index
int index = 0;
for (std::size_t i = 0; i < m_fixed_pool_map.size(); ++i) {
if (bytes > m_fixed_pool_map[index]) { index++; }
else { break; }
}
void* mem;
if (static_cast<std::size_t>(index) < m_fixed_pool.size()) {
// allocate in fixed pool
mem = m_fixed_pool[index]->allocate();
m_map[reinterpret_cast<uintptr_t>(mem)] = index;
}
else {
// allocate in dynamic pool
mem = m_dynamic_pool.allocate(bytes);
m_map[reinterpret_cast<uintptr_t>(mem)] = -1;
}
return mem;
}
void MixedPool::deallocate(void* ptr)
{
auto iter = m_map.find(reinterpret_cast<uintptr_t>(ptr));
if (iter != m_map.end()) {
const int index = iter->second;
if (index < 0) {
m_dynamic_pool.deallocate(ptr);
}
else {
m_fixed_pool[index]->deallocate(ptr);
}
}
}
void MixedPool::release()
{
UMPIRE_LOG(Debug, "MixedPool::release(): Not yet implemented");
}
std::size_t MixedPool::getCurrentSize() const noexcept
{
std::size_t size = 0;
for (auto& fp : m_fixed_pool) size += fp->getCurrentSize();
size += m_dynamic_pool.getCurrentSize();
return size;
}
std::size_t MixedPool::getActualSize() const noexcept
{
std::size_t size = 0;
for (auto& fp : m_fixed_pool) size += fp->getActualSize();
size += m_dynamic_pool.getActualSize();
return size;
}
std::size_t MixedPool::getHighWatermark() const noexcept
{
std::size_t size = 0;
for (auto& fp : m_fixed_pool) size += fp->getHighWatermark();
size += m_dynamic_pool.getHighWatermark();
return size;
}
Platform MixedPool::getPlatform() noexcept
{
return m_allocator->getPlatform();
}
}
}