summaryrefslogtreecommitdiffstats
path: root/yql/essentials/parser/pg_wrapper/arena_ctx.cpp
diff options
context:
space:
mode:
authorvvvv <[email protected]>2024-11-07 12:29:36 +0300
committervvvv <[email protected]>2024-11-07 13:49:47 +0300
commitd4c258e9431675bab6745c8638df6e3dfd4dca6b (patch)
treeb5efcfa11351152a4c872fccaea35749141c0b11 /yql/essentials/parser/pg_wrapper/arena_ctx.cpp
parent13a4f274caef5cfdaf0263b24e4d6bdd5521472b (diff)
Moved other yql/essentials libs YQL-19206
init commit_hash:7d4c435602078407bbf20dd3c32f9c90d2bbcbc0
Diffstat (limited to 'yql/essentials/parser/pg_wrapper/arena_ctx.cpp')
-rw-r--r--yql/essentials/parser/pg_wrapper/arena_ctx.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/yql/essentials/parser/pg_wrapper/arena_ctx.cpp b/yql/essentials/parser/pg_wrapper/arena_ctx.cpp
new file mode 100644
index 00000000000..e91cd6ad7a2
--- /dev/null
+++ b/yql/essentials/parser/pg_wrapper/arena_ctx.cpp
@@ -0,0 +1,140 @@
+#include "arena_ctx.h"
+#include <util/generic/yexception.h>
+
+#define TypeName PG_TypeName
+#define SortBy PG_SortBy
+#undef SIZEOF_SIZE_T
+extern "C" {
+#include "postgres.h"
+#include "nodes/memnodes.h"
+#include "utils/memutils.h"
+#include "utils/memutils_internal.h"
+}
+
+namespace NYql {
+
+struct TArenaPAllocHeader {
+ size_t Size;
+ ui64 Self; // should be placed right before pointer to allocated area, see GetMemoryChunkContext
+};
+
+static_assert(sizeof(TArenaPAllocHeader) == sizeof(size_t) + sizeof(MemoryContext), "Padding is not allowed");
+
+extern "C" {
+extern void *ArenaAlloc(MemoryContext context, Size size);
+extern void ArenaFree(void *pointer);
+extern void *ArenaRealloc(void *pointer, Size size);
+extern void ArenaReset(MemoryContext context);
+extern void ArenaDelete(MemoryContext context);
+extern MemoryContext ArenaGetChunkContext(void *pointer);
+extern Size ArenaGetChunkSpace(void *pointer);
+extern bool ArenaIsEmpty(MemoryContext context);
+extern void ArenaStats(MemoryContext context,
+ MemoryStatsPrintFunc printfunc, void *passthru,
+ MemoryContextCounters *totals,
+ bool print_to_stderr);
+#ifdef MEMORY_CONTEXT_CHECKING
+extern void ArenaCheck(MemoryContext context);
+#endif
+}
+
+extern "C" void *ArenaAlloc(MemoryContext context, Size size) {
+ Y_UNUSED(context);
+ auto fullSize = size + MAXIMUM_ALIGNOF - 1 + sizeof(TArenaPAllocHeader);
+ auto ptr = TArenaMemoryContext::GetCurrentPool().Allocate(fullSize);
+ auto aligned = (TArenaPAllocHeader*)MAXALIGN(ptr + sizeof(TArenaPAllocHeader));
+ Y_ENSURE((ui64(context) & MEMORY_CONTEXT_METHODID_MASK) == 0);
+ aligned[-1].Self = ui64(context) | MCTX_UNUSED2_ID;
+ aligned[-1].Size = size;
+ return aligned;
+}
+
+extern "C" void ArenaFree(void* pointer) {
+ Y_UNUSED(pointer);
+}
+
+extern "C" void* ArenaRealloc(void* pointer, Size size) {
+ if (!size) {
+ return nullptr;
+ }
+
+ void* ret = ArenaAlloc(nullptr, size);
+ if (pointer) {
+ auto prevSize = ((const TArenaPAllocHeader*)pointer)[-1].Size;
+ memmove(ret, pointer, prevSize);
+ }
+
+ return ret;
+}
+
+extern "C" void ArenaReset(MemoryContext context) {
+ Y_UNUSED(context);
+}
+
+extern "C" void ArenaDelete(MemoryContext context) {
+ Y_UNUSED(context);
+}
+
+extern "C" MemoryContext ArenaGetChunkContext(void *pointer) {
+ return (MemoryContext)(((ui64*)pointer)[-1] & ~MEMORY_CONTEXT_METHODID_MASK);
+}
+
+extern "C" Size ArenaGetChunkSpace(void* pointer) {
+ Y_UNUSED(pointer);
+ return 0;
+}
+
+extern "C" bool ArenaIsEmpty(MemoryContext context) {
+ Y_UNUSED(context);
+ return false;
+}
+
+extern "C" void ArenaStats(MemoryContext context,
+ MemoryStatsPrintFunc printfunc, void *passthru,
+ MemoryContextCounters *totals,
+ bool print_to_stderr) {
+ Y_UNUSED(context);
+ Y_UNUSED(printfunc);
+ Y_UNUSED(passthru);
+ Y_UNUSED(totals);
+ Y_UNUSED(print_to_stderr);
+}
+
+extern "C" void ArenaCheck(MemoryContext context) {
+ Y_UNUSED(context);
+}
+
+__thread TArenaMemoryContext* TArenaMemoryContext::Current = nullptr;
+
+TArenaMemoryContext::TArenaMemoryContext() {
+ MyContext = (MemoryContext)malloc(sizeof(MemoryContextData));
+ static_assert(MEMORY_CONTEXT_METHODID_MASK < sizeof(void*));
+ MemoryContextCreate(MyContext,
+ T_AllocSetContext,
+ MCTX_UNUSED2_ID,
+ nullptr,
+ "arena");
+ Acquire();
+}
+
+TArenaMemoryContext::~TArenaMemoryContext() {
+ MemoryContextDeleteChildren(MyContext);
+ Release();
+ free(MyContext);
+}
+
+void TArenaMemoryContext::Acquire() {
+ PrevContext = CurrentMemoryContext;
+ CurrentMemoryContext = MyContext;
+ Prev = Current;
+ Current = this;
+}
+
+void TArenaMemoryContext::Release() {
+ CurrentMemoryContext = PrevContext;
+ PrevContext = nullptr;
+ Current = Prev;
+ Prev = nullptr;
+}
+
+}