alloc: return views rather than raw pointers

This commit is contained in:
Danny Robson 2018-05-10 12:50:37 +10:00
parent df3a556867
commit 2620e2ed33
16 changed files with 62 additions and 42 deletions

View File

@ -38,8 +38,8 @@ namespace util::alloc {
U*
acquire (Args&&... args)
{
U *data = reinterpret_cast<U*> (
m_store.allocate (sizeof (U), alignof (U))
U *data = util::cast::alignment<U*> (
m_store.allocate (sizeof (U), alignof (U)).data ()
);
try {

View File

@ -17,6 +17,8 @@
#ifndef CRUFT_UTIL_ALLOC_RAW_AFFIX_HPP
#define CRUFT_UTIL_ALLOC_RAW_AFFIX_HPP
#include "../../view.hpp"
#include <cstddef>
namespace util::alloc::raw {
@ -29,11 +31,13 @@ namespace util::alloc::raw {
/// useful for sentinels, reference counts, etc.
template <class ParentT, class PrefixT, class SuffixT>
class affix {
void* allocate (size_t bytes);
void* allocate (size_t bytes, size_t align);
util::view<std::byte*> allocate (size_t bytes);
util::view<std::byte*> allocate (size_t bytes, size_t align);
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t align);
void deallocate (util::view<std::byte*> ptr) { return deallocate (ptr.data (), ptr.size ()); }
void deallocate (util::view<std::byte*> ptr, size_t alignment) { return deallocate (ptr.data (), ptr.size (), alignment); }
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t align);
std::byte* begin (void);
const std::byte* begin (void) const;

View File

@ -18,6 +18,7 @@
#define CRUFT_UTIL_ALLOC_RAW_ALIGNED_DIRECT_HPP
#include "../../../debug.hpp"
#include "../../../view.hpp"
#include <cstddef>
#include <utility>

View File

@ -70,7 +70,7 @@ namespace util::alloc::raw::aligned {
allocate (std::size_t size)
{
auto ptr= reinterpret_cast<std::byte*> (
m_successor.allocate (size)
m_successor.allocate (size).data ()
);
return ptr + m_offset;
}

View File

@ -98,8 +98,8 @@ namespace util::alloc::raw {
virtual ~interface () { ; }
// allocation management
virtual void* allocate (size_t bytes) = 0;
virtual void* allocate (size_t bytes, size_t alignment) = 0;
virtual util::view<std::byte*> allocate (size_t bytes) = 0;
virtual util::view<std::byte*> allocate (size_t bytes, size_t alignment) = 0;
virtual void deallocate (void *ptr, size_t bytes) = 0;
virtual void deallocate (void *ptr, size_t bytes, size_t alignment) = 0;
@ -132,7 +132,7 @@ namespace util::alloc::raw {
{ ; }
// allocation management
void*
util::view<std::byte*>
allocate (size_t bytes) override
{ return m_target.allocate (bytes); }
@ -140,7 +140,7 @@ namespace util::alloc::raw {
// we can't totally eliminate this call given the point is to
// expose the common API area, but we will throw if the operation
// is unsupported in the child.
void*
util::view<std::byte*>
allocate (size_t bytes, size_t alignment) override
{
if constexpr (has_aligned_allocate_v<ChildT>) {

View File

@ -17,6 +17,8 @@
#ifndef CRUFT_UTIL_ALLOC_RAW_FALLBACK_HPP
#define CRUFT_UTIL_ALLOC_RAW_FALLBACK_HPP
#include "../../view.hpp"
#include <cstddef>
#include <tuple>
@ -30,9 +32,11 @@ namespace util::alloc::raw {
m_children (_children...)
{ ; }
void* allocate (size_t bytes);
void* allocate (size_t bytes, size_t align);
util::view<std::byte*> allocate (size_t bytes);
util::view<std::byte*> allocate (size_t bytes, size_t align);
void deallocate (util::view<std::byte*> ptr) { return deallocate (ptr.data (), ptr.size ()); }
void deallocate (util::view<std::byte*> ptr, size_t alignment) { return deallocate (ptr.data (), ptr.size (), alignment); }
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t align);

View File

@ -31,7 +31,7 @@ linear::linear (util::view<std::byte*> _data):
///////////////////////////////////////////////////////////////////////////////
void*
util::view<std::byte*>
linear::allocate (size_t bytes)
{
if (m_cursor + bytes > m_end)
@ -39,12 +39,12 @@ linear::allocate (size_t bytes)
auto ptr = m_cursor;
m_cursor += bytes;
return ptr;
return { ptr, bytes };
}
//-----------------------------------------------------------------------------
void*
util::view<std::byte*>
linear::allocate (size_t bytes, size_t alignment)
{
auto ptr = align (m_cursor, alignment);
@ -53,7 +53,7 @@ linear::allocate (size_t bytes, size_t alignment)
m_cursor = ptr + bytes;
return ptr;
return { ptr, bytes };
}

View File

@ -34,11 +34,13 @@ namespace util::alloc::raw {
linear (util::view<std::byte*> _data);
void* allocate (size_t bytes);
void* allocate (size_t bytes, size_t alignment);
util::view<std::byte*> allocate (size_t bytes);
util::view<std::byte*> allocate (size_t bytes, size_t alignment);
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t alignment);
void deallocate (util::view<std::byte*> ptr) { return deallocate (ptr.data (), ptr.size ()); }
void deallocate (util::view<std::byte*> ptr, size_t alignment) { return deallocate (ptr.data (), ptr.size (), alignment); }
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t alignment);
std::byte* data (void);
std::byte* begin (void);

View File

@ -24,7 +24,7 @@ using util::alloc::raw::malloc;
///////////////////////////////////////////////////////////////////////////////
void*
util::view<std::byte*>
malloc::allocate (size_t bytes)
{
return allocate (bytes, alignof (std::max_align_t));
@ -32,14 +32,14 @@ malloc::allocate (size_t bytes)
//-----------------------------------------------------------------------------
void*
util::view<std::byte*>
malloc::allocate (size_t bytes, size_t align)
{
// C malloc guarantees maximal alignment
CHECK_LE (align, alignof (std::max_align_t));
(void)align;
return ::malloc (bytes);
return util::view<std::byte*> (reinterpret_cast<std::byte*> (::malloc (bytes)), bytes);
}

View File

@ -17,17 +17,21 @@
#ifndef CRUFT_UTIL_ALLOC_RAW_MALLOC_HPP
#define CRUFT_UTIL_ALLOC_RAW_MALLOC_HPP
#include "../../view.hpp"
#include <cstddef>
namespace util::alloc::raw {
class malloc {
public:
void* allocate (size_t bytes);
void* allocate (size_t bytes, size_t align);
util::view<std::byte*> allocate (size_t bytes);
util::view<std::byte*> allocate (size_t bytes, size_t align);
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t align);
void deallocate (util::view<std::byte*> ptr) { return deallocate (ptr.data (), ptr.size ()); }
void deallocate (util::view<std::byte*> ptr, size_t alignment) { return deallocate (ptr.data (), ptr.size (), alignment); }
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t align);
};
}

View File

@ -25,7 +25,7 @@ using util::alloc::raw::null;
///////////////////////////////////////////////////////////////////////////////
void*
util::view<std::byte*>
null::allocate (size_t bytes)
{
return allocate (bytes, alignof (std::max_align_t));
@ -33,7 +33,7 @@ null::allocate (size_t bytes)
//-----------------------------------------------------------------------------
void*
util::view<std::byte*>
null::allocate (size_t bytes, size_t align)
{
(void)bytes;

View File

@ -32,8 +32,11 @@ namespace util::alloc::raw {
null (const null&) = delete;
null& operator= (const null&) = delete;
void* allocate (size_t bytes);
void* allocate (size_t bytes, size_t align);
util::view<std::byte*> allocate (size_t bytes);
util::view<std::byte*> allocate (size_t bytes, size_t align);
void deallocate (util::view<std::byte*> ptr) { return deallocate (ptr.data (), ptr.size ()); }
void deallocate (util::view<std::byte*> ptr, size_t alignment) { return deallocate (ptr.data (), ptr.size (), alignment); }
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t align);

View File

@ -47,7 +47,7 @@ constexpr auto MIN_ALIGNMENT = sizeof (record::offset_t);
///////////////////////////////////////////////////////////////////////////////
void*
util::view<std::byte*>
stack::allocate (size_t bytes)
{
return allocate (bytes, alignof (std::max_align_t));
@ -55,7 +55,7 @@ stack::allocate (size_t bytes)
//-----------------------------------------------------------------------------
void*
util::view<std::byte*>
stack::allocate (size_t bytes, size_t alignment)
{
// reserve space at the front of the allocation to record the total
@ -78,7 +78,7 @@ stack::allocate (size_t bytes, size_t alignment)
*record.as_offset = util::cast::lossless <uint32_t> (ptr - m_cursor);
m_cursor = ptr + bytes;
return ptr;
return { ptr, bytes };
}

View File

@ -34,9 +34,11 @@ namespace util::alloc::raw {
stack (util::view<std::byte*> _data);
void *allocate (size_t bytes, size_t alignment);
void *allocate (size_t bytes);
util::view<std::byte*> allocate (size_t bytes, size_t alignment);
util::view<std::byte*> allocate (size_t bytes);
void deallocate (util::view<std::byte*> ptr) { return deallocate (ptr.data (), ptr.size ()); }
void deallocate (util::view<std::byte*> ptr, size_t alignment) { return deallocate (ptr.data (), ptr.size (), alignment); }
void deallocate (void *ptr, size_t bytes);
void deallocate (void *ptr, size_t bytes, size_t alignment);

View File

@ -29,10 +29,10 @@ main (int, char**)
// alignment to produce a likely system alignment. eg, 3 + 5 == 8 which is
// a power-of-2.
uintptr_t result[4] = {
reinterpret_cast<uintptr_t>(alloc.allocate (9)), // just over a power of two
reinterpret_cast<uintptr_t>(alloc.allocate (1)), // a single byte
reinterpret_cast<uintptr_t>(alloc.allocate (64)), // a cache line
reinterpret_cast<uintptr_t>(alloc.allocate (250)) // multiple cache lines, but not a power of two
reinterpret_cast<uintptr_t>(alloc.allocate (9).data ()), // just over a power of two
reinterpret_cast<uintptr_t>(alloc.allocate (1).data ()), // a single byte
reinterpret_cast<uintptr_t>(alloc.allocate (64).data ()), // a cache line
reinterpret_cast<uintptr_t>(alloc.allocate (250).data ()) // multiple cache lines, but not a power of two
};
tap.expect (

View File

@ -11,7 +11,7 @@ n_allocations (util::alloc::raw::stack &store,
{
for (unsigned i = 0; i < count; ++i) {
auto ptr = store.allocate (bytes, alignment);
store.deallocate (ptr, bytes, alignment);
store.deallocate (ptr, alignment);
}
}