[*] Harden AuByteBuffer

[+] Alias: AuNewSharableBuffer
[+] Alias: AuNewSharableResizableBuffer
[+] Alias: AuNewRingBuffer
[+] Alias: AuNewResizableBuffer
This commit is contained in:
Reece Wilson 2024-03-09 06:51:23 +00:00
parent 9a846a6d2f
commit c935b892c7
6 changed files with 193 additions and 24 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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()

View File

@ -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>;

View File

@ -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));
}