From 3229fa753cef10eda963247eaedec1d6ed9de9e4 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Tue, 18 Jun 2024 10:06:53 +0200 Subject: Moved AllocatorDefinition in a lanes namespace --- docs/index.html | 10 +++++-- src/allocator.h | 84 +++++++++++++++++++++++++++++--------------------------- src/lanesconf.h | 1 + src/state.cpp | 4 +-- src/universe.cpp | 4 +-- src/universe.h | 4 +-- 6 files changed, 59 insertions(+), 48 deletions(-) diff --git a/docs/index.html b/docs/index.html index fe92565..4a9fc35 100644 --- a/docs/index.html +++ b/docs/index.html @@ -289,11 +289,17 @@ If nil, Lua states are created with lua_newstate() and reuse the allocator from the master state.
If "protected", The default allocator obtained from lua_getallocf() in the master state is wrapped inside a critical section and used in all newly created states.
- If a function, this function is called prior to creating the state, with a single string argument, either "keeper" or "lane". It should return a full userdata containing the following structure: + If a function, this function is called prior to creating the state, with a single string argument, either "keeper" or "lane". It should return a full userdata created as follows:
-
	struct { uintptr_t version { AllocatorDefinition::kAllocatorVersion }; lua_Alloc allocF; void* allocUD; }
