boost :: object_pool в пользовательской куче памяти

Я хотел бы создать пул объектов, но я хочу, чтобы он выделял память только на определенный сегмент моей кучи памяти. Есть ли способ сделать это с помощью Boost?

0

Решение

Boost.Pool-х object_pool позволяет пользователю управлять памятью, используемой пулом, предоставляя UserAllocator. Согласно документации:

Объекты пула должны запрашивать блоки памяти из системы, которые затем разделяет пул на части для выделения пользователю. Указав UserAllocator Параметр шаблона для различных интерфейсов пула позволяет пользователям контролировать распределение этих блоков системной памяти.

Boost.Pool предоставляет только базовые распределители, которые используют new/delete а также malloc/free, Однако, если распределитель может быть записан для выделения в определенных сегментах бесплатного хранилища, то object_pool может быть настроен так же. Может возникнуть необходимость проверить, поддерживает ли компилятор и платформа ограничение выделения в бесплатном хранилище определенным сегментом.


Вот базовый пример, где я проигнорировал некоторые детали, чтобы сохранить пример простым, и показать, как тип может соответствовать требованиям для UserAllocator, В этом примере boost::object_pool будет использовать пользовательский распределитель, который использует предварительно выделенную статическую память.

#include <iostream>
#include <boost/array.hpp>
#include <boost/pool/object_pool.hpp>

namespace detail {

/// @brief Pre-allocated managed memory block.
template <std::size_t N>
class arena
{
public:

/// @brief Constructor.
arena()
: current_(&buffer_.front()), // Set current to start.
end_(current_ + N)          // End sentinel.
{
std::cout << "arena memory range: "<< static_cast<void*>(current_) << " - "<< static_cast<const void*>(end_) << std::endl;
}

/// @brief Attempt to allocate memory from pre-allocated block.
///
/// @param n Count of bytes to allocate.
///
/// @param Non-zero if allocation is succesfull.  Otherwise, zero.
char* allocate(std::size_t n)
{
// If there is no more memory, then return zero.
if ((current_ + n) > end_) return 0;

// Otherwise, return available memory and shift current.
std::cout << "arena allocating: "<< static_cast<void*>(current_) << std::endl;
char* ptr = current_;
current_ += n;
return ptr;
}

void deallocate(char* p, std::size_t n)
{
// ...
}

private:

/// @brief Block of memory used for allocations.
boost::array<char, N> buffer_;

/// @brief Pointer to current allocation.
char* current_;

//// @brief End pointer sentinel.
const char* end_;
};

} // namespace detail

/// @brief Allocator that meets Boost.Pool's UserAllocator Concepts.
///        This allocator will allocate memory from a pre-allocated
///        block of static memory.  Each instance of the template is
///        considered to be its own unique allocator, and thus has its
///        own memory.
template <std::size_t N>
class static_allocator
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;

static char* malloc(const size_type n) { return arena_.allocate(n); }
static void free(char* p)              { arena_.deallocate(p, 1);   }

private:
static detail::arena<N> arena_;
};

template <std::size_t N>
detail::arena<N> static_allocator<N>::arena_;

/// @brief Helper type.
template <typename T, std::size_t N>
struct static_object_pool:
boost::object_pool<T, static_allocator<N * sizeof(T)> >
{};

/// Mockup object.
class Foo {};

int main()
{
static_object_pool<Foo, 128> pool;

Foo* a = pool.malloc();
std::cout << "a is at " << a << std::endl;
Foo* b = pool.malloc();
std::cout << "b is at " << b << " -- freeing b" << std::endl;
pool.free(b);
Foo* c = pool.malloc();
std::cout << "c is at " << c << std::endl;
}

И вывод:

arena memory range: 0x804b5a0 - 0x804b620
arena allocating: 0x804b5a0
a is at 0x804b5a0
b is at 0x804b5a4 -- freeing b
c is at 0x804b5a4

Обратите внимание, что каждый адрес возвращается из object_pool::malloc() находится в пределах памяти арены. Кроме того, когда b был освобожден через pool.free(b), память (0x804b5a4) был немедленно повторно использован бассейном при следующем malloc() за c,

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]