alloc: return views rather than raw pointers
This commit is contained in:
parent
df3a556867
commit
2620e2ed33
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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>) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 (
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user