alloc: seperate out the raw allocators from the adapters

This commit is contained in:
Danny Robson 2017-08-29 16:53:11 +10:00
parent 417175b2dd
commit 9d5e599246
23 changed files with 122 additions and 82 deletions

View File

@ -150,26 +150,26 @@ list (
algo/sort.hpp algo/sort.hpp
algo/sort.ipp algo/sort.ipp
alloc/fwd.hpp alloc/fwd.hpp
alloc/affix.cpp
alloc/affix.hpp
alloc/aligned.hpp
alloc/allocator.cpp alloc/allocator.cpp
alloc/allocator.hpp alloc/allocator.hpp
alloc/allocator.ipp alloc/allocator.ipp
alloc/arena.cpp alloc/arena.cpp
alloc/arena.hpp alloc/arena.hpp
alloc/arena.ipp alloc/arena.ipp
alloc/dynamic.hpp alloc/raw/affix.cpp
alloc/fallback.cpp alloc/raw/affix.hpp
alloc/fallback.hpp alloc/raw/aligned.hpp
alloc/linear.cpp alloc/raw/dynamic.hpp
alloc/linear.hpp alloc/raw/fallback.cpp
alloc/malloc.cpp alloc/raw/fallback.hpp
alloc/malloc.hpp alloc/raw/linear.cpp
alloc/null.cpp alloc/raw/linear.hpp
alloc/null.hpp alloc/raw/malloc.cpp
alloc/stack.cpp alloc/raw/malloc.hpp
alloc/stack.hpp alloc/raw/null.cpp
alloc/raw/null.hpp
alloc/raw/stack.cpp
alloc/raw/stack.hpp
annotation.hpp annotation.hpp
ascii.hpp ascii.hpp
backtrace.hpp backtrace.hpp

View File

@ -1 +0,0 @@
#include "./fallback.hpp"

View File

@ -19,17 +19,20 @@
namespace util::alloc { namespace util::alloc {
class affix; namespace raw {
class fallback; class affix;
class linear; class fallback;
class malloc; class linear;
class null; class malloc;
class stack; class null;
class stack;
class dynamic; class dynamic;
template <typename AllocT>
class aligned;
}
template <typename AllocT>
class aligned;
template <typename T> class arena; template <typename T> class arena;
template <typename B, typename T> class allocator; template <typename B, typename T> class allocator;

View File

@ -16,7 +16,8 @@
#include "./affix.hpp" #include "./affix.hpp"
using util::alloc::affix; using util::alloc::raw::affix;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -14,13 +14,20 @@
* Copyright 2015 Danny Robson <danny@nerdcruft.net> * Copyright 2015 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_ALLOC_AFFIX_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_AFFIX_HPP
#define __UTIL_ALLOC_AFFIX_HPP #define CRUFT_UTIL_ALLOC_RAW_AFFIX_HPP
#include <cstddef> #include <cstddef>
namespace util::alloc { namespace util::alloc::raw {
template <class parent, class prefix, class suffix> /// a raw memory allocator which initialises an instance of PrefixT
/// immediately before each allocation and, if specified, an instance
/// of SuffixT after the allocation.
///
/// uses an instance of ParentT to actually perform the bulk allocations.
///
/// useful for sentinels, reference counts, etc.
template <class ParentT, class PrefixT, class SuffixT>
class affix { class affix {
void* allocate (size_t bytes); void* allocate (size_t bytes);
void* allocate (size_t bytes, size_t align); void* allocate (size_t bytes, size_t align);

View File

@ -14,10 +14,10 @@
* Copyright 2016 Danny Robson <danny@nerdcruft.net> * Copyright 2016 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __CRUFT_UTIL_ALLOC_ALIGNED_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_ALIGNED_HPP
#define __CRUFT_UTIL_ALLOC_ALIGNED_HPP #define CRUFT_UTIL_ALLOC_RAW_ALIGNED_HPP
namespace util::alloc { namespace util::alloc::raw {
/// wraps a child allocator and enforces a fixed alignment /// wraps a child allocator and enforces a fixed alignment
template <typename ChildT> template <typename ChildT>
class aligned { class aligned {

View File

@ -14,13 +14,13 @@
* Copyright 2016 Danny Robson <danny@nerdcruft.net> * Copyright 2016 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_ALLOC_DYNAMIC_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_DYNAMIC_HPP
#define __UTIL_ALLOC_DYNAMIC_HPP #define CRUFT_UTIL_ALLOC_RAW_DYNAMIC_HPP
#include <cstddef> #include <cstddef>
#include <memory> #include <memory>
namespace util::alloc { namespace util::alloc::raw {
// wraps an allocator given at construction time, forwarding all calls to // wraps an allocator given at construction time, forwarding all calls to
// the inner object. used to allow virtual dispatch of the non-virtual // the inner object. used to allow virtual dispatch of the non-virtual
// allocator interface. // allocator interface.

17
alloc/raw/fallback.cpp Normal file
View File

@ -0,0 +1,17 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2017 Danny Robson <danny@nerdcruft.net>
*/
#include "./fallback.hpp"

View File

@ -11,25 +11,33 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
* Copyright 2015 Danny Robson <danny@nerdcruft.net> * Copyright 2015-2017 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_ALLOC_FALLBACK_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_FALLBACK_HPP
#define __UTIL_ALLOC_FALLBACK_HPP #define CRUFT_UTIL_ALLOC_RAW_FALLBACK_HPP
#include <cstddef> #include <cstddef>
#include <tuple>
namespace util::alloc { namespace util::alloc::raw {
template <class A, class B> /// A raw memory allocator that allocates memory series of child
/// allocators, preferring earlier allocators.
template <typename ...ChildT>
class fallback { class fallback {
public: public:
fallback (A&, B&); fallback (ChildT &..._children):
m_children (_children...)
{ ; }
void* allocate (size_t bytes); void* allocate (size_t bytes);
void* allocate (size_t bytes, size_t align); void* allocate (size_t bytes, size_t align);
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);
private:
std::tuple<ChildT&...> m_children;
}; };
} }

View File

@ -16,10 +16,10 @@
#include "./linear.hpp" #include "./linear.hpp"
#include "../pointer.hpp" #include "../../pointer.hpp"
#include "../debug.hpp" #include "../../debug.hpp"
using util::alloc::linear; using util::alloc::raw::linear;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -14,12 +14,12 @@
* Copyright 2015 Danny Robson <danny@nerdcruft.net> * Copyright 2015 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_ALLOC_LINEAR_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_LINEAR_HPP
#define __UTIL_ALLOC_LINEAR_HPP #define CRUFT_UTIL_ALLOC_RAW_LINEAR_HPP
#include <cstddef> #include <cstddef>
namespace util::alloc { namespace util::alloc::raw {
// allocate progressively across a buffer without concern for deallocation. // allocate progressively across a buffer without concern for deallocation.
// deallocation is a noop; the only way to free allocations is via reset. // deallocation is a noop; the only way to free allocations is via reset.
class linear { class linear {

View File

@ -16,11 +16,11 @@
#include "./malloc.hpp" #include "./malloc.hpp"
#include "../debug.hpp" #include "../../debug.hpp"
#include <cstdlib> #include <cstdlib>
using util::alloc::malloc; using util::alloc::raw::malloc;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -14,13 +14,13 @@
* Copyright 2015 Danny Robson <danny@nerdcruft.net> * Copyright 2015 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_ALLOC_MALLOC_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_MALLOC_HPP
#define __UTIL_ALLOC_MALLOC_HPP #define CRUFT_UTIL_ALLOC_RAW_MALLOC_HPP
#include <cstddef> #include <cstddef>
namespace util::alloc { namespace util::alloc::raw {
class malloc { class malloc {
public: public:
void* allocate (size_t bytes); void* allocate (size_t bytes);

View File

@ -17,11 +17,11 @@
#include "./null.hpp" #include "./null.hpp"
#include "../debug.hpp" #include "../../debug.hpp"
#include <new> #include <new>
using util::alloc::null; using util::alloc::raw::null;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -14,13 +14,13 @@
* Copyright 2015 Danny Robson <danny@nerdcruft.net> * Copyright 2015 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_ALLOC_NULL_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_NULL_HPP
#define __UTIL_ALLOC_NULL_HPP #define CRUFT_UTIL_ALLOC_RAW_NULL_HPP
#include <cstddef> #include <cstddef>
namespace util::alloc { namespace util::alloc::raw {
// allocator that always fails, throwing bad_alloc. deallocate will // allocator that always fails, throwing bad_alloc. deallocate will
// succeed with nullptr as with delete, but is undefined with other values // succeed with nullptr as with delete, but is undefined with other values
// (it is likely to at least assert). // (it is likely to at least assert).

View File

@ -16,11 +16,11 @@
#include "./stack.hpp" #include "./stack.hpp"
#include "../debug.hpp" #include "../../debug.hpp"
#include "../pointer.hpp" #include "../../pointer.hpp"
#include "../cast.hpp" #include "../../cast.hpp"
using util::alloc::stack; using util::alloc::raw::stack;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -14,13 +14,13 @@
* Copyright 2015 Danny Robson <danny@nerdcruft.net> * Copyright 2015 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_ALLOC_STACK_HPP #ifndef CRUFT_UTIL_ALLOC_RAW_STACK_HPP
#define __UTIL_ALLOC_STACK_HPP #define CRUFT_UTIL_ALLOC_RAW_STACK_HPP
#include <cstddef> #include <cstddef>
namespace util::alloc { namespace util::alloc::raw {
// allocate memory from a buffer in a stacklike manner. deallocation that // allocate memory from a buffer in a stacklike manner. deallocation that
// is not correctly ordered has undefined (read 'bad') results. // is not correctly ordered has undefined (read 'bad') results.
class stack { class stack {

View File

@ -14,10 +14,10 @@
* Copyright 2015 Danny Robson <danny@nerdcruft.net> * Copyright 2015 Danny Robson <danny@nerdcruft.net>
*/ */
#ifdef __UTIL_ALLOC_STACK_IPP #ifdef CRUFT_UTIL_ALLOC_RAW_STACK_IPP
#error #error
#endif #endif
#define __UTIL_ALLOC_STACK_IPP #define CRUFT_UTIL_ALLOC_RAW_STACK_IPP

View File

@ -1,7 +1,7 @@
#include "tap.hpp" #include "tap.hpp"
#include "alloc/aligned.hpp" #include "alloc/raw/aligned.hpp"
#include "alloc/linear.hpp" #include "alloc/raw/linear.hpp"
int int
@ -20,7 +20,7 @@ main (int, char**)
// we're probably operating correctly. // we're probably operating correctly.
static constexpr std::size_t alignment = 3; static constexpr std::size_t alignment = 3;
util::alloc::aligned<util::alloc::linear> alloc ( util::alloc::raw::aligned<util::alloc::raw::linear> alloc (
alignment, std::begin (buffer), std::end (buffer) alignment, std::begin (buffer), std::end (buffer)
); );

View File

@ -1,11 +1,13 @@
#include "tap.hpp" #include "tap.hpp"
#include "alloc/arena.hpp" #include "alloc/arena.hpp"
#include "alloc/linear.hpp" #include "alloc/raw/linear.hpp"
///////////////////////////////////////////////////////////////////////////////
static char g_backing[1024*1024]; static char g_backing[1024*1024];
//-----------------------------------------------------------------------------
struct setter { struct setter {
setter (const setter&) = delete; setter (const setter&) = delete;
@ -20,11 +22,12 @@ struct setter {
}; };
//-----------------------------------------------------------------------------
int int
main (void) main (void)
{ {
util::alloc::linear alloc (std::begin (g_backing), std::end (g_backing)); util::alloc::raw::linear alloc (std::begin (g_backing), std::end (g_backing));
util::alloc::arena<util::alloc::linear> arena (alloc); util::alloc::arena<util::alloc::raw::linear> arena (alloc);
util::TAP::logger tap; util::TAP::logger tap;

View File

@ -1,14 +1,15 @@
#include "tap.hpp" #include "tap.hpp"
#include "alloc/dynamic.hpp" #include "alloc/raw/dynamic.hpp"
#include "alloc/null.hpp" #include "alloc/raw/null.hpp"
///////////////////////////////////////////////////////////////////////////////
int int
main (void) main (void)
{ {
util::TAP::logger tap; util::TAP::logger tap;
auto obj = util::alloc::dynamic::make<util::alloc::null> (); auto obj = util::alloc::raw::dynamic::make<util::alloc::raw::null> ();
tap.expect_throw<std::bad_alloc> ( tap.expect_throw<std::bad_alloc> (
[&] (void) { [&] (void) {

View File

@ -1,7 +1,8 @@
#include "tap.hpp" #include "tap.hpp"
#include "alloc/linear.hpp" #include "alloc/raw/linear.hpp"
///////////////////////////////////////////////////////////////////////////////
int int
main (void) main (void)
{ {
@ -10,7 +11,7 @@ main (void)
constexpr size_t BUFFER_SIZE = 1024; constexpr size_t BUFFER_SIZE = 1024;
alignas (std::max_align_t) char memory[BUFFER_SIZE]; alignas (std::max_align_t) char memory[BUFFER_SIZE];
util::alloc::linear store (std::begin (memory), std::end (memory)); util::alloc::raw::linear store (std::begin (memory), std::end (memory));
tap.expect_eq (store.base (), std::begin (memory), "base pointers match"); tap.expect_eq (store.base (), std::begin (memory), "base pointers match");
tap.expect_eq (store.offset (std::begin (memory)), 0u, "base offset is 0"); tap.expect_eq (store.offset (std::begin (memory)), 0u, "base offset is 0");

View File

@ -1,10 +1,10 @@
#include "tap.hpp" #include "tap.hpp"
#include "alloc/stack.hpp" #include "alloc/raw/stack.hpp"
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void void
n_allocations (util::alloc::stack &store, n_allocations (util::alloc::raw::stack &store,
unsigned count, unsigned count,
size_t bytes, size_t bytes,
size_t alignment = alignof (std::max_align_t)) size_t alignment = alignof (std::max_align_t))
@ -32,7 +32,7 @@ main (void)
alignas (std::max_align_t) char memory[BUFFER_SIZE]; alignas (std::max_align_t) char memory[BUFFER_SIZE];
std::fill (std::begin (memory), std::end (memory), 0); std::fill (std::begin (memory), std::end (memory), 0);
util::alloc::stack store (memory, memory + BUFFER_AVAILABLE); util::alloc::raw::stack store (memory, memory + BUFFER_AVAILABLE);
tap.expect_eq (store.base (), std::begin (memory), "base pointers match"); tap.expect_eq (store.base (), std::begin (memory), "base pointers match");
tap.expect_eq (store.offset (std::begin (memory)), 0u, "base offset is 0"); tap.expect_eq (store.offset (std::begin (memory)), 0u, "base offset is 0");