aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/memory/memoryarena.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-10-22 17:57:29 +0200
committerGitHub Enterprise <[email protected]>2025-10-22 17:57:29 +0200
commit5c139e2d8a260544bc5e730de0440edbab4b0f03 (patch)
treeb477208925fe3b373d4833460b90d61a8051cf05 /src/zencore/memory/memoryarena.cpp
parent5.7.7-pre3 (diff)
downloadzen-5c139e2d8a260544bc5e730de0440edbab4b0f03.tar.xz
zen-5c139e2d8a260544bc5e730de0440edbab4b0f03.zip
add support for OTLP logging/tracing (#599)
- adds `zentelemetry` project which houses new functionality for serializing logs and traces in OpenTelemetry Protocol format (OTLP) - moved existing stats functionality from `zencore` to `zentelemetry` - adds `TRefCounted<T>` for vtable-less refcounting - adds `MemoryArena` class which allows for linear allocation of memory from chunks - adds `protozero` which is used to encode OTLP protobuf messages
Diffstat (limited to 'src/zencore/memory/memoryarena.cpp')
-rw-r--r--src/zencore/memory/memoryarena.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/zencore/memory/memoryarena.cpp b/src/zencore/memory/memoryarena.cpp
new file mode 100644
index 000000000..9c907a66d
--- /dev/null
+++ b/src/zencore/memory/memoryarena.cpp
@@ -0,0 +1,126 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zencore/memory/memoryarena.h>
+
+namespace zen {
+
+MemoryArena::~MemoryArena()
+{
+ for (auto Chunk : m_Chunks)
+ delete[] Chunk;
+}
+
+void*
+MemoryArena::AllocateAligned(size_t ByteCount, size_t align)
+{
+ if (ByteCount == 0)
+ {
+ return nullptr;
+ }
+
+ void* Ptr = nullptr;
+
+ m_Lock.WithExclusiveLock([&] {
+ size_t AlignedOffset = (m_CurrentOffset + (align - 1)) & ~(align - 1);
+
+ if (m_CurrentChunk == nullptr || AlignedOffset + ByteCount > ChunkSize)
+ {
+ uint8_t* NewChunk = new uint8_t[ChunkSize];
+ if (!NewChunk)
+ {
+ return;
+ }
+
+ m_Chunks.push_back(NewChunk);
+ m_CurrentChunk = NewChunk;
+ AlignedOffset = 0;
+ }
+
+ Ptr = m_CurrentChunk + AlignedOffset;
+ m_CurrentOffset = AlignedOffset + ByteCount;
+ });
+
+ return Ptr;
+}
+
+void*
+MemoryArena::AllocateAlignedWithOffset(size_t ByteCount, size_t align, size_t offset)
+{
+ if (ByteCount == 0)
+ {
+ return nullptr;
+ }
+
+ void* Ptr = nullptr;
+
+ m_Lock.WithExclusiveLock([&] {
+ size_t AlignedOffset = (m_CurrentOffset + (align - 1) + offset) & ~(align - 1);
+
+ if (m_CurrentChunk == nullptr || AlignedOffset + ByteCount > ChunkSize)
+ {
+ uint8_t* NewChunk = new uint8_t[ChunkSize];
+ if (!NewChunk)
+ {
+ return;
+ }
+
+ m_Chunks.push_back(NewChunk);
+ m_CurrentChunk = NewChunk;
+ AlignedOffset = offset;
+ }
+
+ Ptr = m_CurrentChunk + AlignedOffset;
+ m_CurrentOffset = AlignedOffset + ByteCount;
+ });
+
+ return Ptr;
+}
+
+void*
+MemoryArena::Allocate(size_t Size)
+{
+ if (Size == 0)
+ {
+ return nullptr;
+ }
+
+ void* Ptr = nullptr;
+ constexpr size_t Alignment = alignof(std::max_align_t);
+
+ m_Lock.WithExclusiveLock([&] {
+ size_t AlignedOffset = (m_CurrentOffset + Alignment - 1) & ~(Alignment - 1);
+
+ if (m_CurrentChunk == nullptr || AlignedOffset + Size > ChunkSize)
+ {
+ uint8_t* NewChunk = new uint8_t[ChunkSize];
+ if (!NewChunk)
+ {
+ return;
+ }
+
+ m_Chunks.push_back(NewChunk);
+ m_CurrentChunk = NewChunk;
+ AlignedOffset = 0;
+ }
+
+ Ptr = m_CurrentChunk + AlignedOffset;
+ m_CurrentOffset = AlignedOffset + Size;
+ });
+
+ return Ptr;
+}
+
+const char*
+MemoryArena::DuplicateString(std::string_view Str)
+{
+ const size_t Len = Str.size();
+ char* NewStr = static_cast<char*>(Allocate(Len + 1));
+ if (NewStr)
+ {
+ memcpy(NewStr, Str.data(), Len);
+ NewStr[Len] = '\0';
+ }
+ return NewStr;
+}
+
+} // namespace zen