From da2ae8bfe1adebbffcd6c168203ec6ce10c3899e Mon Sep 17 00:00:00 2001 From: silverweed Date: Wed, 10 Jul 2024 17:48:23 +0200 Subject: [PATCH] add arena --- Makefile | 2 +- lmext1.root | Bin 0 -> 1341 bytes mem.cpp | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++ mem.h | 13 ++++++ rntviewer.cpp | 47 ++++++++++++++++--- types.h | 13 ++++++ 6 files changed, 190 insertions(+), 7 deletions(-) create mode 100644 lmext1.root create mode 100644 mem.cpp create mode 100644 mem.h create mode 100644 types.h diff --git a/Makefile b/Makefile index 8f609c2..be72e65 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CXX = clang++ d: - $(CXX) -g -O0 -o rntviewer rntviewer.cpp $(shell root-config --cflags --libs) -lROOTNTuple + $(CXX) -DDEBUG -g -O0 -o rntviewer rntviewer.cpp $(shell root-config --cflags --libs) -lROOTNTuple -lasan r: $(CXX) -O2 -o rntviewer rntviewer.cpp $(shell root-config --cflags --libs) -lROOTNTuple diff --git a/lmext1.root b/lmext1.root new file mode 100644 index 0000000000000000000000000000000000000000..f42d7dc2878aed3f4bec4ab52f34b8ac01957445 GIT binary patch literal 1341 zcmXTQ&o5zM`0mQUz>vbgz-kM`+(5Pw5HkX?6$_C5$-ux|2&88L1;_+t3_ybzJWH=^ zU(BEjHW_Fe(5?`-%$!v2oZQrk5<|TrkXukV46Gm>U|kFh89)tIKn&IibP^}n9FQ@% zKp)uFm0f;aoO1G$7#O008Iu_pRx&VXY}Nm(u<|Ms!xLskARpw^ypn<( zULYOh?;oO2W~OIstY=_&cV!WLi!MYkp$M0}(+6g)e8cOjZT8elX)^(C277 zB|e4m=RTtxb<3&ROstQO?PHn990}B+2R4`m;TlGekKnEWI>Tu(-=xKoUU}_6aY%^O zAgP{)tQzQcZw7`MsM~8qnHZKZF$4K9m)rq6Rf2)>z?mB$|8z0_1iD>&=Dm|LQOP=- z4DJ)65*Z%tbtwy(BKn;vl0k`E0OYq~up8GPY-Qp>v(A~@vr)U!lA-~$Vp`Z#SVi51A`L-8&EA15W~P9 zC?f|-17jBinDihtLm-p}`hfvt0>f-c*3yq_7|nsq46sWaz%J1MxdfQRK*GJIiSs9@YX>7d^s2N73&*50lS*ESTs*59y7MWR>9L%Qc!23tj|(ixM> zLMyem>HSszfAGls3-%YTdvT};U1ZBQT0b}Q`Mj64rV}fVO9drJ1|}}`Nr|(M*e04G z#C+-arN9SQ({pAWu-h+}?@_FKWp(K82%UbLOYa&|6n-5|`g=yMs`k+Bufel;uUEcK z&WXtV#%5x8@KL1`zc7{VS&z=uo)4g23OzGnext=(f), (f)=(n)) +#define SLLStackPop_N(f,next) ((f)=(f)->next) + +#ifdef DEBUG +#define asan_poison_memory_region(mem, cmt) __asan_poison_memory_region(mem, cmt) +#define asan_unpoison_memory_region(mem, cmt) __asan_unpoison_memory_region(mem, cmt) +#else +#define asan_poison_memory_region(mem, cmt) +#define asan_unpoison_memory_region(mem, cmt) +#endif + +void *os_reserve(u64 size) +{ + return mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); +} + +void os_release(void *mem, u64 size) +{ + munmap(mem, size); +} + +b32x os_commit(void *addr, u64 size) +{ + return mprotect(addr, size, PROT_READ|PROT_WRITE) == 0; +} + +// init_res: initial reserved size +// init_cmt: initial committed size +Arena *arena_alloc_sized(u64 init_res, u64 init_cmt) +{ + assert(ARENA_HEADER_SIZE < init_cmt && init_cmt <= init_res); + + u64 page_size = getpagesize(); + u64 res = align_pow2(init_res, page_size); + u64 cmt = align_pow2(init_cmt, page_size); + + // reserve memory + void *mem = os_reserve(res); + if (!os_commit(mem, cmt)) { + munmap(mem, init_res); + } + + Arena *arena = (Arena *)mem; + if (arena) { + asan_poison_memory_region(mem, cmt); + asan_unpoison_memory_region(mem, ARENA_HEADER_SIZE); + + arena->cur = arena; + arena->pos = ARENA_HEADER_SIZE; + arena->cmt = cmt; + arena->res = res; + arena->align = 8; + } + + return arena; +} + +Arena *arena_alloc() +{ + return arena_alloc_sized(ARENA_RESERVE_SIZE, ARENA_COMMIT_SIZE); +} + +void arena_release(Arena *arena) +{ + for (Arena *node = arena->cur, *prev = 0; node; node = prev) { + prev = node->prev; + os_release(node, node->res); + } +} + +u64 arena_huge_push_threshold() +{ + u64 res = ARENA_RESERVE_SIZE; + u64 threshold = (res - ARENA_HEADER_SIZE) / 2 + 1; + return threshold; +} + +void *arena_push_impl(Arena *arena, u64 size) +{ + Arena *cur = arena->cur; + u64 pos_mem = align_pow2(cur->pos, arena->align); + u64 pos_new = pos_mem + size; + + if (cur->res < pos_new) { + Arena *new_block; + if (size < arena_huge_push_threshold()) { + new_block = arena_alloc(); + } else { + u64 new_block_size = size + ARENA_HEADER_SIZE; + new_block = arena_alloc_sized(new_block_size, new_block_size); + } + + if (new_block) { + new_block->base_pos = cur->base_pos + cur->res; + SLLStackPush_N(arena->cur, new_block, prev); + + cur = new_block; + pos_mem = align_pow2(cur->pos, cur->align); + pos_new = pos_mem + size; + } + } + + if (cur->cmt < pos_new) { + u64 cmt_new_aligned = align_pow2(pos_new, ARENA_COMMIT_SIZE); + u64 cmt_new_clamped = std::min(cmt_new_aligned, cur->res); + u64 cmt_new_size = cmt_new_clamped - cur->cmt; + b32x is_cmt_ok = os_commit((u8*)cur + cur->cmt, cmt_new_size); + + if (is_cmt_ok) + cur->cmt = cmt_new_clamped; + } + + void *mem = 0; + if (cur->cmt >= pos_new) { + mem = (u8*)cur + pos_mem; + cur->pos = pos_new; + asan_unpoison_memory_region(mem, size); + } + + return mem; +} diff --git a/mem.h b/mem.h new file mode 100644 index 0000000..9966456 --- /dev/null +++ b/mem.h @@ -0,0 +1,13 @@ +#define ARENA_HEADER_SIZE 128 +#define ARENA_COMMIT_SIZE (64 * 1024) +#define ARENA_RESERVE_SIZE (64 * 1024 * 1024) + +struct Arena { + Arena *prev; + Arena *cur; + u64 base_pos; + u64 pos; + u64 cmt; + u64 res; + u64 align; +}; diff --git a/rntviewer.cpp b/rntviewer.cpp index b3b7ab2..366d990 100644 --- a/rntviewer.cpp +++ b/rntviewer.cpp @@ -1,10 +1,22 @@ -#include "defer.hpp" - #include +#include +#include #include +#include #include +#include + +#ifdef DEBUG +#include +#endif + +#include "types.h" +#include "defer.hpp" +#include "mem.h" + +#include "mem.cpp" using namespace ROOT::Experimental; @@ -18,14 +30,24 @@ static size_t file_size(FILE *f) int main(int argc, char **argv) { - if (argc < 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); + if (argc < 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } - // Open and map the file - const char *fname = argv[0]; + // Collect arguments + const char *ntpl_name = argv[1]; + const char *fname = argv[2]; + // Allocate memory + Arena *arena = arena_alloc(); + if (!arena) { + fprintf(stderr, "Failed to allocate memory\n"); + return 1; + } + defer { arena_release(arena); }; + + // Open and map the file FILE *file = fopen(fname, "rb"); defer { fclose(file); }; @@ -38,7 +60,20 @@ int main(int argc, char **argv) } defer { munmap(fmem, fsize); }; + // Open the TFile + TFile *tfile = TFile::Open(fname, "READ"); + if (!tfile) { + fprintf(stderr, "Failed to open TFile.\n"); + return 1; + } + defer { delete tfile; }; + // Get the RNTuple information + const RNTuple *anchor = tfile->Get(ntpl_name); + if (!anchor) { + fprintf(stderr, "RNTuple '%s' not found in %s.\n", ntpl_name, fname); + return 1; + } return 0; } diff --git a/types.h b/types.h new file mode 100644 index 0000000..bd6948c --- /dev/null +++ b/types.h @@ -0,0 +1,13 @@ +using u8 = uint8_t; +using u16 = uint16_t; +using u32 = uint32_t; +using u64 = uint64_t; + +using f32 = float; +using f64 = double; + +using b8 = bool; +using b32x = int; + +using i32 = int32_t; +using i64 = int64_t;