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* U*
acquire (Args&&... args) acquire (Args&&... args)
{ {
U *data = reinterpret_cast<U*> ( U *data = util::cast::alignment<U*> (
m_store.allocate (sizeof (U), alignof (U)) m_store.allocate (sizeof (U), alignof (U)).data ()
); );
try { try {

View File

@ -17,6 +17,8 @@
#ifndef CRUFT_UTIL_ALLOC_RAW_AFFIX_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_AFFIX_HPP
#define CRUFT_UTIL_ALLOC_RAW_AFFIX_HPP #define CRUFT_UTIL_ALLOC_RAW_AFFIX_HPP
#include "../../view.hpp"
#include <cstddef> #include <cstddef>
namespace util::alloc::raw { namespace util::alloc::raw {
@ -29,9 +31,11 @@ namespace util::alloc::raw {
/// useful for sentinels, reference counts, etc. /// useful for sentinels, reference counts, etc.
template <class ParentT, class PrefixT, class SuffixT> template <class ParentT, class PrefixT, class SuffixT>
class affix { class affix {
void* allocate (size_t bytes); util::view<std::byte*> allocate (size_t bytes);
void* allocate (size_t bytes, size_t align); 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);
void deallocate (void *ptr, size_t bytes, size_t align); void deallocate (void *ptr, size_t bytes, size_t align);

View File

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

View File

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

View File

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

View File

@ -17,6 +17,8 @@
#ifndef CRUFT_UTIL_ALLOC_RAW_FALLBACK_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_FALLBACK_HPP
#define CRUFT_UTIL_ALLOC_RAW_FALLBACK_HPP #define CRUFT_UTIL_ALLOC_RAW_FALLBACK_HPP
#include "../../view.hpp"
#include <cstddef> #include <cstddef>
#include <tuple> #include <tuple>
@ -30,9 +32,11 @@ namespace util::alloc::raw {
m_children (_children...) m_children (_children...)
{ ; } { ; }
void* allocate (size_t bytes); util::view<std::byte*> allocate (size_t bytes);
void* allocate (size_t bytes, size_t align); 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);
void deallocate (void *ptr, size_t bytes, size_t align); 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) linear::allocate (size_t bytes)
{ {
if (m_cursor + bytes > m_end) if (m_cursor + bytes > m_end)
@ -39,12 +39,12 @@ linear::allocate (size_t bytes)
auto ptr = m_cursor; auto ptr = m_cursor;
m_cursor += bytes; m_cursor += bytes;
return ptr; return { ptr, bytes };
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void* util::view<std::byte*>
linear::allocate (size_t bytes, size_t alignment) linear::allocate (size_t bytes, size_t alignment)
{ {
auto ptr = align (m_cursor, alignment); auto ptr = align (m_cursor, alignment);
@ -53,7 +53,7 @@ linear::allocate (size_t bytes, size_t alignment)
m_cursor = ptr + bytes; m_cursor = ptr + bytes;
return ptr; return { ptr, bytes };
} }

View File

@ -34,9 +34,11 @@ namespace util::alloc::raw {
linear (util::view<std::byte*> _data); linear (util::view<std::byte*> _data);
void* allocate (size_t bytes); util::view<std::byte*> allocate (size_t bytes);
void* allocate (size_t bytes, size_t alignment); util::view<std::byte*> allocate (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);
void deallocate (void *ptr, size_t bytes, size_t alignment); void deallocate (void *ptr, size_t bytes, size_t alignment);

View File

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

View File

@ -17,15 +17,19 @@
#ifndef CRUFT_UTIL_ALLOC_RAW_MALLOC_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_MALLOC_HPP
#define CRUFT_UTIL_ALLOC_RAW_MALLOC_HPP #define CRUFT_UTIL_ALLOC_RAW_MALLOC_HPP
#include "../../view.hpp"
#include <cstddef> #include <cstddef>
namespace util::alloc::raw { namespace util::alloc::raw {
class malloc { class malloc {
public: public:
void* allocate (size_t bytes); util::view<std::byte*> allocate (size_t bytes);
void* allocate (size_t bytes, size_t align); 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);
void deallocate (void *ptr, size_t bytes, size_t align); 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) null::allocate (size_t bytes)
{ {
return allocate (bytes, alignof (std::max_align_t)); 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) null::allocate (size_t bytes, size_t align)
{ {
(void)bytes; (void)bytes;

View File

@ -32,8 +32,11 @@ namespace util::alloc::raw {
null (const null&) = delete; null (const null&) = delete;
null& operator= (const null&) = delete; null& operator= (const null&) = delete;
void* allocate (size_t bytes); util::view<std::byte*> allocate (size_t bytes);
void* allocate (size_t bytes, size_t align); 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);
void deallocate (void *ptr, size_t bytes, size_t align); 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) stack::allocate (size_t bytes)
{ {
return allocate (bytes, alignof (std::max_align_t)); 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) stack::allocate (size_t bytes, size_t alignment)
{ {
// reserve space at the front of the allocation to record the total // 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); *record.as_offset = util::cast::lossless <uint32_t> (ptr - m_cursor);
m_cursor = ptr + bytes; 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); stack (util::view<std::byte*> _data);
void *allocate (size_t bytes, size_t alignment); util::view<std::byte*> allocate (size_t bytes, size_t alignment);
void *allocate (size_t bytes); 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);
void deallocate (void *ptr, size_t bytes, size_t alignment); 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 // alignment to produce a likely system alignment. eg, 3 + 5 == 8 which is
// a power-of-2. // a power-of-2.
uintptr_t result[4] = { uintptr_t result[4] = {
reinterpret_cast<uintptr_t>(alloc.allocate (9)), // just over 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)), // a single byte reinterpret_cast<uintptr_t>(alloc.allocate (1).data ()), // a single byte
reinterpret_cast<uintptr_t>(alloc.allocate (64)), // a cache line reinterpret_cast<uintptr_t>(alloc.allocate (64).data ()), // 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 (250).data ()) // multiple cache lines, but not a power of two
}; };
tap.expect ( tap.expect (

View File

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