diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2022-02-21 11:30:51 +0100 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2022-02-21 11:30:51 +0100 |
commit | baf5414b853524bb20df2b92e4b4e13bb1e425cd (patch) | |
tree | f66565c529558cbc7a23cfd6e503193c8f5e7b9d | |
parent | a147fa3aaf2a60252bd9cfd609ee7b65725d0ce8 (diff) | |
download | lanes-baf5414b853524bb20df2b92e4b4e13bb1e425cd.tar.gz lanes-baf5414b853524bb20df2b92e4b4e13bb1e425cd.tar.bz2 lanes-baf5414b853524bb20df2b92e4b4e13bb1e425cd.zip |
Make allocator threadsafe by default when running LuaJIT, because LuaJIT allocator is not
-rw-r--r-- | src/keeper.c | 16 | ||||
-rw-r--r-- | src/lanes.c | 12 | ||||
-rw-r--r-- | src/lanes.lua | 3 | ||||
-rw-r--r-- | src/linda.c | 12 | ||||
-rw-r--r-- | 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) | |||
612 | // free the keeper bookkeeping structure | 612 | // free the keeper bookkeeping structure |
613 | { | 613 | { |
614 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly | 614 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly |
615 | #if LUAJIT_FLAVOR == 0 | 615 | #if USE_LUA_STATE_ALLOCATOR |
616 | { | 616 | { |
617 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 617 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; |
618 | allocD->allocF( allocUD, U->keepers, sizeof( Keepers) + (nbKeepers - 1) * sizeof( Keeper), 0); | 618 | allocD->allocF( allocD->allocUD, U->keepers, sizeof( Keepers) + (nbKeepers - 1) * sizeof( Keeper), 0); |
619 | } | 619 | } |
620 | #else // LUAJIT_FLAVOR | 620 | #else // USE_LUA_STATE_ALLOCATOR |
621 | free(U->keepers); | 621 | free(U->keepers); |
622 | #endif // LUAJIT_FLAVOR | 622 | #endif // USE_LUA_STATE_ALLOCATOR |
623 | U->keepers = NULL; | 623 | U->keepers = NULL; |
624 | } | 624 | } |
625 | } | 625 | } |
@@ -654,14 +654,14 @@ void init_keepers( Universe* U, lua_State* L) | |||
654 | { | 654 | { |
655 | size_t const bytes = sizeof( Keepers) + (nb_keepers - 1) * sizeof( Keeper); | 655 | size_t const bytes = sizeof( Keepers) + (nb_keepers - 1) * sizeof( Keeper); |
656 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly | 656 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly |
657 | #if LUAJIT_FLAVOR == 0 | 657 | #if USE_LUA_STATE_ALLOCATOR |
658 | { | 658 | { |
659 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 659 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; |
660 | U->keepers = (Keepers*) allocD->allocF( allocUD, NULL, 0, bytes); | 660 | U->keepers = (Keepers*) allocD->allocF( allocD->allocUD, NULL, 0, bytes); |
661 | } | 661 | } |
662 | #else // LUAJIT_FLAVOR | 662 | #else // USE_LUA_STATE_ALLOCATOR |
663 | U->keepers = (Keepers*)malloc(bytes); | 663 | U->keepers = (Keepers*)malloc(bytes); |
664 | #endif // LUAJIT_FLAVOR | 664 | #endif // USE_LUA_STATE_ALLOCATOR |
665 | if( U->keepers == NULL) | 665 | if( U->keepers == NULL) |
666 | { | 666 | { |
667 | (void) luaL_error( L, "init_keepers() failed while creating keeper array; out of memory"); | 667 | (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) | |||
254 | #endif // HAVE_LANE_TRACKING | 254 | #endif // HAVE_LANE_TRACKING |
255 | 255 | ||
256 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly | 256 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly |
257 | #if LUAJIT_FLAVOR == 0 | 257 | #if USE_LUA_STATE_ALLOCATOR |
258 | { | 258 | { |
259 | AllocatorDefinition* const allocD = &s->U->protected_allocator.definition; | 259 | AllocatorDefinition* const allocD = &s->U->protected_allocator.definition; |
260 | allocD->allocF(allocD->allocUD, s, sizeof(Lane), 0); | 260 | allocD->allocF(allocD->allocUD, s, sizeof(Lane), 0); |
261 | } | 261 | } |
262 | #else // LUAJIT_FLAVOR | 262 | #else // USE_LUA_STATE_ALLOCATOR |
263 | free(s); | 263 | free(s); |
264 | #endif // LUAJIT_FLAVOR | 264 | #endif // USE_LUA_STATE_ALLOCATOR |
265 | } | 265 | } |
266 | 266 | ||
267 | /* | 267 | /* |
@@ -1231,14 +1231,14 @@ LUAG_FUNC( lane_new) | |||
1231 | // a Lane full userdata needs a single uservalue | 1231 | // a Lane full userdata needs a single uservalue |
1232 | ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs priority globals package required gc_cb lane | 1232 | ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs priority globals package required gc_cb lane |
1233 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly | 1233 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly |
1234 | #if LUAJIT_FLAVOR == 0 | 1234 | #if USE_LUA_STATE_ALLOCATOR |
1235 | { | 1235 | { |
1236 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 1236 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; |
1237 | s = *ud = (Lane*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(Lane)); | 1237 | s = *ud = (Lane*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(Lane)); |
1238 | } | 1238 | } |
1239 | #else // LUAJIT_FLAVOR | 1239 | #else // USE_LUA_STATE_ALLOCATOR |
1240 | s = *ud = (Lane*) malloc(sizeof(Lane)); | 1240 | s = *ud = (Lane*) malloc(sizeof(Lane)); |
1241 | #endif // LUAJIT_FLAVOR | 1241 | #endif // USE_LUA_STATE_ALLOCATOR |
1242 | if( s == NULL) | 1242 | if( s == NULL) |
1243 | { | 1243 | { |
1244 | return luaL_error( L, "could not create lane: out of memory"); | 1244 | 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_) | |||
76 | track_lanes = false, | 76 | track_lanes = false, |
77 | demote_full_userdata = nil, | 77 | demote_full_userdata = nil, |
78 | verbose_errors = false, | 78 | verbose_errors = false, |
79 | allocator = nil | 79 | -- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes |
80 | allocator = (package.loaded.jit and jit.version) and "protected" or nil | ||
80 | } | 81 | } |
81 | local boolean_param_checker = function( val_) | 82 | local boolean_param_checker = function( val_) |
82 | -- non-'boolean-false' should be 'boolean-true' or nil | 83 | -- 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_) | |||
795 | * just don't use L's allocF because we don't know which state will get the honor of GCing the linda | 795 | * just don't use L's allocF because we don't know which state will get the honor of GCing the linda |
796 | */ | 796 | */ |
797 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly | 797 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly |
798 | #if LUAJIT_FLAVOR == 0 | 798 | #if USE_LUA_STATE_ALLOCATOR |
799 | { | 799 | { |
800 | Universe* const U = universe_get(L); | 800 | Universe* const U = universe_get(L); |
801 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 801 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; |
802 | 802 | ||
803 | s = (struct s_Linda*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(struct s_Linda) + name_len); // terminating 0 is already included | 803 | s = (struct s_Linda*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(struct s_Linda) + name_len); // terminating 0 is already included |
804 | } | 804 | } |
805 | #else // LUAJIT_FLAVOR | 805 | #else // USE_LUA_STATE_ALLOCATOR |
806 | s = (struct s_Linda*)malloc(sizeof(struct s_Linda) + name_len); // terminating 0 is already included | 806 | s = (struct s_Linda*)malloc(sizeof(struct s_Linda) + name_len); // terminating 0 is already included |
807 | #endif // LUAJIT_FLAVOR | 807 | #endif // USE_LUA_STATE_ALLOCATOR |
808 | if( s) | 808 | if( s) |
809 | { | 809 | { |
810 | s->prelude.magic.value = DEEP_VERSION.value; | 810 | s->prelude.magic.value = DEEP_VERSION.value; |
@@ -838,16 +838,16 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
838 | SIGNAL_FREE( &linda->read_happened); | 838 | SIGNAL_FREE( &linda->read_happened); |
839 | SIGNAL_FREE( &linda->write_happened); | 839 | SIGNAL_FREE( &linda->write_happened); |
840 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly | 840 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly |
841 | #if LUAJIT_FLAVOR == 0 | 841 | #if USE_LUA_STATE_ALLOCATOR |
842 | { | 842 | { |
843 | Universe* const U = universe_get(L); | 843 | Universe* const U = universe_get(L); |
844 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 844 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; |
845 | 845 | ||
846 | allocD->allocF(allocD->allocUD, linda, sizeof(struct s_Linda) + strlen(linda->name), 0); | 846 | allocD->allocF(allocD->allocUD, linda, sizeof(struct s_Linda) + strlen(linda->name), 0); |
847 | } | 847 | } |
848 | #else // LUAJIT_FLAVOR | 848 | #else // USE_LUA_STATE_ALLOCATOR |
849 | free(linda); | 849 | free(linda); |
850 | #endif // LUAJIT_FLAVOR | 850 | #endif // USE_LUA_STATE_ALLOCATOR |
851 | return NULL; | 851 | return NULL; |
852 | } | 852 | } |
853 | 853 | ||
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; | |||
109 | #define LUAJIT_FLAVOR 0 | 109 | #define LUAJIT_FLAVOR 0 |
110 | #endif // LUA_JITLIBNAME | 110 | #endif // LUA_JITLIBNAME |
111 | 111 | ||
112 | // 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 | ||
113 | #define USE_LUA_STATE_ALLOCATOR 1 // (LUAJIT_FLAVOR==0) | ||
114 | |||
112 | #endif // MACROS_AND_UTILS_H | 115 | #endif // MACROS_AND_UTILS_H |