allocator.hpp
Go to the documentation of this file.
/*
* Copyright 2016-2017, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PMEMOBJ_ALLOCATOR_HPP
#define PMEMOBJ_ALLOCATOR_HPP
#include "libpmemobj++/detail/common.hpp"
#include "libpmemobj++/detail/life.hpp"
#include "libpmemobj++/detail/pexceptions.hpp"
#include "libpmemobj++/persistent_ptr.hpp"
#include "libpmemobj++/pext.hpp"
#include "libpmemobj.h"
namespace pmem
{
namespace obj
{
template <typename T>
class object_traits {
public:
/*
* Important typedefs.
*/
using value_type = T;
using pointer = persistent_ptr<value_type>;
using const_pointer = persistent_ptr<const value_type>;
using reference = value_type &;
using const_reference = const value_type &;
template <class U>
struct rebind {
using other = object_traits<U>;
};
object_traits() = default;
~object_traits() = default;
template <typename U,
typename = typename std::enable_if<
std::is_convertible<U *, T *>::value>::type>
explicit object_traits(object_traits<U> const &)
{
}
void
construct(pointer p, const_reference t)
{
/* construct called on newly allocated objects */
detail::conditional_add_to_tx(p.get());
new (static_cast<void *>(p.get())) value_type(t);
}
template <typename... Args>
void
construct(pointer p, Args &&... args)
{
detail::conditional_add_to_tx(p.get());
new (static_cast<void *>(p.get()))
value_type(std::forward<Args>(args)...);
}
void
destroy(pointer p)
{
/* XXX should we allow modifications outside of tx? */
if (pmemobj_tx_stage() == TX_STAGE_WORK) {
pmemobj_tx_add_range_direct((void *)p.get(), sizeof(p));
}
detail::destroy<value_type>(*p);
}
};
template <>
class object_traits<void> {
public:
/*
* Important typedefs.
*/
using value_type = void;
using pointer = persistent_ptr<value_type>;
template <class U>
struct rebind {
using other = object_traits<U>;
};
object_traits() = default;
~object_traits() = default;
template <typename U>
explicit object_traits(object_traits<U> const &)
{
}
};
template <typename T>
class standard_alloc_policy {
public:
/*
* Important typedefs.
*/
using value_type = T;
using pointer = persistent_ptr<value_type>;
using const_void_pointer = persistent_ptr<const void>;
using size_type = std::size_t;
using bool_type = bool;
template <class U>
struct rebind {
using other = standard_alloc_policy<U>;
};
standard_alloc_policy() = default;
~standard_alloc_policy() = default;
explicit standard_alloc_policy(standard_alloc_policy const &)
{
}
template <typename U,
typename = typename std::enable_if<
std::is_convertible<U *, T *>::value>::type>
explicit standard_alloc_policy(standard_alloc_policy<U> const &)
{
}
pointer
allocate(size_type cnt, const_void_pointer = 0)
{
if (pmemobj_tx_stage() != TX_STAGE_WORK)
throw transaction_scope_error(
"refusing to allocate "
"memory outside of transaction scope");
/* allocate raw memory, no object construction */
return pmemobj_tx_alloc(sizeof(value_type) * cnt,
detail::type_num<T>());
}
void
deallocate(pointer p, size_type = 0)
{
if (pmemobj_tx_stage() != TX_STAGE_WORK)
throw transaction_scope_error(
"refusing to free "
"memory outside of transaction scope");
if (pmemobj_tx_free(*p.raw_ptr()) != 0)
throw transaction_free_error(
"failed to delete "
"persistent memory object");
}
size_type
max_size() const
{
return PMEMOBJ_MAX_ALLOC_SIZE / sizeof(value_type);
}
};
template <>
class standard_alloc_policy<void> {
public:
/*
* Important typedefs.
*/
using value_type = void;
using pointer = persistent_ptr<value_type>;
using const_pointer = persistent_ptr<const value_type>;
using reference = value_type;
using const_reference = const value_type;
using size_type = std::size_t;
using bool_type = bool;
template <class U>
struct rebind {
using other = standard_alloc_policy<U>;
};
standard_alloc_policy() = default;
~standard_alloc_policy() = default;
explicit standard_alloc_policy(standard_alloc_policy const &)
{
}
template <typename U>
explicit standard_alloc_policy(standard_alloc_policy<U> const &)
{
}
pointer
allocate(size_type cnt, const_pointer = 0)
{
if (pmemobj_tx_stage() != TX_STAGE_WORK)
throw transaction_scope_error(
"refusing to allocate "
"memory outside of transaction scope");
/* allocate raw memory, no object construction */
return pmemobj_tx_alloc(1 /* void size */ * cnt, 0);
}
void
deallocate(pointer p, size_type = 0)
{
if (pmemobj_tx_stage() != TX_STAGE_WORK)
throw transaction_scope_error(
"refusing to free "
"memory outside of transaction scope");
if (pmemobj_tx_free(p.raw()) != 0)
throw transaction_free_error(
"failed to delete "
"persistent memory object");
}
size_type
max_size() const
{
return PMEMOBJ_MAX_ALLOC_SIZE;
}
};
template <typename T, typename T2>
inline bool
operator==(standard_alloc_policy<T> const &, standard_alloc_policy<T2> const &)
{
return true;
}
template <typename T, typename OtherAllocator>
inline bool
operator==(standard_alloc_policy<T> const &, OtherAllocator const &)
{
return false;
}
template <typename T, typename Policy = standard_alloc_policy<T>,
typename Traits = object_traits<T>>
class allocator : public Policy, public Traits {
private:
/*
* private typedefs
*/
using AllocationPolicy = Policy;
using TTraits = Traits;
public:
/*
* Important typedefs.
*/
using size_type = typename AllocationPolicy::size_type;
using pointer = typename AllocationPolicy::pointer;
using value_type = typename AllocationPolicy::value_type;
template <typename U>
struct rebind {
using other = allocator<
U, typename AllocationPolicy::template rebind<U>::other,
typename TTraits::template rebind<U>::other>;
};
allocator() = default;
~allocator() = default;
explicit allocator(allocator const &rhs) : Policy(rhs), Traits(rhs)
{
}
template <typename U>
explicit allocator(allocator<U> const &)
{
}
template <typename U, typename P, typename T2>
explicit allocator(allocator<U, P, T2> const &rhs)
: Policy(rhs), Traits(rhs)
{
}
};
template <typename T, typename P, typename Tr, typename T2, typename P2,
typename Tr2>
inline bool
operator==(const allocator<T, P, Tr> &lhs, const allocator<T2, P2, Tr2> &rhs)
{
return operator==(static_cast<const P &>(lhs),
static_cast<const P2 &>(rhs));
}
template <typename T, typename P, typename Tr, typename OtherAllocator>
inline bool
operator!=(const allocator<T, P, Tr> &lhs, const OtherAllocator &rhs)
{
return !operator==(lhs, rhs);
}
} /* namespace obj */
} /* namespace pmem */
#endif /* PMEMOBJ_ALLOCATOR_HPP */
pmem::obj::operator==
bool operator==(standard_alloc_policy< T > const &, standard_alloc_policy< T2 > const &)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:406
pmem::obj::standard_alloc_policy< void >::allocate
pointer allocate(size_type cnt, const_pointer=0)
Allocate storage for cnt bytes.
Definition: allocator.hpp:355
pmem::obj::allocator
(EXPERIMENTAL) Encapsulates the information about the persistent memory allocation model using PMDK&#39;s...
Definition: allocator.hpp:432
pmem::obj::standard_alloc_policy::standard_alloc_policy
standard_alloc_policy(standard_alloc_policy< U > const &)
Type converting constructor.
Definition: allocator.hpp:239
pmem::obj::allocator::allocator
allocator(allocator const &rhs)
Explicit copy constructor.
Definition: allocator.hpp:471
pmem::obj::persistent_ptr
Persistent pointer class.
Definition: common.hpp:51
pmem::obj::standard_alloc_policy< void >::deallocate
void deallocate(pointer p, size_type=0)
Deallocates storage pointed to p, which must be a value returned by a previous call to allocate that ...
Definition: allocator.hpp:374
pmem::obj::allocator::allocator
allocator(allocator< U, P, T2 > const &rhs)
Type converting constructor.
Definition: allocator.hpp:487
pmem::obj::object_traits::object_traits
object_traits(object_traits< U > const &)
Type converting constructor.
Definition: allocator.hpp:94
pmem::obj::standard_alloc_policy::standard_alloc_policy
standard_alloc_policy(standard_alloc_policy const &)
Explicit copy constructor.
Definition: allocator.hpp:229
pext.hpp
Convenience extensions for the resides on pmem property template.
pmem::obj::object_traits::destroy
void destroy(pointer p)
Destroy an object based on a pointer.
Definition: allocator.hpp:139
life.hpp
Functions for destroying arrays.
common.hpp
Commonly used functionality.
pmem::obj::standard_alloc_policy::deallocate
void deallocate(pointer p, size_type=0)
Deallocates storage pointed to p, which must be a value returned by a previous call to allocate that ...
Definition: allocator.hpp:272
pexceptions.hpp
Custom exceptions.
pmem::obj::object_traits::rebind
Rebind to a different type.
Definition: allocator.hpp:74
pmem::obj::object_traits< void >::object_traits
object_traits(object_traits< U > const &)
Type converting constructor.
Definition: allocator.hpp:185
pmem::obj::standard_alloc_policy
The allocation policy template for a given type.
Definition: allocator.hpp:197
pmem::obj::object_traits::object_traits
object_traits()=default
Defaulted constructor.
pmem::obj::object_traits::~object_traits
~object_traits()=default
Defaulted destructor.
pmem::obj::standard_alloc_policy< void >::standard_alloc_policy
standard_alloc_policy(standard_alloc_policy const &)
Explicit copy constructor.
Definition: allocator.hpp:335
pmem::obj::allocator::allocator
allocator(allocator< U > const &)
Type converting constructor.
Definition: allocator.hpp:479
pmem::obj::allocator::rebind
Rebind to a different type.
Definition: allocator.hpp:452
pmem::obj::standard_alloc_policy::rebind
Rebind to a different type.
Definition: allocator.hpp:212
persistent_ptr.hpp
Persistent smart pointer.
pmem::detail::persistent_ptr_base::raw
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:296
pmem::obj::standard_alloc_policy::allocate
pointer allocate(size_type cnt, const_void_pointer=0)
Allocate storage for cnt objects of type T.
Definition: allocator.hpp:252
pmem::transaction_free_error
Custom transaction error class.
Definition: pexceptions.hpp:94
pmem::detail::persistent_ptr_base::raw_ptr
PMEMoid * raw_ptr() noexcept
Get pointer to PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:309
pmem::obj::p
Resides on pmem class.
Definition: p.hpp:64
pmem::obj::standard_alloc_policy< void >::max_size
size_type max_size() const
The largest value that can meaningfully be passed to allocate().
Definition: allocator.hpp:393
pmem::obj::operator!=
bool operator!=(const allocator< T, P, Tr > &lhs, const OtherAllocator &rhs)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:522
pmem::transaction_scope_error
Custom transaction error class.
Definition: pexceptions.hpp:104
pmem
Definition: allocator.hpp:48
pmem::detail::persistent_ptr_base::get
element_type * get() const noexcept
Get a direct pointer.
Definition: persistent_ptr_base.hpp:278
pmem::obj::object_traits
Encapsulates object specific allocator functionality.
Definition: allocator.hpp:59
pmem::obj::object_traits::construct
void construct(pointer p, Args &&... args)
Create an object at a specific address.
Definition: allocator.hpp:124
pmem::obj::standard_alloc_policy::max_size
size_type max_size() const
The largest value that can meaningfully be passed to allocate().
Definition: allocator.hpp:291
pmem::obj::object_traits::construct
void construct(pointer p, const_reference t)
Create an object at a specific address.
Definition: allocator.hpp:107
pmem::obj::standard_alloc_policy< void >::standard_alloc_policy
standard_alloc_policy(standard_alloc_policy< U > const &)
Type converting constructor.
Definition: allocator.hpp:343