[-] AuMemoryView
[-] AuMemory::Heap [*] Use AuSetAllocator [-] AuMemory::PmrCppHeapWrapper
This commit is contained in:
parent
b80bb7fc77
commit
9acc56431a
@ -4,6 +4,7 @@
|
|||||||
File: CppHeapWrapper.hpp
|
File: CppHeapWrapper.hpp
|
||||||
Date: 2023-12-22
|
Date: 2023-12-22
|
||||||
Author: Reece
|
Author: Reece
|
||||||
|
Note: use AuPMRAllocator instead
|
||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@ -21,258 +22,8 @@ namespace Aurora::Memory
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
/// @deprecated use ROXTL AuPMRAllocator instead
|
||||||
struct PmrCppHeapWrapper
|
/// Some legacy code treats the container as the handle, such that .get_allocator() still returns a reference.
|
||||||
{
|
|
||||||
using value_type = T;
|
|
||||||
|
|
||||||
using size_type = size_t;
|
|
||||||
using difference_type = ptrdiff_t;
|
|
||||||
|
|
||||||
using propagate_on_container_move_assignment = AuTrueType;
|
|
||||||
using propagate_on_container_copy_assignment = AuTrueType;
|
|
||||||
using is_always_equal = AuFalseType;
|
|
||||||
|
|
||||||
#if defined(AU_LANG_CPP_17)
|
|
||||||
using pointer = T *;
|
|
||||||
using const_pointer = const T *;
|
|
||||||
|
|
||||||
using reference = T &;
|
|
||||||
using const_reference = const T &;
|
|
||||||
|
|
||||||
template <class Z>
|
|
||||||
struct rebind
|
|
||||||
{
|
|
||||||
using other = CppHeapWrapper<Z>;
|
|
||||||
};
|
|
||||||
|
|
||||||
T *address(T &val) const noexcept
|
|
||||||
{
|
|
||||||
return std::addressof(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
const T *address(const T &val) const noexcept
|
|
||||||
{
|
|
||||||
return std::addressof(val);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline PmrCppHeapWrapper(std::shared_ptr<Heap> pHeap) :
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
spHeap(pHeap),
|
|
||||||
pHeap(pHeap.get())
|
|
||||||
#else
|
|
||||||
spHeap(pHeap)
|
|
||||||
#endif
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline PmrCppHeapWrapper(Heap *pHeap, std::shared_ptr<void> pThat = {}) :
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
spHeap(pThat),
|
|
||||||
pHeap(pHeap)
|
|
||||||
#else
|
|
||||||
spHeap(AuSharedPointerFromShared(pHeap, pThat))
|
|
||||||
#endif
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <class B>
|
|
||||||
inline PmrCppHeapWrapper(const PmrCppHeapWrapper<B> &fuckCpp) :
|
|
||||||
spHeap(fuckCpp.spHeap)
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
,pHeap(fuckCpp.pHeap)
|
|
||||||
#endif
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline PmrCppHeapWrapper(const PmrCppHeapWrapper &fuckCpp) :
|
|
||||||
spHeap(fuckCpp.spHeap)
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
,pHeap(fuckCpp.pHeap)
|
|
||||||
#endif
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline PmrCppHeapWrapper(PmrCppHeapWrapper &&fuckCpp) :
|
|
||||||
spHeap(fuckCpp.spHeap)
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
,pHeap(fuckCpp.pHeap)
|
|
||||||
#endif
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
AU_DEF(PmrCppHeapWrapper)
|
|
||||||
AU_OPERATOR_COPY_MOVE(PmrCppHeapWrapper)
|
|
||||||
|
|
||||||
void *allocate_bytes(std::size_t nbytes,
|
|
||||||
std::size_t alignment = alignof(std::max_align_t))
|
|
||||||
{
|
|
||||||
if (auto pRet = this->GetHeapRaw()->FAlloc(nbytes, alignment))
|
|
||||||
{
|
|
||||||
return pRet;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void deallocate_bytes(void *p,
|
|
||||||
std::size_t nbytes,
|
|
||||||
std::size_t alignment = alignof(std::max_align_t)) noexcept
|
|
||||||
{
|
|
||||||
return this->GetHeapRaw()->Free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(AU_LANG_CPP_23_)
|
|
||||||
std::allocation_result<T *> allocate_at_least(const size_t count)
|
|
||||||
{
|
|
||||||
auto pThat = this->allocate(count);
|
|
||||||
return { (T *)pThat, this->GetHeapRaw()->GetChunkSize(pThat) / sizeof(T) };
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class U, class... Args >
|
|
||||||
void construct(U *p, Args&&... args)
|
|
||||||
{
|
|
||||||
new ((void *)p) U(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class U, class... Args >
|
|
||||||
void construct_at(U *p, Args&&... args)
|
|
||||||
{
|
|
||||||
new ((void *)p) U(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
void deallocate(const T *pType,
|
|
||||||
const size_t count) noexcept
|
|
||||||
{
|
|
||||||
this->deallocate_bytes((void *)pType, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
AU_ALLOC T *allocate(const size_t count)
|
|
||||||
{
|
|
||||||
if (!count)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (T *)this->allocate_bytes(count * sizeof(T), alignof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class U>
|
|
||||||
U *allocate_object(std::size_t n = 1)
|
|
||||||
{
|
|
||||||
return (U *)this->allocate_bytes(sizeof(U) * n, alignof(U));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class U>
|
|
||||||
void deallocate_object(U *p, std::size_t n = 1)
|
|
||||||
{
|
|
||||||
this->deallocate_bytes(p, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class U, class... CtorArgs>
|
|
||||||
U *new_object(CtorArgs&&... args)
|
|
||||||
{
|
|
||||||
U *p = this->allocate_object<U>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this->construct(p, AuForward<CtorArgs>(args)...);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
this->deallocate_object(p);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class U>
|
|
||||||
void delete_object(U *p)
|
|
||||||
{
|
|
||||||
if constexpr (AuIsClass_v<U> &&
|
|
||||||
!AuIsTriviallyDestructible_v<U>)
|
|
||||||
{
|
|
||||||
p->~U();
|
|
||||||
}
|
|
||||||
|
|
||||||
this->deallocate_object(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsInitialized() const
|
|
||||||
{
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
return bool(this->pHeap);
|
|
||||||
#else
|
|
||||||
return bool(this->spHeap);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Heap> GetHeap() const
|
|
||||||
{
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
return AuSharedPointerFromShared(this->pHeap, this->spHeap);
|
|
||||||
#else
|
|
||||||
return this->spHeap;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Heap *GetHeapRaw() const
|
|
||||||
{
|
|
||||||
Heap *pRet {};
|
|
||||||
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
pRet = this->pHeap;
|
|
||||||
#else
|
|
||||||
pRet = this->spHeap.get();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pRet)
|
|
||||||
{
|
|
||||||
return pRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
return this->pHeap = __audetail::gDefaultDiscontiguousHeap;
|
|
||||||
#else
|
|
||||||
return (this->spHeap = __audetail::gDefaultDiscontiguousHeapShared).get();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Z>
|
|
||||||
bool operator==(const Aurora::Memory::PmrCppHeapWrapper<Z> &rhs) noexcept
|
|
||||||
{
|
|
||||||
return this->GetHeapRaw() == rhs.GetHeapRaw();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Z>
|
|
||||||
bool operator!=(const Aurora::Memory::PmrCppHeapWrapper<Z> &rhs) noexcept
|
|
||||||
{
|
|
||||||
return this->GetHeapRaw() == rhs.GetHeapRaw();
|
|
||||||
}
|
|
||||||
template <class Z>
|
|
||||||
bool operator==(const Aurora::Memory::CppHeapWrapper<Z> &rhs) noexcept
|
|
||||||
{
|
|
||||||
return this->GetHeapRaw() == rhs.GetHeapRaw();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Z>
|
|
||||||
bool operator!=(const Aurora::Memory::CppHeapWrapper<Z> &rhs) noexcept
|
|
||||||
{
|
|
||||||
return this->GetHeapRaw() == rhs.GetHeapRaw();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
|
||||||
mutable std::shared_ptr<void> spHeap;
|
|
||||||
mutable Heap *pHeap {};
|
|
||||||
#else
|
|
||||||
mutable std::shared_ptr<Heap> spHeap;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename Z>
|
|
||||||
friend struct PmrCppHeapWrapper;
|
|
||||||
friend struct detail::AccessorICantEven;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct CppHeapWrapper
|
struct CppHeapWrapper
|
||||||
{
|
{
|
||||||
@ -520,7 +271,7 @@ namespace Aurora::Memory
|
|||||||
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
|
||||||
return this->pHeap = __audetail::gDefaultDiscontiguousHeap;
|
return this->pHeap = __audetail::gDefaultDiscontiguousHeap;
|
||||||
#else
|
#else
|
||||||
return (this->spHeap = __audetail::gDefaultDiscontiguousHeapShared).get();
|
return (this->spHeap = AuUnsafeRaiiToShared(__audetail::gDefaultDiscontiguousHeap)).get();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,22 +346,9 @@ inline bool operator==(const Aurora::Memory::CppHeapWrapper<T> &lhs,
|
|||||||
return lhs.GetHeapRaw() == rhs.GetHeapRaw();
|
return lhs.GetHeapRaw() == rhs.GetHeapRaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class Z>
|
|
||||||
inline bool operator==(const Aurora::Memory::PmrCppHeapWrapper<T> &lhs,
|
|
||||||
const Aurora::Memory::PmrCppHeapWrapper<Z> &rhs) noexcept
|
|
||||||
{
|
|
||||||
return lhs.GetHeapRaw() == rhs.GetHeapRaw();
|
|
||||||
}
|
|
||||||
template <class T, class Z>
|
template <class T, class Z>
|
||||||
inline bool operator!=(const Aurora::Memory::CppHeapWrapper<T> &lhs,
|
inline bool operator!=(const Aurora::Memory::CppHeapWrapper<T> &lhs,
|
||||||
const Aurora::Memory::CppHeapWrapper<Z> &rhs) noexcept
|
const Aurora::Memory::CppHeapWrapper<Z> &rhs) noexcept
|
||||||
{
|
{
|
||||||
return lhs.GetHeapRaw() != rhs.GetHeapRaw();
|
return lhs.GetHeapRaw() != rhs.GetHeapRaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class Z>
|
|
||||||
inline bool operator!=(const Aurora::Memory::PmrCppHeapWrapper<T> &lhs,
|
|
||||||
const Aurora::Memory::PmrCppHeapWrapper<Z> &rhs) noexcept
|
|
||||||
{
|
|
||||||
return lhs.GetHeapRaw() != rhs.GetHeapRaw();
|
|
||||||
}
|
|
@ -13,160 +13,8 @@ namespace Aurora::Memory
|
|||||||
static const AuUInt8 kHeapSize = 128;
|
static const AuUInt8 kHeapSize = 128;
|
||||||
static const AuUInt8 kHeap2Size = 255;
|
static const AuUInt8 kHeap2Size = 255;
|
||||||
|
|
||||||
template <class T>
|
using HeapAccessor = AuHeapAccessor;
|
||||||
struct CppHeapWrapper;
|
using Heap = AuHeap;
|
||||||
|
|
||||||
/**
|
|
||||||
* Note: The following public global aliases exists for heap and/or global process heap based allocations:
|
|
||||||
*
|
|
||||||
* AuHUPOf_t<T> AuNewClassArrayUnique([pHeap, ]uElements, ...)
|
|
||||||
* AuSPtr<T> AuNewClassArray([pHeap, ]uElements, ...)
|
|
||||||
* AuHUPOf_t<T> AuNewClassUnique([pHeap, ] ...)
|
|
||||||
* AuSPtr<T> AuNewClass([pHeap, ] ...)
|
|
||||||
* AuHUPOf_t<T> AuNullHeapPointer<T>()
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Heap
|
|
||||||
{
|
|
||||||
virtual AuSPtr<Heap> AllocateDivision(AuUInt32 heap, AuUInt32 alignment = 32) = 0;
|
|
||||||
virtual Types::size_t GetChunkSize(const void *pHead) = 0;
|
|
||||||
virtual HeapStats &GetStats() = 0;
|
|
||||||
virtual void WalkHeap(bool(*fCallback)(void *, void *), void *pSecondArg) = 0;
|
|
||||||
|
|
||||||
/// Potentially slower, zero allocate
|
|
||||||
template<typename T = void *>
|
|
||||||
T ZAlloc(Types::size_t uLength);
|
|
||||||
|
|
||||||
/// POD zero allocation
|
|
||||||
template<typename T = void *>
|
|
||||||
T ZAlloc(Types::size_t uLength, Types::size_t uAlignment);
|
|
||||||
|
|
||||||
/// POD zero allocation
|
|
||||||
template<typename T>
|
|
||||||
T *ZAlloc();
|
|
||||||
|
|
||||||
/// POD array, zero allocation
|
|
||||||
template<typename T>
|
|
||||||
T *NewArray(Types::size_t uLength);
|
|
||||||
|
|
||||||
/// POD array, zero allocation
|
|
||||||
template<typename T>
|
|
||||||
T *NewArray(Types::size_t uLength, Types::size_t uAlignment);
|
|
||||||
|
|
||||||
/// Fast, POD, non-zeroing allocation
|
|
||||||
template<typename T = void *>
|
|
||||||
T FAlloc(Types::size_t uLength);
|
|
||||||
|
|
||||||
/// Fast, POD, non-zeroing allocation
|
|
||||||
template<typename T = void *>
|
|
||||||
T FAlloc(Types::size_t uLength, Types::size_t uAlignment);
|
|
||||||
|
|
||||||
/// Fast, POD, non-zeroing allocation
|
|
||||||
template<typename T>
|
|
||||||
T *FAlloc();
|
|
||||||
|
|
||||||
// Reallocs
|
|
||||||
|
|
||||||
/// POD, zero-based expansion or reallocation
|
|
||||||
template<typename T>
|
|
||||||
T ZRealloc(T pHead, Types::size_t uLength);
|
|
||||||
|
|
||||||
/// POD, zero-based expansion or reallocation
|
|
||||||
template<typename T>
|
|
||||||
T ZRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment);
|
|
||||||
|
|
||||||
/// POD, expansion or reallocation
|
|
||||||
template<typename T>
|
|
||||||
T FRealloc(T pHead, Types::size_t uLength);
|
|
||||||
|
|
||||||
/// POD, expansion or reallocation
|
|
||||||
template<typename T>
|
|
||||||
T FRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment);
|
|
||||||
|
|
||||||
/// Free
|
|
||||||
template<typename T>
|
|
||||||
void Free(T pHead);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static void DeleteThat(T *pThat);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static void DeleteThatArray(T *pThat);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static void DeleteThatArray2(T *pThat);
|
|
||||||
|
|
||||||
template <typename T, typename Z>
|
|
||||||
static void DeleteThatCastedOnce(T *pThat);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static void RetardedSpecWrittenByRetards(T *pThat);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> NewClass(Args &&...args);
|
|
||||||
|
|
||||||
// note: callers can use AuHUPOf_t<Z> pUniquePointer = AuNullHeapPointer<Z>()
|
|
||||||
|
|
||||||
template <class T, class Z = T, class ...Args>
|
|
||||||
AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> NewClassUnique(Args &&...args);
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> NewClassArray(AuUInt uElements, Args &&... fillCtr);
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr);
|
|
||||||
|
|
||||||
// note: callers can use AuHUPOf_t<T> pUniquePointer = AuNullHeapPointer<T>()
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr);
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr);
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
cstatic AuUPtr<T, decltype(&Heap::DeleteThat<T>)> NullUniquePointer();
|
|
||||||
|
|
||||||
template <class Z, class T>
|
|
||||||
cstatic AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> CastPointer(AuUPtr<T, decltype(&Heap::DeleteThat<T>)> &&pInPointer);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using HUPOf_t = AuUPtr<T, decltype(&Heap::DeleteThat<T>)>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
friend struct ProxyHeap;
|
|
||||||
friend struct HeapAccessor;
|
|
||||||
|
|
||||||
virtual AuSPtr<Heap> GetSelfReference() = 0; // may return empty/default. not all heaps are sharable.
|
|
||||||
virtual Heap *GetSelfReferenceRaw() = 0;
|
|
||||||
|
|
||||||
virtual AU_ALLOC void *_ZAlloc(Types::size_t uLength) = 0;
|
|
||||||
virtual AU_ALLOC void *_ZAlloc(Types::size_t uLength, Types::size_t uAlignment) = 0;
|
|
||||||
virtual AU_ALLOC void *_FAlloc(Types::size_t uLength) = 0;
|
|
||||||
virtual AU_ALLOC void *_FAlloc(Types::size_t uLength, Types::size_t uAlignment) = 0;
|
|
||||||
virtual AU_ALLOC void *_ZRealloc(void *pBase, Types::size_t uLength, Types::size_t uAlign) = 0;
|
|
||||||
virtual AU_ALLOC void *_ZRealloc(void *pBase, Types::size_t uLength) = 0;
|
|
||||||
virtual AU_ALLOC void *_FRealloc(void *pBase, Types::size_t uLength, Types::size_t uAlign) = 0;
|
|
||||||
virtual AU_ALLOC void *_FRealloc(void *pBase, Types::size_t uLength) = 0;
|
|
||||||
virtual void _Free(void* pBase) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HeapAccessor
|
|
||||||
{
|
|
||||||
cstatic AuSPtr<Heap> GetSelfReference(Heap *pHeap)
|
|
||||||
{
|
|
||||||
return pHeap->GetSelfReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
cstatic Heap *GetSelfReferenceRaw(Heap *pHeap)
|
|
||||||
{
|
|
||||||
return pHeap->GetSelfReferenceRaw();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HeapAdapterHandle
|
struct HeapAdapterHandle
|
||||||
{
|
{
|
||||||
|
@ -1,566 +1 @@
|
|||||||
/***
|
// Moved to ROXTL
|
||||||
Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: Heap.inl
|
|
||||||
Date: 2024-7-14
|
|
||||||
Date: 2021-6-9
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::Memory
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
T Heap::ZAlloc(Types::size_t uLength)
|
|
||||||
{
|
|
||||||
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZAlloc(uLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZAlloc(uLength, alignof(AuRemovePointer_t<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Heap::ZAlloc(Types::size_t uLength, Types::size_t uAlignment)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZAlloc(uLength, uAlignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T *Heap::ZAlloc()
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T *>(_ZAlloc(sizeof(T), alignof(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T *Heap::NewArray(Types::size_t uLength)
|
|
||||||
{
|
|
||||||
return ZAlloc<T *>(uLength * sizeof(T), alignof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T *Heap::NewArray(Types::size_t uLength, Types::size_t uAlignment)
|
|
||||||
{
|
|
||||||
return ZAlloc<T *>(uLength * sizeof(T), uAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Heap::FAlloc(Types::size_t uLength)
|
|
||||||
{
|
|
||||||
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FAlloc(uLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FAlloc(uLength, alignof(AuRemovePointer_t<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Heap::FAlloc(Types::size_t uLength, Types::size_t uAlignment)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FAlloc(uLength, uAlignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T *Heap::FAlloc()
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T *>(_FAlloc(sizeof(T), alignof(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reallocs
|
|
||||||
template<typename T>
|
|
||||||
T Heap::ZRealloc(T pHead, Types::size_t uLength)
|
|
||||||
{
|
|
||||||
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength, alignof(AuRemovePointer_t<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Heap::ZRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(pHead), uLength, uAlignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Heap::FRealloc(T pHead, Types::size_t uLength)
|
|
||||||
{
|
|
||||||
if constexpr (AuIsVoid_v<AuRemovePointer_t<T>>)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength, alignof(AuRemovePointer_t<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T Heap::FRealloc(T pHead, Types::size_t uLength, Types::size_t uAlignment)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T>(_FRealloc(reinterpret_cast<void *>(pHead), uLength, uAlignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free
|
|
||||||
template<typename T>
|
|
||||||
void Heap::Free(T pHead)
|
|
||||||
{
|
|
||||||
_Free(reinterpret_cast<void *>(pHead));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Heap::DeleteThat(T *pThat)
|
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyDestructible_v<T>)
|
|
||||||
{
|
|
||||||
pThat->~T();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &pHeap = *(Heap **)(((char *)pThat) - kAlignment);
|
|
||||||
pHeap->_Free(&pHeap);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Heap::DeleteThatArray(T *pThat)
|
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
|
||||||
|
|
||||||
auto pVoids = (void **)(((char *)pThat) - kAlignment);
|
|
||||||
auto pHeap = (Heap *)pVoids[0];
|
|
||||||
auto uLength = (AuUInt)pVoids[1];
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyDestructible_v<T>)
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uLength))
|
|
||||||
{
|
|
||||||
auto &refElement = pThat[i];
|
|
||||||
refElement.~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pHeap->_Free(pVoids);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Heap::DeleteThatArray2(T *pThat)
|
|
||||||
{
|
|
||||||
auto pBase = ((void **)pThat)[-1];
|
|
||||||
|
|
||||||
auto pVoids = (void **)pBase;
|
|
||||||
auto pHeap = (Heap *)pVoids[0];
|
|
||||||
auto uLength = (AuUInt)pVoids[1];
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyDestructible_v<T>)
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uLength))
|
|
||||||
{
|
|
||||||
auto &refElement = pThat[i];
|
|
||||||
refElement.~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pHeap->_Free(pVoids);
|
|
||||||
}
|
|
||||||
template <typename T, typename Z>
|
|
||||||
void Heap::DeleteThatCastedOnce(T *pThat)
|
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(Z), sizeof(void *));
|
|
||||||
|
|
||||||
auto pBaseClass = AuStaticCast<Z>(pThat);
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<Z> &&
|
|
||||||
!AuIsTriviallyDestructible_v<Z>)
|
|
||||||
{
|
|
||||||
pBaseClass->~Z();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &pHeap = *(Heap **)(((char *)pBaseClass) - kAlignment);
|
|
||||||
pHeap->_Free(&pHeap);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Heap::RetardedSpecWrittenByRetards(T *pThat)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> Heap::NewClass(Args &&...args)
|
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
pPtr = pThat->FAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
|
||||||
if (pPtr)
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment) T(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pPtr = pThat->ZAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
*(void **)pPtr = pThat;
|
|
||||||
|
|
||||||
auto pTThat = (T *)(pPtr + kAlignment);
|
|
||||||
AUROXTL_COMMODITY_TRY
|
|
||||||
{
|
|
||||||
return AuSPtr<T>(pTThat, &Heap::DeleteThat<T>, CppHeapWrapper<T> { this });
|
|
||||||
}
|
|
||||||
AUROXTL_COMMODITY_CATCH
|
|
||||||
{
|
|
||||||
Heap::DeleteThat<T>(pTThat);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class Z, class ...Args>
|
|
||||||
AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> Heap::NewClassUnique(Args &&...args)
|
|
||||||
{
|
|
||||||
static const auto kAlignment = AuMax(alignof(T), sizeof(void *));
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
pPtr = pThat->FAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
|
||||||
if (pPtr)
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment) T(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pPtr = pThat->ZAlloc<AuUInt8 *>(sizeof(T) + kAlignment, kAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<Z>);
|
|
||||||
}
|
|
||||||
|
|
||||||
*(void **)pPtr = pThat;
|
|
||||||
|
|
||||||
if constexpr (AuIsSame_v<T, Z>)
|
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThat<T>);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Heap::CastPointer<Z>(AuMove(AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThat<T>)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> Heap::NewClassArray(AuUInt uElements, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
if (!uElements)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uElements))
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(Args) != 0)
|
|
||||||
{
|
|
||||||
#if defined(AURT_HEAP_NO_STL)
|
|
||||||
static_assert(false);
|
|
||||||
#else
|
|
||||||
auto pElements = (T *)(pPtr + kAlignment);
|
|
||||||
std::fill(pElements, pElements + uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pVoids = (void **)pPtr;
|
|
||||||
pVoids[0] = pThat;
|
|
||||||
pVoids[1] = (void *)uElements;
|
|
||||||
|
|
||||||
auto pTThat = (T *)(pPtr + kAlignment);
|
|
||||||
AUROXTL_COMMODITY_TRY
|
|
||||||
{
|
|
||||||
return AuSPtr<T>(pTThat, &Heap::DeleteThatArray<T>, CppHeapWrapper<T> { this });
|
|
||||||
}
|
|
||||||
AUROXTL_COMMODITY_CATCH
|
|
||||||
{
|
|
||||||
Heap::DeleteThatArray<T>(pTThat);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> Heap::NewClassArray2(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 4);
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
if (!uElements)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uElements))
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(Args) != 0)
|
|
||||||
{
|
|
||||||
#if defined(AURT_HEAP_NO_STL)
|
|
||||||
static_assert(false);
|
|
||||||
#else
|
|
||||||
auto pElements = (T *)(pPtr + kAlignment);
|
|
||||||
std::fill(pElements, pElements + uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pVoids = (void **)pPtr;
|
|
||||||
pVoids[0] = pThat;
|
|
||||||
pVoids[1] = (void *)uElements;
|
|
||||||
((void **)(pPtr + kAlignment))[-1] = pPtr;
|
|
||||||
auto pTThat = (T *)(pPtr + kAlignment);
|
|
||||||
|
|
||||||
AUROXTL_COMMODITY_TRY
|
|
||||||
{
|
|
||||||
return AuSPtr<T>(pTThat, &Heap::DeleteThatArray2<T>, CppHeapWrapper<T> { this });
|
|
||||||
}
|
|
||||||
AUROXTL_COMMODITY_CATCH
|
|
||||||
{
|
|
||||||
Heap::DeleteThatArray2<T>(pTThat);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
const auto kAlignment = AuMax(alignof(T), sizeof(void *) * 2);
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
if (!uElements)
|
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uElements))
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(Args) != 0)
|
|
||||||
{
|
|
||||||
#if defined(AURT_HEAP_NO_STL)
|
|
||||||
static_assert(false);
|
|
||||||
#else
|
|
||||||
auto pElements = (T *)(pPtr + kAlignment);
|
|
||||||
std::fill(pElements, pElements + uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pVoids = (void **)pPtr;
|
|
||||||
pVoids[0] = pThat;
|
|
||||||
pVoids[1] = (void *)uElements;
|
|
||||||
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>((T *)(pPtr + kAlignment), &Heap::DeleteThatArray<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NewClassArray2Unique(AuUInt uElements, AuUInt uAlignment, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 4);
|
|
||||||
AuUInt8 *pPtr;
|
|
||||||
|
|
||||||
if (!uElements)
|
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pThat = this->GetSelfReferenceRaw();
|
|
||||||
if (!pThat)
|
|
||||||
{
|
|
||||||
pThat = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (AuIsClass_v<T> &&
|
|
||||||
!AuIsTriviallyConstructible_v<T, Args...>)
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->FAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
for (AU_ITERATE_N(i, uElements))
|
|
||||||
{
|
|
||||||
new (pPtr + kAlignment + (sizeof(T) * i)) T(AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bool(pPtr = pThat->ZAlloc<AuUInt8 *>((sizeof(T) * uElements) + kAlignment, kAlignment)))
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(Args) != 0)
|
|
||||||
{
|
|
||||||
#if defined(AURT_HEAP_NO_STL)
|
|
||||||
static_assert(false);
|
|
||||||
#else
|
|
||||||
auto pElements = (T *)(pPtr + kAlignment);
|
|
||||||
std::fill(pElements, pElements + uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPtr)
|
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pVoids = (void **)pPtr;
|
|
||||||
pVoids[0] = pThat;
|
|
||||||
pVoids[1] = (void *)uElements;
|
|
||||||
|
|
||||||
((void **)(pPtr + kAlignment))[-1] = pPtr;
|
|
||||||
auto pTThat = (T *)(pPtr + kAlignment);
|
|
||||||
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(pTThat, &Heap::DeleteThatArray2<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
AuUPtr<T, decltype(&Heap::DeleteThat<T>)> Heap::NullUniquePointer()
|
|
||||||
{
|
|
||||||
return AuUPtr<T, decltype(&Heap::DeleteThat<T>)>(nullptr, &Heap::RetardedSpecWrittenByRetards<T>);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Z, class T>
|
|
||||||
AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)> Heap::CastPointer(AuUPtr<T, decltype(&Heap::DeleteThat<T>)> &&pInPointer)
|
|
||||||
{
|
|
||||||
if (!pInPointer)
|
|
||||||
{
|
|
||||||
return NullUniquePointer<Z>();
|
|
||||||
}
|
|
||||||
else if (pInPointer.get_deleter() == &Heap::DeleteThat<T>)
|
|
||||||
{
|
|
||||||
return AuUPtr<Z, decltype(&Heap::DeleteThat<Z>)>(AuStaticCast<Z>(pInPointer.release()), &Heap::DeleteThatCastedOnce<Z, T>);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NullUniquePointer<Z>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
inline AuSPtr<AuUInt8> AllocateArray(Heap *pHeap, AuUInt uLength, AuUInt32 uAlignment)
|
|
||||||
{
|
|
||||||
return pHeap->NewClassArray2<AuUInt8>(uLength, uAlignment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,21 +4,11 @@
|
|||||||
File: HeapStats.hpp
|
File: HeapStats.hpp
|
||||||
Date: 2022-12-07
|
Date: 2022-12-07
|
||||||
Author: Reece
|
Author: Reece
|
||||||
|
Note: moved to ROXTL
|
||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Aurora::Memory
|
namespace Aurora::Memory
|
||||||
{
|
{
|
||||||
struct HeapStats
|
using HeapStats = AuHeapStats;
|
||||||
{
|
|
||||||
AuUInt uBytesAllocatedLifetime {};
|
|
||||||
AuUInt uBytesFreeLifetime {};
|
|
||||||
|
|
||||||
AuUInt uBytesCapacity {};
|
|
||||||
|
|
||||||
AuUInt uBytesLiveCounter {};
|
|
||||||
AuUInt uBytesPeakCounter {};
|
|
||||||
|
|
||||||
bool bIsSharedWithOtherHeaps {};
|
|
||||||
};
|
|
||||||
}
|
}
|
@ -23,8 +23,9 @@ namespace Aurora::Memory
|
|||||||
|
|
||||||
namespace __audetail
|
namespace __audetail
|
||||||
{
|
{
|
||||||
inline auto gDefaultDiscontiguousHeap = Aurora::Memory::GetDefaultDiscontiguousHeap();
|
#if 0
|
||||||
inline auto gDefaultDiscontiguousHeapShared = Aurora::Memory::GetDefaultDiscontiguousHeapShared();
|
inline auto gDefaultDiscontiguousHeapShared = Aurora::Memory::GetDefaultDiscontiguousHeapShared();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Cache.hpp"
|
#include "Cache.hpp"
|
||||||
|
@ -4,717 +4,14 @@
|
|||||||
File: MemoryView.hpp
|
File: MemoryView.hpp
|
||||||
Date: 2021-9-14
|
Date: 2021-9-14
|
||||||
Author: Reece
|
Author: Reece
|
||||||
|
Notes: Moved to ROXTL
|
||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Aurora::Memory
|
namespace Aurora::Memory
|
||||||
{
|
{
|
||||||
struct Heap;
|
using MemoryViewRead = AuMemoryView<true>;
|
||||||
|
using MemoryViewWrite = AuMemoryView<false>;
|
||||||
namespace detail
|
using MemoryViewStreamRead = AuMemoryViewStream<true>;
|
||||||
{
|
using MemoryViewStreamWrite = AuMemoryViewStream<false>;
|
||||||
inline AuSPtr<AuUInt8> AllocateArray(Heap *pHeap, AuUInt uLength, AuUInt32 uAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MemoryControlBlock
|
|
||||||
{
|
|
||||||
// Free-after-use mitigator: ensures a non-zero flag is kept whilst other memory views are present
|
|
||||||
// This helps mitigate:
|
|
||||||
// -> Take view from object
|
|
||||||
// -> Make view shared
|
|
||||||
// -> Pass off shared view to another subsystem
|
|
||||||
// -> Use the aforementioned object to resize, release, or do something bad with the memory pointed to by the initial view
|
|
||||||
// Mitgation: SysAssert(!pObject->uInUse)
|
|
||||||
AuAUInt32 *pInUseCounter {};
|
|
||||||
|
|
||||||
// Mitigation (cont) and reducing code reuse:
|
|
||||||
// -> Allow for [shared!] memory views to have a shared freestanding owner
|
|
||||||
// -> Ensure reference counters or other forms of memory management don't free the owner before us
|
|
||||||
// (Consider inverse construction order, for instance, we'd have to always call MemoryView::ResetControlBlock()
|
|
||||||
// in a derived subclass, in order release the pInUseCounter reference before the derived shared members get released)
|
|
||||||
AuSPtr<void> pPinner; // WARNING: as usual, std types don't validate their allocator, and our shared ptrs can be different between binaries!
|
|
||||||
|
|
||||||
~MemoryControlBlock()
|
|
||||||
{
|
|
||||||
this->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Release()
|
|
||||||
{
|
|
||||||
if (auto pCounter = AuExchange(this->pInUseCounter, nullptr))
|
|
||||||
{
|
|
||||||
AuAtomicSub(pCounter, 1u);
|
|
||||||
}
|
|
||||||
|
|
||||||
AuResetMember(this->pPinner);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<bool Readonly_b>
|
|
||||||
struct MemoryView
|
|
||||||
{
|
|
||||||
using U8_t = AuConditional_t<Readonly_b, const AuUInt8 *, AuUInt8 *>;
|
|
||||||
using Void_t = AuConditional_t<Readonly_b, const void *, void *>;
|
|
||||||
|
|
||||||
template<typename T, int Z>
|
|
||||||
using StdArray_t = AuConditional_t<Readonly_b, const AuArray<T, Z>, AuArray<T, Z>>;
|
|
||||||
|
|
||||||
/*
|
|
||||||
MethodName(MemoryView(tempstring/array/etc)) should be legal, right?
|
|
||||||
|
|
||||||
Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created.
|
|
||||||
|
|
||||||
A full-expression is:
|
|
||||||
[...]
|
|
||||||
* an expression that is not a subexpression of another expression and that is not otherwise part of a full-expression.
|
|
||||||
---------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
MemoryView()
|
|
||||||
{
|
|
||||||
this->ptr = nullptr;
|
|
||||||
this->length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, AU_TEMPLATE_ENABLE_WHEN(AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, T>::value)>
|
|
||||||
MemoryView(T &list)
|
|
||||||
{
|
|
||||||
this->ptr = list.data();
|
|
||||||
this->length = list.size() * sizeof(typename T::value_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView(const AuROString &str)
|
|
||||||
{
|
|
||||||
this->ptr = str.data();
|
|
||||||
this->length = str.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView(const AuRONString &str)
|
|
||||||
{
|
|
||||||
this->ptr = str.data();
|
|
||||||
this->length = str.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView(const AuString &str)
|
|
||||||
{
|
|
||||||
this->ptr = str.data();
|
|
||||||
this->length = str.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView(const MemoryView &view)
|
|
||||||
{
|
|
||||||
this->ptr = view.ptr;
|
|
||||||
this->length = view.length;
|
|
||||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
|
||||||
if (this->controlBlock.pInUseCounter)
|
|
||||||
{
|
|
||||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
|
||||||
}
|
|
||||||
this->controlBlock.pPinner = view.controlBlock.pPinner;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView(const MemoryView &view, const AuSPtr<void> &pThat)
|
|
||||||
{
|
|
||||||
this->ptr = view.ptr;
|
|
||||||
this->length = view.length;
|
|
||||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
|
||||||
if (this->controlBlock.pInUseCounter)
|
|
||||||
{
|
|
||||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
|
||||||
}
|
|
||||||
if (view.controlBlock.pPinner)
|
|
||||||
{
|
|
||||||
auto pThat2 = AuMakeSharedArray<AuSPtr<void>>(2);
|
|
||||||
this->controlBlock.pPinner = pThat2;
|
|
||||||
if (!this->controlBlock.pPinner)
|
|
||||||
{
|
|
||||||
AuMemoryPanic("OOM");
|
|
||||||
}
|
|
||||||
pThat2.get()[0] = pThat;
|
|
||||||
pThat2.get()[1] = view.controlBlock.pPinner;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->controlBlock.pPinner = pThat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView(MemoryView &&view)
|
|
||||||
{
|
|
||||||
this->ptr = view.ptr;
|
|
||||||
this->length = view.length;
|
|
||||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
|
||||||
this->controlBlock.pPinner = AuMove(view.controlBlock.pPinner);
|
|
||||||
view.controlBlock.pInUseCounter = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, int Z>
|
|
||||||
constexpr MemoryView(T(&a)[Z])
|
|
||||||
{
|
|
||||||
this->ptr = &a[0];
|
|
||||||
this->length = Z * sizeof(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, int Z>
|
|
||||||
constexpr MemoryView(AuArray<T, Z> &view)
|
|
||||||
{
|
|
||||||
this->ptr = view.begin();
|
|
||||||
this->length = Z * sizeof(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryView(T *start, T *end)
|
|
||||||
{
|
|
||||||
this->ptr = start;
|
|
||||||
if constexpr (AuIsSame_v<T, Void_t>)
|
|
||||||
{
|
|
||||||
this->length = reinterpret_cast<const AuUInt8 *>(end) - reinterpret_cast<const AuUInt8 *>(start);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->length = (end - start) * sizeof(T);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryView(T *start, T *end, AuAUInt32 *pInUseCounter)
|
|
||||||
{
|
|
||||||
this->ptr = start;
|
|
||||||
if constexpr (AuIsSame_v<T, Void_t>)
|
|
||||||
{
|
|
||||||
this->length = reinterpret_cast<const AuUInt8 *>(end) - reinterpret_cast<const AuUInt8 *>(start);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->length = (end - start) * sizeof(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->controlBlock.pInUseCounter = pInUseCounter;
|
|
||||||
AuAtomicAdd(pInUseCounter, 1u);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryView(T *start, T *end, AuAUInt32 *pInUseCounter, const AuSPtr<void> &pRAIIOwner)
|
|
||||||
{
|
|
||||||
this->ptr = start;
|
|
||||||
if constexpr (AuIsSame_v<T, Void_t>)
|
|
||||||
{
|
|
||||||
this->length = reinterpret_cast<const AuUInt8 *>(end) - reinterpret_cast<const AuUInt8 *>(start);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->length = (end - start) * sizeof(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->controlBlock.pInUseCounter = pInUseCounter;
|
|
||||||
AuAtomicAdd(pInUseCounter, 1u);
|
|
||||||
this->controlBlock.pPinner = pRAIIOwner;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryView(T *start, AuUInt length) // WARNING: length != count
|
|
||||||
// where T = whogivesafuck
|
|
||||||
{
|
|
||||||
this->ptr = start;
|
|
||||||
this->length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryView(T *start, AuUInt length, AuAUInt32 *pInUseCounter) // WARNING: length != count
|
|
||||||
{
|
|
||||||
this->ptr = start;
|
|
||||||
this->length = length;
|
|
||||||
this->controlBlock.pInUseCounter = pInUseCounter;
|
|
||||||
AuAtomicAdd(pInUseCounter, 1u);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryView(T *start, AuUInt length, AuAUInt32 *pInUseCounter, const AuSPtr<void> &pRAIIOwner) // WARNING: length != count
|
|
||||||
{
|
|
||||||
this->ptr = start;
|
|
||||||
this->length = length;
|
|
||||||
this->controlBlock.pInUseCounter = pInUseCounter;
|
|
||||||
AuAtomicAdd(pInUseCounter, 1u);
|
|
||||||
this->controlBlock.pPinner = pRAIIOwner;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename T>
|
|
||||||
MemoryView(T *start, AuUInt length, const MemoryControlBlock ©Block)
|
|
||||||
{
|
|
||||||
this->ptr = start;
|
|
||||||
this->length = length;
|
|
||||||
this->controlBlock = copyBlock;
|
|
||||||
if (this->controlBlock.pInUseCounter)
|
|
||||||
{
|
|
||||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
|
|
||||||
MemoryView &operator =(MemoryView &&view)
|
|
||||||
{
|
|
||||||
this->ptr = view.ptr;
|
|
||||||
this->length = view.length;
|
|
||||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
|
||||||
view.controlBlock.pInUseCounter = nullptr;
|
|
||||||
this->controlBlock.pPinner = AuMove(view.controlBlock.pPinner);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView &operator =(const MemoryView &view)
|
|
||||||
{
|
|
||||||
this->ptr = view.ptr;
|
|
||||||
this->length = view.length;
|
|
||||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
|
||||||
if (this->controlBlock.pInUseCounter)
|
|
||||||
{
|
|
||||||
AuAtomicAdd(this->controlBlock.pInUseCounter, 1u);
|
|
||||||
}
|
|
||||||
this->controlBlock.pPinner = view.controlBlock.pPinner;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt ToPointerValue() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<const AuUInt>(this->ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt ToLength() const
|
|
||||||
{
|
|
||||||
return this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt Length() const
|
|
||||||
{
|
|
||||||
return this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt ToSize() const
|
|
||||||
{
|
|
||||||
return this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt Size() const
|
|
||||||
{
|
|
||||||
return this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T = AuUInt8>
|
|
||||||
AuUInt ToCount() const
|
|
||||||
{
|
|
||||||
return this->length / sizeof(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
AuConditional_t<Readonly_b, const T *, T *> Begin() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<AuConditional_t<Readonly_b, const T *, T *>>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
AuConditional_t<Readonly_b, const T*, T*> End() const
|
|
||||||
{
|
|
||||||
return Begin<T>() + ToCount<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasMemory() const
|
|
||||||
{
|
|
||||||
return this->ptr && this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const
|
|
||||||
{
|
|
||||||
return this->HasMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
U8_t ToPointer() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<U8_t>(this->ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
U8_t begin() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<U8_t>(this->ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
U8_t end() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<U8_t>(this->ptr) + this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
U8_t Begin() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<U8_t>(this->ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
U8_t End() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<U8_t>(this->ptr) + this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt size() const
|
|
||||||
{
|
|
||||||
return this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView AtOffset(AuUInt uOffset) const
|
|
||||||
{
|
|
||||||
if (uOffset < this->uLength)
|
|
||||||
{
|
|
||||||
return MemoryView((AuUInt8 *)this->pBase + uOffset,
|
|
||||||
this->uLength - uOffset,
|
|
||||||
this->controlBlock);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView Take(AuUInt uLength) const
|
|
||||||
{
|
|
||||||
if (uLength <= this->uLength)
|
|
||||||
{
|
|
||||||
return MemoryView((AuUInt8 *)this->pBase,
|
|
||||||
uLength,
|
|
||||||
this->controlBlock);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView Clone() const
|
|
||||||
{
|
|
||||||
auto uLength = this->uLength;
|
|
||||||
auto pData = AuMakeSharedArray<AuUInt8>(uLength);
|
|
||||||
if (!pData)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
AuMemcpy(pData.get(), this->pBase, uLength);
|
|
||||||
return MemoryView(MemoryView(pData.get(), uLength), pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryView Clone(Heap *pHeap, AuUInt32 uAlignment = alignof(double)) const
|
|
||||||
{
|
|
||||||
auto uLength = this->uLength;
|
|
||||||
auto pData = detail::AllocateArray(pHeap, uLength, uAlignment);
|
|
||||||
if (!pData)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
AuMemcpy(pData.get(), this->pBase, uLength);
|
|
||||||
return MemoryView(MemoryView(pData.get(), uLength), pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TryCloneSelf(bool bResetOnFailure = true)
|
|
||||||
{
|
|
||||||
auto replacement = Clone();
|
|
||||||
if (!replacement)
|
|
||||||
{
|
|
||||||
if (bResetOnFailure)
|
|
||||||
{
|
|
||||||
AuResetMember(*this);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
AuResetMember(*this, replacement);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
Void_t /*const*/ ptr;
|
|
||||||
Void_t /*const*/ pBase;
|
|
||||||
};
|
|
||||||
union
|
|
||||||
{
|
|
||||||
AuUInt /*const*/ length;
|
|
||||||
AuUInt /*const*/ uLength;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
MemoryControlBlock controlBlock;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool HasControlBlock() const
|
|
||||||
{
|
|
||||||
return this->controlBlock.pInUseCounter ||
|
|
||||||
this->controlBlock.pPinner;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuSPtr<MemoryView> TryPromoteToSharedView(AuSPtr<void> pParent = {}) const
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
bool bHasControlBlock = this->HasControlBlock();
|
|
||||||
|
|
||||||
if (bHasControlBlock)
|
|
||||||
{
|
|
||||||
if (pParent)
|
|
||||||
{
|
|
||||||
return AuMakeShared<MemoryView>(*this, pParent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return AuMakeShared<MemoryView>(*this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pParent)
|
|
||||||
{
|
|
||||||
return AuMakeShared<MemoryView>(*this, pParent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (pParent)
|
|
||||||
{
|
|
||||||
return AuMakeShared<MemoryView>(*this, pParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->HasControlBlock())
|
|
||||||
{
|
|
||||||
return AuMakeShared<MemoryView>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
AuSPtr<MemoryView> TryPromoteToSharedViewNoParentNesting(AuSPtr<void> pParent = {}) const
|
|
||||||
{
|
|
||||||
if (this->HasControlBlock())
|
|
||||||
{
|
|
||||||
return AuMakeShared<MemoryView>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pParent)
|
|
||||||
{
|
|
||||||
return AuMakeShared<MemoryView>(*this, pParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TryDemoteFromSharedView(const AuSPtr<MemoryView> &pCopy)
|
|
||||||
{
|
|
||||||
if (pCopy && pCopy->HasControlBlock())
|
|
||||||
{
|
|
||||||
AuResetMember(*this, AuConstReference(*pCopy.get()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TryDemoteFromReference(const MemoryView &refCopy)
|
|
||||||
{
|
|
||||||
if (refCopy.HasControlBlock())
|
|
||||||
{
|
|
||||||
AuResetMember(*this, refCopy);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DemoteFromSharedView(const AuSPtr<MemoryView> &pCopy)
|
|
||||||
{
|
|
||||||
if (!pCopy)
|
|
||||||
{
|
|
||||||
AuResetMember(*this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pCopy->HasControlBlock())
|
|
||||||
{
|
|
||||||
AuResetMember(*this, AuConstReference(*pCopy.get()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AuResetMember(*this, AuConstReference(*pCopy.get()), pCopy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AuSPtr<void> ToSharedControlBlock(bool *pbFailed = nullptr)
|
|
||||||
{
|
|
||||||
if (pbFailed)
|
|
||||||
{
|
|
||||||
*pbFailed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->controlBlock.pInUseCounter)
|
|
||||||
{
|
|
||||||
auto pShared = AuMakeShared<MemoryControlBlock>();
|
|
||||||
if (!pShared)
|
|
||||||
{
|
|
||||||
if (pbFailed)
|
|
||||||
{
|
|
||||||
*pbFailed = true;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
AuAtomicAdd(&this->controlBlock.pInUseCounter, 1u);
|
|
||||||
pShared->pInUseCounter = this->controlBlock.pInUseCounter;
|
|
||||||
pShared->pPinner = this->controlBlock.pPinner;
|
|
||||||
return pShared;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->controlBlock.pPinner)
|
|
||||||
{
|
|
||||||
return this->controlBlock.pPinner;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt CopyInto(const MemoryView<false> &write) const
|
|
||||||
{
|
|
||||||
auto uLength = AuMin(this->uLength, write.uLength);
|
|
||||||
AuMemcpy(write.pBase, this->pBase, uLength);
|
|
||||||
return uLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool bThat = Readonly_b, AU_TEMPLATE_ENABLE_WHEN(!bThat)>
|
|
||||||
AuUInt CopyFrom(const MemoryView<true> &read) const
|
|
||||||
{
|
|
||||||
auto uLength = AuMin(this->uLength, read.uLength);
|
|
||||||
AuMemcpy(this->pBase, read.pBase, uLength);
|
|
||||||
return uLength;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using MemoryViewRead = MemoryView<true>;
|
|
||||||
using MemoryViewWrite = MemoryView<false>;
|
|
||||||
|
|
||||||
template<bool Readonly_b>
|
|
||||||
struct MemoryViewStream : MemoryView<Readonly_b>
|
|
||||||
{
|
|
||||||
template<typename T, AU_TEMPLATE_ENABLE_WHEN(AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, T>::value)>
|
|
||||||
constexpr MemoryViewStream(T &list, AuUInt &length) : MemoryView<Readonly_b>(list), outVariable(length)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr MemoryViewStream(const AuString &str, AuUInt &length) : MemoryView<Readonly_b>(str), outVariable(length)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryViewStream(T *start, T *end, AuUInt &length) : MemoryView<Readonly_b>(start, end), outVariable(length)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryViewStream(T *start, AuUInt &length) : MemoryView<Readonly_b>(start, length), outVariable(length)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, int Z>
|
|
||||||
constexpr MemoryViewStream(AuArray<T, Z> &view,
|
|
||||||
AuUInt &length) :
|
|
||||||
MemoryView<Readonly_b>(view),
|
|
||||||
outVariable(length)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename AuEnableIf<AuIsBaseOfTemplate<AURORA_RUNTIME_AU_LIST, T>::value>::type* = nullptr>
|
|
||||||
constexpr MemoryViewStream(T &list) : MemoryView<Readonly_b>(list), outVariable(unused)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr MemoryViewStream(const AuString &str) :
|
|
||||||
MemoryView<Readonly_b>(str),
|
|
||||||
outVariable(unused)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr MemoryViewStream(const AuROString &str) :
|
|
||||||
MemoryView<Readonly_b>(str),
|
|
||||||
outVariable(unused)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr MemoryViewStream(const AuRONString &str) :
|
|
||||||
MemoryView<Readonly_b>(str),
|
|
||||||
outVariable(unused)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr MemoryViewStream(T *start, T *end) : MemoryView<Readonly_b>(start, end), outVariable(unused)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr MemoryViewStream(MemoryView<Readonly_b> in) : MemoryView<Readonly_b>(in.ptr, in.length), outVariable(unused)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr MemoryViewStream(MemoryView<Readonly_b> in, AuUInt &len) : MemoryView<Readonly_b>(in.ptr, in.length), outVariable(len)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, int Z>
|
|
||||||
constexpr MemoryViewStream(T(&a)[Z]) : MemoryView<Readonly_b>(a), outVariable(unused)
|
|
||||||
{
|
|
||||||
outVariable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasMemory() const
|
|
||||||
{
|
|
||||||
return this->ptr && this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const
|
|
||||||
{
|
|
||||||
return HasMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CopyStreamInto(const MemoryView<false> &write) const
|
|
||||||
{
|
|
||||||
auto uLength = AuMin(this->uLength, write.uLength);
|
|
||||||
AuMemcpy(write.pBase, this->pBase, uLength);
|
|
||||||
this->outVariable = uLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool bThat = Readonly_b, AU_TEMPLATE_ENABLE_WHEN(!bThat)>
|
|
||||||
void CopyStreamFrom(const MemoryView<true> &read) const
|
|
||||||
{
|
|
||||||
auto uLength = AuMin(this->uLength, read.uLength);
|
|
||||||
AuMemcpy(this->pBase, read.pBase, uLength);
|
|
||||||
this->outVariable = uLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
AuUInt &outVariable;
|
|
||||||
private:
|
|
||||||
AuUInt unused;
|
|
||||||
};
|
|
||||||
|
|
||||||
using MemoryViewStreamRead = MemoryViewStream<true>;
|
|
||||||
using MemoryViewStreamWrite = MemoryViewStream<false>;
|
|
||||||
}
|
}
|
@ -61,11 +61,6 @@ using AuWorkerID = AuAsync::WorkerPId_t;
|
|||||||
|
|
||||||
using AuByteBuffer = AuMemory::ByteBuffer;
|
using AuByteBuffer = AuMemory::ByteBuffer;
|
||||||
|
|
||||||
using AuMemoryViewRead = AuMemory::MemoryViewRead;
|
|
||||||
using AuMemoryViewWrite = AuMemory::MemoryViewWrite;
|
|
||||||
using AuMemoryViewStreamRead = AuMemory::MemoryViewStreamRead;
|
|
||||||
using AuMemoryViewStreamWrite = AuMemory::MemoryViewStreamWrite;
|
|
||||||
|
|
||||||
#if defined(AURORA_RUNTIME_BAD_PLATFORM_FORCE_FUTEX_MUTEX_SEMAPHORE_IN_CLIENT)
|
#if defined(AURORA_RUNTIME_BAD_PLATFORM_FORCE_FUTEX_MUTEX_SEMAPHORE_IN_CLIENT)
|
||||||
using AuMutex = AuThreading::Waitables::FutexWaitable;
|
using AuMutex = AuThreading::Waitables::FutexWaitable;
|
||||||
using AuSemaphore = AuThreading::Waitables::FutexSemaphoreWaitable;
|
using AuSemaphore = AuThreading::Waitables::FutexSemaphoreWaitable;
|
||||||
@ -127,103 +122,6 @@ static inline void AuDebugBreak()
|
|||||||
AuDebug::DebugBreak();
|
AuDebug::DebugBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using AuHUPOf_t = typename Aurora::Memory::Heap::HUPOf_t<T>;
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
auto AuNullHeapPointer()
|
|
||||||
{
|
|
||||||
return Aurora::Memory::Heap::NullUniquePointer<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
auto AuNullPointer()
|
|
||||||
{
|
|
||||||
return Aurora::Memory::Heap::NullUniquePointer<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuHUPOf_t<T> AuNewClassArrayUnique(AuUInt uElements, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
return __audetail::gDefaultDiscontiguousHeap->NewClassArrayUnique<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> AuNewClassArray(AuUInt uElements, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
return __audetail::gDefaultDiscontiguousHeap->NewClassArray<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class Z = T, class ...Args>
|
|
||||||
AuHUPOf_t<Z> AuNewClassUnique(Args &&...args)
|
|
||||||
{
|
|
||||||
return __audetail::gDefaultDiscontiguousHeap->NewClassUnique<T, Z, Args...>(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> AuNewClass(Args &&...args)
|
|
||||||
{
|
|
||||||
#if !defined(AURORA_RUNTIME_HEADERS_ALWAYS_LOOKUP_HEAP)
|
|
||||||
return AuMakeShared<T, Args...>(AuForward<Args>(args)...);
|
|
||||||
#else
|
|
||||||
return Aurora::Memory::GetDefaultDiscontiguousHeap()->NewClass<T, Args...>(AuForward<Args>(args)...);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuHUPOf_t<T> AuNewClassArrayUnique(Aurora::Memory::Heap *pHeap, AuUInt uElements, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
return pHeap->NewClassArrayUnique<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> AuNewClassArray(Aurora::Memory::Heap *pHeap, AuUInt uElements, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
return pHeap->NewClassArray<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuHUPOf_t<T> AuNewClassUnique(Aurora::Memory::Heap *pHeap, Args &&...args)
|
|
||||||
{
|
|
||||||
return pHeap->NewClassUnique<T, Args...>(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> AuNewClass(Aurora::Memory::Heap *pHeap, Args &&...args)
|
|
||||||
{
|
|
||||||
return pHeap->NewClass<T, Args...>(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuHUPOf_t<T> AuNewClassArrayUnique(const AuSPtr<Aurora::Memory::Heap> &pHeap, AuUInt uElements, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
return pHeap->NewClassArrayUnique<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> AuNewClassArray(const AuSPtr<Aurora::Memory::Heap> &pHeap, AuUInt uElements, Args &&... fillCtr)
|
|
||||||
{
|
|
||||||
return pHeap->NewClassArray<T, Args...>(uElements, AuForward<Args>(fillCtr)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class Z = T, class ...Args>
|
|
||||||
AuHUPOf_t<Z> AuNewClassUnique(const AuSPtr<Aurora::Memory::Heap> &pHeap, Args &&...args)
|
|
||||||
{
|
|
||||||
return pHeap->NewClassUnique<T, Z, Args...>(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class ...Args>
|
|
||||||
AuSPtr<T> AuNewClass(const AuSPtr<Aurora::Memory::Heap> &pHeap, Args &&...args)
|
|
||||||
{
|
|
||||||
return pHeap->NewClass<T, Args...>(AuForward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Z, class T>
|
|
||||||
AuHUPOf_t<Z> AuCastPointer(AuHUPOf_t<T> &&pInPointer)
|
|
||||||
{
|
|
||||||
return Aurora::Memory::Heap::CastPointer<Z>(AuMove(pInPointer));
|
|
||||||
}
|
|
||||||
|
|
||||||
static AuSPtr<AuMemory::SharableByteBuffer> AuNewSharableBuffer(AuUInt32 length = 0)
|
static AuSPtr<AuMemory::SharableByteBuffer> AuNewSharableBuffer(AuUInt32 length = 0)
|
||||||
{
|
{
|
||||||
return AuMove(AuMemory::NewSharableBuffer(length));
|
return AuMove(AuMemory::NewSharableBuffer(length));
|
||||||
|
@ -1269,7 +1269,7 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
if (this->pHeap)
|
if (this->pHeap)
|
||||||
{
|
{
|
||||||
AuResetMember(pThreadState->pendingWorkItems, AuMemory::PmrCppHeapWrapper<WorkEntry_t>());
|
AuSetAllocator(pThreadState->pendingWorkItems, this->pHeap.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!create)
|
if (!create)
|
||||||
|
Loading…
Reference in New Issue
Block a user