[-] AuMemoryView

[-] AuMemory::Heap
[*] Use AuSetAllocator
[-] AuMemory::PmrCppHeapWrapper
This commit is contained in:
Reece Wilson 2024-09-13 08:48:33 +01:00
parent b80bb7fc77
commit 9acc56431a
8 changed files with 17 additions and 1810 deletions

View File

@ -4,6 +4,7 @@
File: CppHeapWrapper.hpp
Date: 2023-12-22
Author: Reece
Note: use AuPMRAllocator instead
***/
#pragma once
@ -21,258 +22,8 @@ namespace Aurora::Memory
};
}
template <class T>
struct PmrCppHeapWrapper
{
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;
};
/// @deprecated use ROXTL AuPMRAllocator instead
/// Some legacy code treats the container as the handle, such that .get_allocator() still returns a reference.
template <class T>
struct CppHeapWrapper
{
@ -520,7 +271,7 @@ namespace Aurora::Memory
#if defined(AU_NO_COMPRESS_CPPHEAP_WRAPPER)
return this->pHeap = __audetail::gDefaultDiscontiguousHeap;
#else
return (this->spHeap = __audetail::gDefaultDiscontiguousHeapShared).get();
return (this->spHeap = AuUnsafeRaiiToShared(__audetail::gDefaultDiscontiguousHeap)).get();
#endif
}
@ -595,22 +346,9 @@ inline bool operator==(const Aurora::Memory::CppHeapWrapper<T> &lhs,
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>
inline bool operator!=(const Aurora::Memory::CppHeapWrapper<T> &lhs,
const Aurora::Memory::CppHeapWrapper<Z> &rhs) noexcept
{
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();
}

View File

@ -13,160 +13,8 @@ namespace Aurora::Memory
static const AuUInt8 kHeapSize = 128;
static const AuUInt8 kHeap2Size = 255;
template <class T>
struct CppHeapWrapper;
/**
* 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();
}
};
using HeapAccessor = AuHeapAccessor;
using Heap = AuHeap;
struct HeapAdapterHandle
{

View File

@ -1,566 +1 @@
/***
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);
}
}
}
// Moved to ROXTL

View File

@ -4,21 +4,11 @@
File: HeapStats.hpp
Date: 2022-12-07
Author: Reece
Note: moved to ROXTL
***/
#pragma once
namespace Aurora::Memory
{
struct HeapStats
{
AuUInt uBytesAllocatedLifetime {};
AuUInt uBytesFreeLifetime {};
AuUInt uBytesCapacity {};
AuUInt uBytesLiveCounter {};
AuUInt uBytesPeakCounter {};
bool bIsSharedWithOtherHeaps {};
};
using HeapStats = AuHeapStats;
}

View File

@ -23,8 +23,9 @@ namespace Aurora::Memory
namespace __audetail
{
inline auto gDefaultDiscontiguousHeap = Aurora::Memory::GetDefaultDiscontiguousHeap();
#if 0
inline auto gDefaultDiscontiguousHeapShared = Aurora::Memory::GetDefaultDiscontiguousHeapShared();
#endif
}
#include "Cache.hpp"

View File

@ -4,717 +4,14 @@
File: MemoryView.hpp
Date: 2021-9-14
Author: Reece
Notes: Moved to ROXTL
***/
#pragma once
namespace Aurora::Memory
{
struct Heap;
namespace detail
{
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 &copyBlock)
{
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>;
using MemoryViewRead = AuMemoryView<true>;
using MemoryViewWrite = AuMemoryView<false>;
using MemoryViewStreamRead = AuMemoryViewStream<true>;
using MemoryViewStreamWrite = AuMemoryViewStream<false>;
}

View File

@ -61,11 +61,6 @@ using AuWorkerID = AuAsync::WorkerPId_t;
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)
using AuMutex = AuThreading::Waitables::FutexWaitable;
using AuSemaphore = AuThreading::Waitables::FutexSemaphoreWaitable;
@ -127,103 +122,6 @@ static inline void AuDebugBreak()
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)
{
return AuMove(AuMemory::NewSharableBuffer(length));

View File

@ -1269,7 +1269,7 @@ namespace Aurora::Async
if (this->pHeap)
{
AuResetMember(pThreadState->pendingWorkItems, AuMemory::PmrCppHeapWrapper<WorkEntry_t>());
AuSetAllocator(pThreadState->pendingWorkItems, this->pHeap.get());
}
if (!create)