+
+	static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) {
+		lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} };
+		// populate _def->allocF and _def->allocUD here
+		return 1;
+	};
+							
diff --git a/src/allocator.h b/src/allocator.h index 9a9c245..e09ab38 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -2,46 +2,50 @@ // ################################################################################################# -// everything we need to provide to lua_newstate() -class AllocatorDefinition -{ - public: - // xxh64 of string "kAllocatorVersion_1" generated at https://www.pelock.com/products/hash-calculator - static constexpr uintptr_t kAllocatorVersion{ static_cast(0xCF9D321B0DFB5715ull) }; - uintptr_t version{ kAllocatorVersion }; - lua_Alloc allocF{ nullptr }; - void* allocUD{ nullptr }; - - [[nodiscard]] static void* operator new(size_t size_) noexcept = delete; // can't create one outside of a Lua state - [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept { return lua_newuserdatauv(L_, size_, 0); } - // always embedded somewhere else or "in-place constructed" as a full userdata - // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception - static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] lua_State* L_) {} - - AllocatorDefinition(uintptr_t const version_, lua_Alloc const allocF_, void* const allocUD_) noexcept - : version{ version_ } - , allocF{ allocF_ } - , allocUD{ allocUD_ } - { - } - AllocatorDefinition() = default; - AllocatorDefinition(AllocatorDefinition const& rhs_) = default; - AllocatorDefinition(AllocatorDefinition&& rhs_) = default; - AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; - AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; - - void initFrom(lua_State* L_) - { - allocF = lua_getallocf(L_, &allocUD); - } +namespace lanes { - void* alloc(size_t nsize_) + // everything we need to provide to lua_newstate() + class AllocatorDefinition { - return allocF(allocUD, nullptr, 0, nsize_); - } + public: + // xxh64 of string "kAllocatorVersion_1" generated at https://www.pelock.com/products/hash-calculator + static constexpr uintptr_t kAllocatorVersion{ static_cast(0xCF9D321B0DFB5715ull) }; + uintptr_t version{ kAllocatorVersion }; + lua_Alloc allocF{ nullptr }; + void* allocUD{ nullptr }; - void free(void* ptr_, size_t osize_) - { - std::ignore = allocF(allocUD, ptr_, osize_, 0); - } -}; + [[nodiscard]] static void* operator new(size_t size_) noexcept = delete; // can't create one outside of a Lua state + [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept { return lua_newuserdatauv(L_, size_, 0); } + // always embedded somewhere else or "in-place constructed" as a full userdata + // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception + static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] lua_State* L_) {} + + AllocatorDefinition(uintptr_t const version_, lua_Alloc const allocF_, void* const allocUD_) noexcept + : version{ version_ } + , allocF{ allocF_ } + , allocUD{ allocUD_ } + { + } + AllocatorDefinition() = default; + AllocatorDefinition(AllocatorDefinition const& rhs_) = default; + AllocatorDefinition(AllocatorDefinition&& rhs_) = default; + AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; + AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; + + void initFrom(lua_State* L_) + { + allocF = lua_getallocf(L_, &allocUD); + } + + void* alloc(size_t nsize_) + { + return allocF(allocUD, nullptr, 0, nsize_); + } + + void free(void* ptr_, size_t osize_) + { + std::ignore = allocF(allocUD, ptr_, osize_, 0); + } + }; + +} // namespace lanes diff --git a/src/lanesconf.h b/src/lanesconf.h index f20dfff..0afd493 100644 --- a/src/lanesconf.h +++ b/src/lanesconf.h @@ -26,6 +26,7 @@ // static function variable: prefix s, followed by an uppercase letter // function local variable: prefix _, followed by an uppercase letter // named lambda capture: no prefix, start with a lowercase letter +// stuff for external consumption in a 'lanes' namespace #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) #ifdef __cplusplus diff --git a/src/state.cpp b/src/state.cpp index bae2ba5..6d3910b 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -209,8 +209,8 @@ namespace state { lua_pushcclosure(from, U->provideAllocator, 0); // L: provideAllocator() luaG_pushstring(from, hint); // L: provideAllocator() "" lua_call(from, 1, 1); // L: result - AllocatorDefinition* const _def{ luaG_tofulluserdata(from, -1) }; - if (!_def || _def->version != AllocatorDefinition::kAllocatorVersion) { + lanes::AllocatorDefinition* const _def{ luaG_tofulluserdata(from, -1) }; + if (!_def || _def->version != lanes::AllocatorDefinition::kAllocatorVersion) { raise_luaL_error(from, "Bad config.allocator function, must provide a valid AllocatorDefinition"); } lua_State* const _L{ lua_newstate(_def->allocF, _def->allocUD) }; diff --git a/src/universe.cpp b/src/universe.cpp index d24a784..770fccf 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -166,7 +166,7 @@ Universe::Universe() { Universe* const _U{ Universe::Get(L_) }; // push a new full userdata on the stack, giving access to the universe's protected allocator - [[maybe_unused]] AllocatorDefinition* const _def{ new (L_) AllocatorDefinition{ _U->protectedAllocator.makeDefinition() } }; + [[maybe_unused]] lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{ _U->protectedAllocator.makeDefinition() } }; return 1; } @@ -218,7 +218,7 @@ void Universe::initializeAllocatorFunction(lua_State* const L_) std::ignore = luaG_getfield(L_, -1, "internal_allocator"); // L_: settings "libc"|"allocator" std::string_view const _allocator{ luaG_tostring(L_, -1) }; if (_allocator == "libc") { - internalAllocator = AllocatorDefinition{ AllocatorDefinition::kAllocatorVersion, libc_lua_Alloc, nullptr }; + internalAllocator = lanes::AllocatorDefinition{ lanes::AllocatorDefinition::kAllocatorVersion, libc_lua_Alloc, nullptr }; } else if (provideAllocator == luaG_provide_protected_allocator) { // user wants mutex protection on the state's allocator. Use protection for our own allocations too, just in case. internalAllocator = protectedAllocator.makeDefinition(); diff --git a/src/universe.h b/src/universe.h index 2edd825..d890e5c 100644 --- a/src/universe.h +++ b/src/universe.h @@ -17,7 +17,7 @@ class Lane; // mutex-protected allocator for use with Lua states that share a non-threadsafe allocator class ProtectedAllocator -: public AllocatorDefinition +: public lanes::AllocatorDefinition { private: std::mutex mutex; @@ -90,7 +90,7 @@ class Universe // contains a mutex and the original allocator definition ProtectedAllocator protectedAllocator; - AllocatorDefinition internalAllocator; + lanes::AllocatorDefinition internalAllocator; Keepers keepers; -- cgit v1.2.3-55-g6feb