[*] Harden AuByteBuffer
[+] Alias: AuNewSharableBuffer [+] Alias: AuNewSharableResizableBuffer [+] Alias: AuNewRingBuffer [+] Alias: AuNewResizableBuffer
This commit is contained in:
parent
9a846a6d2f
commit
c935b892c7
@ -79,6 +79,7 @@ namespace Aurora::Memory
|
||||
// - implicit padding
|
||||
AuUInt8 scaleSize {};//
|
||||
AuUInt8 alignment {};
|
||||
AuAUInt32 uInUseCounter { 0 };
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@ -644,21 +645,70 @@ namespace Aurora::Memory
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryViewRead readView;
|
||||
MemoryViewWrite writeView;
|
||||
|
||||
public:
|
||||
inline AuSPtr<MemoryViewWrite> ToSharedWriteView()
|
||||
{
|
||||
this->writeView = *this;
|
||||
return { this->SharedFromThis(), &this->writeView };
|
||||
MemoryViewWrite view = *this;
|
||||
struct View : MemoryViewWrite
|
||||
{
|
||||
View(MemoryViewWrite &&in) : MemoryViewWrite(in)
|
||||
{ }
|
||||
|
||||
~View()
|
||||
{
|
||||
this->ResetControlBlock();
|
||||
AuResetMember(this->pin);
|
||||
}
|
||||
|
||||
AuSPtr<void> pin;
|
||||
};
|
||||
|
||||
if (!view)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto pView = AuMakeShared<View>(AuMove(view)))
|
||||
{
|
||||
pView->pin = AuSharedFromThis();
|
||||
return pView;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
inline AuSPtr<MemoryViewRead> ToSharedReadView()
|
||||
{
|
||||
this->readView = *this;
|
||||
return { this->SharedFromThis(), &this->readView };
|
||||
MemoryViewRead view = *this;
|
||||
struct View : MemoryViewRead
|
||||
{
|
||||
View(MemoryViewRead &&in) : MemoryViewRead(in)
|
||||
{ }
|
||||
|
||||
~View()
|
||||
{
|
||||
this->ResetControlBlock();
|
||||
AuResetMember(this->pin);
|
||||
}
|
||||
|
||||
AuSPtr<void> pin;
|
||||
};
|
||||
|
||||
if (!view)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto pView = AuMakeShared<View>(AuMove(view)))
|
||||
{
|
||||
pView->pin = AuSharedFromThis();
|
||||
return pView;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
inline operator AuSPtr<MemoryViewWrite>()
|
||||
@ -672,7 +722,6 @@ namespace Aurora::Memory
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static ByteBuffer NewResizableBuffer(AuUInt32 length = 0)
|
||||
{
|
||||
return ByteBuffer(length, false, true);
|
||||
|
@ -12,7 +12,8 @@ namespace Aurora::Memory
|
||||
bool ByteBuffer::Allocate(AuUInt length)
|
||||
{
|
||||
if (this->flagNoFree ||
|
||||
this->flagNoRealloc)
|
||||
this->flagNoRealloc ||
|
||||
this->uInUseCounter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -55,7 +56,8 @@ namespace Aurora::Memory
|
||||
bool ByteBuffer::Allocate(AuUInt length, AuUInt alignment)
|
||||
{
|
||||
if (this->flagNoFree ||
|
||||
this->flagNoRealloc)
|
||||
this->flagNoRealloc ||
|
||||
this->uInUseCounter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -92,7 +94,8 @@ namespace Aurora::Memory
|
||||
bool ByteBuffer::SetBuffer(MemoryViewRead readView, bool bMoveWriteHeadForReaders)
|
||||
{
|
||||
if (this->flagNoFree ||
|
||||
this->flagNoRealloc)
|
||||
this->flagNoRealloc ||
|
||||
this->uInUseCounter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -120,6 +123,11 @@ namespace Aurora::Memory
|
||||
|
||||
void ByteBuffer::Reset()
|
||||
{
|
||||
if (this->uInUseCounter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->base && !this->flagNoFree)
|
||||
{
|
||||
Free(this->base);
|
||||
@ -148,7 +156,8 @@ namespace Aurora::Memory
|
||||
void ByteBuffer::GC()
|
||||
{
|
||||
if (this->flagNoFree ||
|
||||
this->flagNoRealloc)
|
||||
this->flagNoRealloc ||
|
||||
this->uInUseCounter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -206,7 +215,8 @@ namespace Aurora::Memory
|
||||
bool ByteBuffer::Resize(AuUInt length)
|
||||
{
|
||||
if (this->flagNoFree ||
|
||||
this->flagNoRealloc)
|
||||
this->flagNoRealloc ||
|
||||
this->uInUseCounter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ namespace Aurora::Memory
|
||||
return {};
|
||||
}
|
||||
|
||||
return MemoryViewRead(pBase, uCount);
|
||||
return MemoryViewRead(pBase, uCount, &this->uInUseCounter);
|
||||
}
|
||||
|
||||
MemoryViewWrite ByteBuffer::GetNextLinearWrite()
|
||||
@ -320,7 +320,7 @@ namespace Aurora::Memory
|
||||
return {};
|
||||
}
|
||||
|
||||
return MemoryViewWrite(pBase, uCount);
|
||||
return MemoryViewWrite(pBase, uCount, &this->uInUseCounter);
|
||||
}
|
||||
|
||||
bool ByteBuffer::CanWrite(AuUInt length)
|
||||
@ -353,7 +353,7 @@ namespace Aurora::Memory
|
||||
MemoryViewRead ByteBuffer::GetLinearReadableForNoMore(AuUInt length)
|
||||
{
|
||||
auto view = this->GetNextLinearRead();
|
||||
return MemoryViewRead(view.ptr, AuMin(view.length, length));
|
||||
return MemoryViewRead(view.ptr, AuMin(view.length, length), &this->uInUseCounter);
|
||||
}
|
||||
|
||||
MemoryViewWrite ByteBuffer::GetLinearWriteableForNoMore(AuUInt length)
|
||||
@ -364,14 +364,14 @@ namespace Aurora::Memory
|
||||
{
|
||||
return this->GetOrAllocateLinearWriteable(length);
|
||||
}
|
||||
return MemoryViewWrite(view.ptr, AuMin(view.length, length));
|
||||
return MemoryViewWrite(view.ptr, AuMin(view.length, length), &this->uInUseCounter);
|
||||
}
|
||||
|
||||
/* exactly */
|
||||
MemoryViewRead ByteBuffer::GetLinearReadable(AuUInt length)
|
||||
{
|
||||
auto view = this->GetNextLinearRead();
|
||||
return view.length < length ? MemoryViewRead {} : MemoryViewRead(view.ptr, length);
|
||||
return view.length < length ? MemoryViewRead {} : MemoryViewRead(view.ptr, length, &this->uInUseCounter);
|
||||
}
|
||||
|
||||
/* exactly */
|
||||
@ -383,7 +383,7 @@ namespace Aurora::Memory
|
||||
{
|
||||
return this->GetOrAllocateLinearWriteable(length);
|
||||
}
|
||||
return view.length < length ? MemoryViewWrite {} : MemoryViewWrite(view.ptr, length);
|
||||
return view.length < length ? MemoryViewWrite {} : MemoryViewWrite(view.ptr, length, &this->uInUseCounter);
|
||||
}
|
||||
|
||||
MemoryViewWrite ByteBuffer::GetOrAllocateLinearWriteable(AuUInt length)
|
||||
|
@ -149,7 +149,7 @@ namespace Aurora::Memory
|
||||
|
||||
ByteBuffer::operator MemoryViewRead() const
|
||||
{
|
||||
return MemoryViewRead(cbegin(), cend());
|
||||
return MemoryViewRead(cbegin(), cend(), (AuAUInt32 *)&this->uInUseCounter);
|
||||
}
|
||||
|
||||
ByteBuffer::operator MemoryViewWrite()
|
||||
|
@ -9,6 +9,11 @@
|
||||
|
||||
namespace Aurora::Memory
|
||||
{
|
||||
struct MemoryControlBlock
|
||||
{
|
||||
AuAUInt32 *pInUseCounter {};
|
||||
};
|
||||
|
||||
template<bool Readonly_b>
|
||||
struct MemoryView
|
||||
{
|
||||
@ -47,14 +52,62 @@ namespace Aurora::Memory
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryView(MemoryView &&view)
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
this->length = view.length;
|
||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
||||
view.controlBlock.pInUseCounter = nullptr;
|
||||
}
|
||||
|
||||
~MemoryView()
|
||||
{
|
||||
if (controlBlock.pInUseCounter)
|
||||
{
|
||||
AuAtomicSub(controlBlock.pInUseCounter, 1u);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryView &operator =(MemoryView &&view)
|
||||
{
|
||||
this->ptr = view.ptr;
|
||||
this->length = view.length;
|
||||
this->controlBlock.pInUseCounter = view.controlBlock.pInUseCounter;
|
||||
view.controlBlock.pInUseCounter = nullptr;
|
||||
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);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, int Z>
|
||||
constexpr MemoryView(T(&a)[Z])
|
||||
{
|
||||
this->ptr = &a[0];
|
||||
this->length = Z * sizeof(T);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
constexpr MemoryView(T *start, T *end)
|
||||
{
|
||||
@ -69,6 +122,23 @@ namespace Aurora::Memory
|
||||
}
|
||||
}
|
||||
|
||||
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, AuUInt length) // WARNING: length != count
|
||||
// where T = whogivesafuck
|
||||
@ -77,6 +147,15 @@ namespace Aurora::Memory
|
||||
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);
|
||||
}
|
||||
|
||||
AuUInt ToPointerValue() const
|
||||
{
|
||||
return reinterpret_cast<const AuUInt>(this->ptr);
|
||||
@ -142,6 +221,17 @@ namespace Aurora::Memory
|
||||
|
||||
Void_t /*const*/ ptr;
|
||||
AuUInt /*const*/ length;
|
||||
private:
|
||||
MemoryControlBlock controlBlock;
|
||||
|
||||
protected:
|
||||
void ResetControlBlock()
|
||||
{
|
||||
if (auto pCounter = AuExchange(this->controlBlock.pInUseCounter, nullptr))
|
||||
{
|
||||
AuAtomicSub(pCounter, 1u);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using MemoryViewRead = MemoryView<true>;
|
||||
|
@ -208,4 +208,24 @@ 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));
|
||||
}
|
||||
|
||||
static AuSPtr<AuMemory::SharableByteBuffer> AuNewSharableResizableBuffer(AuUInt32 length = 0)
|
||||
{
|
||||
return AuMove(AuMemory::NewSharableResizableBuffer(length));
|
||||
}
|
||||
|
||||
static AuByteBuffer AuNewRingBuffer(AuUInt32 length = 1024 * 5)
|
||||
{
|
||||
return AuMove(AuMemory::NewRingBuffer(length));
|
||||
}
|
||||
|
||||
static AuByteBuffer AuNewResizableBuffer(AuUInt32 length = 0)
|
||||
{
|
||||
return AuMove(AuMemory::NewResizableBuffer(length));
|
||||
}
|
Loading…
Reference in New Issue
Block a user