/* EngineBufferManager(Test) - cover the interface to a central buffer manager Copyright (C) 2026, Hermann Vosseler   **Lumiera** is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the   Free Software Foundation; either version 2 of the License, or (at your   option) any later version. See the file COPYING for further details. * *****************************************************************/ /** @file engine-buffer-manager-test.cpp ** unit test \ref EngineBufferManager_test */ #include "test/run.hpp" #include "test/test-helper.hpp" //#include "vault/mem/engine-buffer-metadata.hpp" #include "vault/mem/engine-buffer-manager.hpp" #include "vault/mem/engine-buffer-allocator.hpp" //#include "lib/depend-inject.hpp" //#include "lib/thread.hpp" //#include "lib/error.hpp" #include "lib/symbol.hpp" #include "test/diagnostic-output.hpp"////////////TODO #include //using std::this_thread::yield; //using lib::Thread; using lib::Literal; namespace vault { namespace mem { namespace test { // using LERR_(LOGIC); // using LERR_(LIFECYCLE); namespace { // Test helper // template // Buff* // mark_as_Buffer(X& something) // { // return reinterpret_cast (std::addressof(something)); // } // } /*****************************************************************************//** * @test Show how the central buffer manager of the Render Engine can be accessed. */ class EngineBufferManager_test : public Test { virtual void run (Arg) { // seedRand(); demonstrate_AllocatorInterface(); verify_syncRequest(); verify_asyncRequest(); verify_lulz(); } /** @test show how to allocate buffer memory * with the underlying base allocator. * @remark 4/2026 for the first integration of the Render Engine, * a simplified implementation is used that just delegates * to the regular heap allocator (which actually performs * quite well on modern C++ STDLib). The plan is to * use some kind of tiling pool allocator eventually, * contingent on the actual performance observations. */ void demonstrate_AllocatorInterface() { using Allo = HeapBufferAllocator; CHECK (lib::allo::is_Stateless_v); Allo allo; auto a1 = allo.allocate (55); auto a2 = allo.allocate (555); CHECK (a1.mem); CHECK (a2.mem); CHECK (a1.siz == Allo::TILE_SIZ); CHECK (a2.siz % Allo::TILE_SIZ == 0); CHECK (a2.siz > 555); // can use that memory without blowing up.... auto doooh = new(a1.mem) f128{std::numeric_limits::max()}; *doooh /= 2; CHECK (2 == std::numeric_limits::max() / *doooh); allo.deallocate (a1); allo.deallocate (a2); } /** @test show that a direct request for allocation is honored * - request some memory * - read and write to that memory * - return all leased allocations * - verify the diagnostic meshes up with the allocation * @remark in principle it is not possible to prove that some * memory allocation actually works, other than checking * that access to the given memory is possible, because * the fact that no memory corruption took place is * only semi-decidable (you can show a corruption event, * but not the absence of any such an event). */ void verify_syncRequest() { EngineBufferManager manager; CHECK (watch(manager).isEmpty()); Alloc alloc = manager.requestAllocation (555); CHECK (not alloc.empty()); CHECK (alloc.siz >= 555); CHECK (alloc.siz == watch(manager).bytesAllocd()); CHECK (alloc.siz == watch(manager).bytesLeased()); CHECK (alloc.siz % HeapBufferAllocator::TILE_SIZ == 0); // can use that memory char* buf = reinterpret_cast (alloc.mem); string ranS{lib::randStr(555-1)}; auto* p = std::copy (ranS.begin(), ranS.end(), buf); CHECK (ranS.length() == size_t(p - buf)); *p = '\0'; CHECK (ranS == buf); CHECK (1 == watch(manager).numAllocs()); Alloc a2 = manager.requestAllocation (1'000'000); CHECK (not a2.empty()); CHECK (a2.siz >= 1e6); CHECK (2 == watch(manager).numAllocs()); CHECK (1e6+555 < watch(manager).bytesLeased()); manager.supply (a2); manager.processPendingRequests(); CHECK (1 == watch(manager).numAllocs()); CHECK (1e6 > watch(manager).bytesLeased()); manager.supply (alloc); manager.processPendingRequests(); CHECK (0 == watch(manager).numAllocs()); CHECK (0 == watch(manager).bytesLeased()); } /** @test show that an working allocation request across thread boundaries */ void verify_asyncRequest() { } /** @test */ void verify_lulz() { } }; /** Register this test class... */ LAUNCHER (EngineBufferManager_test, "unit engine"); }}} // namespace vault::mem::test