From baf5414b853524bb20df2b92e4b4e13bb1e425cd Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 21 Feb 2022 11:30:51 +0100 Subject: Make allocator threadsafe by default when running LuaJIT, because LuaJIT allocator is not --- src/keeper.c | 16 ++++++++-------- src/lanes.c | 12 ++++++------ src/lanes.lua | 3 ++- src/linda.c | 12 ++++++------ src/macros_and_utils.h | 3 +++ 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/keeper.c b/src/keeper.c index 6b3a810..3211c1b 100644 --- a/src/keeper.c +++ b/src/keeper.c @@ -612,14 +612,14 @@ void close_keepers( Universe* U, lua_State* L) // free the keeper bookkeeping structure { // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if LUAJIT_FLAVOR == 0 +#if USE_LUA_STATE_ALLOCATOR { AllocatorDefinition* const allocD = &U->protected_allocator.definition; - allocD->allocF( allocUD, U->keepers, sizeof( Keepers) + (nbKeepers - 1) * sizeof( Keeper), 0); + allocD->allocF( allocD->allocUD, U->keepers, sizeof( Keepers) + (nbKeepers - 1) * sizeof( Keeper), 0); } -#else // LUAJIT_FLAVOR +#else // USE_LUA_STATE_ALLOCATOR free(U->keepers); -#endif // LUAJIT_FLAVOR +#endif // USE_LUA_STATE_ALLOCATOR U->keepers = NULL; } } @@ -654,14 +654,14 @@ void init_keepers( Universe* U, lua_State* L) { size_t const bytes = sizeof( Keepers) + (nb_keepers - 1) * sizeof( Keeper); // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if LUAJIT_FLAVOR == 0 +#if USE_LUA_STATE_ALLOCATOR { AllocatorDefinition* const allocD = &U->protected_allocator.definition; - U->keepers = (Keepers*) allocD->allocF( allocUD, NULL, 0, bytes); + U->keepers = (Keepers*) allocD->allocF( allocD->allocUD, NULL, 0, bytes); } -#else // LUAJIT_FLAVOR +#else // USE_LUA_STATE_ALLOCATOR U->keepers = (Keepers*)malloc(bytes); -#endif // LUAJIT_FLAVOR +#endif // USE_LUA_STATE_ALLOCATOR if( U->keepers == NULL) { (void) luaL_error( L, "init_keepers() failed while creating keeper array; out of memory"); diff --git a/src/lanes.c b/src/lanes.c index bf0f0a3..f702685 100644 --- a/src/lanes.c +++ b/src/lanes.c @@ -254,14 +254,14 @@ static void lane_cleanup( Lane* s) #endif // HAVE_LANE_TRACKING // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if LUAJIT_FLAVOR == 0 +#if USE_LUA_STATE_ALLOCATOR { AllocatorDefinition* const allocD = &s->U->protected_allocator.definition; allocD->allocF(allocD->allocUD, s, sizeof(Lane), 0); } -#else // LUAJIT_FLAVOR +#else // USE_LUA_STATE_ALLOCATOR free(s); -#endif // LUAJIT_FLAVOR +#endif // USE_LUA_STATE_ALLOCATOR } /* @@ -1231,14 +1231,14 @@ LUAG_FUNC( lane_new) // a Lane full userdata needs a single uservalue ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs priority globals package required gc_cb lane // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if LUAJIT_FLAVOR == 0 +#if USE_LUA_STATE_ALLOCATOR { AllocatorDefinition* const allocD = &U->protected_allocator.definition; s = *ud = (Lane*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(Lane)); } -#else // LUAJIT_FLAVOR +#else // USE_LUA_STATE_ALLOCATOR s = *ud = (Lane*) malloc(sizeof(Lane)); -#endif // LUAJIT_FLAVOR +#endif // USE_LUA_STATE_ALLOCATOR if( s == NULL) { return luaL_error( L, "could not create lane: out of memory"); diff --git a/src/lanes.lua b/src/lanes.lua index 2f06137..0858ad7 100644 --- a/src/lanes.lua +++ b/src/lanes.lua @@ -76,7 +76,8 @@ lanes.configure = function( settings_) track_lanes = false, demote_full_userdata = nil, verbose_errors = false, - allocator = nil + -- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes + allocator = (package.loaded.jit and jit.version) and "protected" or nil } local boolean_param_checker = function( val_) -- non-'boolean-false' should be 'boolean-true' or nil diff --git a/src/linda.c b/src/linda.c index 4149e71..42cda51 100644 --- a/src/linda.c +++ b/src/linda.c @@ -795,16 +795,16 @@ static void* linda_id( lua_State* L, DeepOp op_) * just don't use L's allocF because we don't know which state will get the honor of GCing the linda */ // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if LUAJIT_FLAVOR == 0 +#if USE_LUA_STATE_ALLOCATOR { Universe* const U = universe_get(L); AllocatorDefinition* const allocD = &U->protected_allocator.definition; s = (struct s_Linda*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(struct s_Linda) + name_len); // terminating 0 is already included } -#else // LUAJIT_FLAVOR +#else // USE_LUA_STATE_ALLOCATOR s = (struct s_Linda*)malloc(sizeof(struct s_Linda) + name_len); // terminating 0 is already included -#endif // LUAJIT_FLAVOR +#endif // USE_LUA_STATE_ALLOCATOR if( s) { s->prelude.magic.value = DEEP_VERSION.value; @@ -838,16 +838,16 @@ static void* linda_id( lua_State* L, DeepOp op_) SIGNAL_FREE( &linda->read_happened); SIGNAL_FREE( &linda->write_happened); // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly -#if LUAJIT_FLAVOR == 0 +#if USE_LUA_STATE_ALLOCATOR { Universe* const U = universe_get(L); AllocatorDefinition* const allocD = &U->protected_allocator.definition; allocD->allocF(allocD->allocUD, linda, sizeof(struct s_Linda) + strlen(linda->name), 0); } -#else // LUAJIT_FLAVOR +#else // USE_LUA_STATE_ALLOCATOR free(linda); -#endif // LUAJIT_FLAVOR +#endif // USE_LUA_STATE_ALLOCATOR return NULL; } diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index dac89d1..e8e725b 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -109,4 +109,7 @@ extern char const* debugspew_indent; #define LUAJIT_FLAVOR 0 #endif // LUA_JITLIBNAME +// after all, it looks like we can use the state allocator for our own usage when running LuaJIT, as long as we mutex-protect it +#define USE_LUA_STATE_ALLOCATOR 1 // (LUAJIT_FLAVOR==0) + #endif // MACROS_AND_UTILS_H -- cgit v1.2.3-55-g6feb