Skip to content

Commit

Permalink
Move ALIGNMENT to detail namespace
Browse files Browse the repository at this point in the history
Add more doc comments to allocators
  • Loading branch information
KredeGC committed Mar 19, 2023
1 parent 9a9c41d commit 0897420
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 16 deletions.
38 changes: 36 additions & 2 deletions include/ktl/allocators/cascading.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,17 @@ namespace ktl
}

#pragma region Allocation
/**
* @brief Attempts to allocate a chunk of memory defined by @p n
* @note May create a new instance of the underlying allocator and attempt to allocate using it
* @param n The amount of bytes to allocate memory for
* @return A location in memory that is at least @p n bytes big or nullptr if it could not be allocated
*/
void* allocate(size_type n)
{
// Add an initial allocator
if (!m_Node)
m_Node = detail::aligned_new<node>(ALIGNMENT);
m_Node = detail::aligned_new<node>(detail::ALIGNMENT);

if constexpr (detail::has_max_size<Alloc>::value)
{
Expand All @@ -100,7 +106,7 @@ namespace ktl
{
node* next = m_Node;

m_Node = detail::aligned_new<node>(ALIGNMENT);
m_Node = detail::aligned_new<node>(detail::ALIGNMENT);
m_Node->Next = next;

p = m_Node->Allocator.allocate(n);
Expand All @@ -112,6 +118,12 @@ namespace ktl
return p;
}

/**
* @brief Attempts to deallocate the memory at location @p p
* @note Deallocation can take O(n) time as it may have to traverse all allocator instances
* @param p The location in memory to deallocate
* @param n The size that was initially allocated
*/
void deallocate(void* p, size_type n) noexcept
{
KTL_ASSERT(p != nullptr);
Expand Down Expand Up @@ -143,6 +155,13 @@ namespace ktl
#pragma endregion

#pragma region Construction
/**
* @brief Constructs an object of T with the given @p ...args at the given location
* @note Only defined if the underlying allocator defines it
* @tparam ...Args The types of the arguments
* @param p The location of the object in memory
* @param ...args A range of arguments to use to construct the object
*/
template<typename T, typename... Args>
typename std::enable_if<detail::has_construct_v<Alloc, T*, Args...>, void>::type
construct(T* p, Args&&... args)
Expand All @@ -162,6 +181,11 @@ namespace ktl
::new(p) T(std::forward<Args>(args)...);
}

/**
* @brief Destructs an object of T at the given location
* @note Only defined if the underlying allocator defines it
* @param p The location of the object in memory
*/
template<typename T>
typename std::enable_if<detail::has_destroy_v<Alloc, T*>, void>::type
destroy(T* p)
Expand All @@ -183,13 +207,23 @@ namespace ktl
#pragma endregion

#pragma region Utility
/**
* @brief Returns the maximum size that an allocation can be
* @note Only defined if the underlying allocator defines it
* @return The maximum size an allocation may be
*/
template<typename A = Alloc>
typename std::enable_if<detail::has_max_size_v<A>, size_type>::type
max_size() const noexcept
{
return m_Node->Allocator.max_size();
}

/**
* @brief Returns whether or not the allocator owns the given location in memory
* @param p The location of the object in memory
* @return Whether the allocator owns @p p
*/
bool owns(void* p) const
{
node* next = m_Node;
Expand Down
44 changes: 44 additions & 0 deletions include/ktl/allocators/freelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ namespace ktl
}

#pragma region Allocation
/**
* @brief Attempts to allocate a chunk of memory defined by @p n.
* Will use previous allocations that were meant to be deallocated.
* @note If @p n is not within Min and Max, this function will return nullptr
* @param n The amount of bytes to allocate memory for
* @return A location in memory that is at least @p n bytes big or nullptr if it could not be allocated
*/
void* allocate(size_type n)
{
if (n > Min && n <= Max)
Expand All @@ -112,6 +119,12 @@ namespace ktl
return nullptr;
}

/**
* @brief Attempts to deallocate the memory at location @p p
* @note Will not deallocate the memory, but instead tie it to a linked list for later reuse
* @param p The location in memory to deallocate
* @param n The size that was initially allocated
*/
void deallocate(void* p, size_type n)
{
KTL_ASSERT(p != nullptr);
Expand All @@ -126,13 +139,25 @@ namespace ktl
#pragma endregion

#pragma region Construction
/**
* @brief Constructs an object of T with the given @p ...args at the given location
* @note Only defined if the underlying allocator defines it
* @tparam ...Args The types of the arguments
* @param p The location of the object in memory
* @param ...args A range of arguments to use to construct the object
*/
template<typename T, typename... Args>
typename std::enable_if<detail::has_construct_v<Alloc, T*, Args...>, void>::type
construct(T* p, Args&&... args)
{
m_Alloc.construct(p, std::forward<Args>(args)...);
}

/**
* @brief Destructs an object of T at the given location
* @note Only defined if the underlying allocator defines it
* @param p The location of the object in memory
*/
template<typename T>
typename std::enable_if<detail::has_destroy_v<Alloc, T*>, void>::type
destroy(T* p)
Expand All @@ -142,13 +167,24 @@ namespace ktl
#pragma endregion

#pragma region Utility
/**
* @brief Returns the maximum size that an allocation can be
* @note Only defined if the underlying allocator defines it
* @return The maximum size an allocation may be
*/
template<typename A = Alloc>
typename std::enable_if<detail::has_max_size_v<A>, size_type>::type
max_size() const noexcept
{
return m_Alloc.max_size();
}

/**
* @brief Returns whether or not the allocator owns the given location in memory
* @note Only defined if the underlying allocator defines it
* @param p The location of the object in memory
* @return Whether the allocator owns @p p
*/
template<typename A = Alloc>
typename std::enable_if<detail::has_owns_v<A>, bool>::type
owns(void* p) const
Expand All @@ -157,11 +193,19 @@ namespace ktl
}
#pragma endregion

/**
* @brief Returns a reference to the underlying allocator
* @return The allocator
*/
Alloc& get_allocator()
{
return m_Alloc;
}

/**
* @brief Returns a const reference to the underlying allocator
* @return The allocator
*/
const Alloc& get_allocator() const
{
return m_Alloc;
Expand Down
36 changes: 33 additions & 3 deletions include/ktl/allocators/linear_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ namespace ktl

linear_allocator(const linear_allocator&) noexcept = delete;

/**
* @brief Move constructor
* @note Moving is only allowed if the original allocator has no allocations
* @param other The original allocator
*/
linear_allocator(linear_allocator&& other) noexcept :
m_Data{},
m_Free(m_Data),
Expand All @@ -36,6 +41,11 @@ namespace ktl

linear_allocator& operator=(const linear_allocator&) noexcept = delete;

/**
* @brief Move assignment operator
* @note Moving is only allowed if the original allocator has no allocations
* @param rhs The original allocator
*/
linear_allocator& operator=(linear_allocator&& rhs) noexcept
{
m_Free = m_Data;
Expand All @@ -57,9 +67,14 @@ namespace ktl
}

#pragma region Allocation
/**
* @brief Attempts to allocate a chunk of memory defined by @p n
* @param n The amount of bytes to allocate memory for
* @return A location in memory that is at least @p n bytes big or nullptr if it could not be allocated
*/
void* allocate(size_t n)
{
size_t totalSize = n + align_to_architecture(n);
size_t totalSize = n + detail::align_to_architecture(n);

if ((size_t(m_Free - m_Data) + totalSize) > Size)
return nullptr;
Expand All @@ -72,11 +87,17 @@ namespace ktl
return current;
}

/**
* @brief Attempts to deallocate the memory at location @p p
* @note The memory is only completely deallocated if it was the last allocation made or all memory has been deallocated
* @param p The location in memory to deallocate
* @param n The size that was initially allocated
*/
void deallocate(void* p, size_t n) noexcept
{
KTL_ASSERT(p != nullptr);

size_t totalSize = n + align_to_architecture(n);
size_t totalSize = n + detail::align_to_architecture(n);

if (m_Free - totalSize == p)
m_Free -= totalSize;
Expand All @@ -90,19 +111,28 @@ namespace ktl
#pragma endregion

#pragma region Utility
/**
* @brief Returns the maximum size that an allocation can be
* @return The maximum size an allocation may be
*/
size_t max_size() const noexcept
{
return Size;
}

/**
* @brief Returns whether or not the allocator owns the given location in memory
* @param p The location of the object in memory
* @return Whether the allocator owns @p p
*/
bool owns(void* p) const
{
return p >= m_Data && p < m_Data + Size;
}
#pragma endregion

private:
alignas(ALIGNMENT) char m_Data[Size];
alignas(detail::ALIGNMENT) char m_Data[Size];
char* m_Free;
size_t m_ObjectCount;
};
Expand Down
2 changes: 1 addition & 1 deletion include/ktl/allocators/mallocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace ktl
#pragma region Allocation
void* allocate(size_t n)
{
return detail::aligned_malloc(n, ALIGNMENT);
return detail::aligned_malloc(n, detail::ALIGNMENT);
}

void deallocate(void* p, size_t n) noexcept
Expand Down
4 changes: 2 additions & 2 deletions include/ktl/allocators/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace ktl
typedef typename detail::get_size_type_t<Alloc> size_type;

shared() noexcept :
m_Block(detail::aligned_new<block>(ALIGNMENT)) {}
m_Block(detail::aligned_new<block>(detail::ALIGNMENT)) {}

/**
* @brief Constructor for forwarding any arguments to the underlying allocator
Expand All @@ -42,7 +42,7 @@ namespace ktl
typename = std::enable_if_t<
detail::can_construct_v<Alloc, Args...>>>
explicit shared(Args&&... alloc) noexcept :
m_Block(detail::aligned_new<block>(ALIGNMENT, std::forward<Args>(alloc)...)) {}
m_Block(detail::aligned_new<block>(detail::ALIGNMENT, std::forward<Args>(alloc)...)) {}

shared(const shared& other) noexcept :
m_Block(other.m_Block)
Expand Down
6 changes: 3 additions & 3 deletions include/ktl/allocators/stack_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace ktl
template<size_t Size>
struct stack
{
alignas(ALIGNMENT) char Data[Size];
alignas(detail::ALIGNMENT) char Data[Size];
char* Free;
size_t ObjectCount;

Expand Down Expand Up @@ -62,7 +62,7 @@ namespace ktl
#pragma region Allocation
void* allocate(size_t n)
{
size_t totalSize = n + align_to_architecture(n);
size_t totalSize = n + detail::align_to_architecture(n);

if ((size_t(m_Block->Free - m_Block->Data) + totalSize) > Size)
return nullptr;
Expand All @@ -77,7 +77,7 @@ namespace ktl

void deallocate(void* p, size_t n) noexcept
{
size_t totalSize = n + align_to_architecture(n);
size_t totalSize = n + detail::align_to_architecture(n);

if (m_Block->Free - totalSize == p)
m_Block->Free -= totalSize;
Expand Down
4 changes: 2 additions & 2 deletions include/ktl/allocators/threaded.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace ktl
typedef typename detail::get_size_type_t<Alloc> size_type;

threaded() noexcept :
m_Block(detail::aligned_new<block>(ALIGNMENT)) {}
m_Block(detail::aligned_new<block>(detail::ALIGNMENT)) {}

/**
* @brief Constructor for forwarding any arguments to the underlying allocator
Expand All @@ -46,7 +46,7 @@ namespace ktl
typename = std::enable_if_t<
detail::can_construct_v<Alloc, Args...>>>
explicit threaded(Args&&... alloc) noexcept :
m_Block(detail::aligned_new<block>(ALIGNMENT, std::forward<Args>(alloc)...)) {}
m_Block(detail::aligned_new<block>(detail::ALIGNMENT, std::forward<Args>(alloc)...)) {}

threaded(const threaded& other) noexcept :
m_Block(other.m_Block)
Expand Down
8 changes: 6 additions & 2 deletions include/ktl/allocators/type_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ namespace ktl
typedef type_allocator<U, Alloc> other;
};

/**
* @brief Default constructor
* @note Only defined if the underlying allocator defines it
*/
type_allocator() noexcept = default;

/**
Expand Down Expand Up @@ -110,9 +114,9 @@ namespace ktl

#pragma region Utility
/**
* @brief Returns the maximum size that an allocation can be
* @brief Returns the maximum size that an allocation of objects can be
* @note Only defined if the underlying allocator defines it
* @return The maximum size an allocation may be
* @return The maximum size an allocation may be. Not in bytes, but number of T
*/
template<typename A = Alloc>
typename std::enable_if<detail::has_max_size_v<A>, size_type>::type
Expand Down
2 changes: 1 addition & 1 deletion include/ktl/utility/alignment.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <cstddef>

namespace ktl
namespace ktl::detail
{
constexpr size_t ALIGNMENT = 8;
constexpr size_t ALIGNMENT_MASK = ALIGNMENT - 1;
Expand Down

0 comments on commit 0897420

Please sign in to comment.