diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/deep.c | 2 | ||||
-rw-r--r-- | src/keeper.c | 20 | ||||
-rw-r--r-- | src/keeper.h | 2 | ||||
-rw-r--r-- | src/lanes.c | 16 | ||||
-rw-r--r-- | src/lanes.h | 2 | ||||
-rw-r--r-- | src/lanes.lua | 8 | ||||
-rw-r--r-- | src/linda.c | 14 | ||||
-rw-r--r-- | src/macros_and_utils.h | 3 | ||||
-rw-r--r-- | src/tools.c | 38 | ||||
-rw-r--r-- | src/universe.h | 2 |
10 files changed, 54 insertions, 53 deletions
@@ -389,7 +389,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_) | |||
389 | DeepPrelude* prelude = idfunc( L, eDO_new); | 389 | DeepPrelude* prelude = idfunc( L, eDO_new); |
390 | if( prelude == NULL) | 390 | if( prelude == NULL) |
391 | { | 391 | { |
392 | luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); | 392 | return luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); |
393 | } | 393 | } |
394 | if( prelude->magic.value != DEEP_VERSION.value) | 394 | if( prelude->magic.value != DEEP_VERSION.value) |
395 | { | 395 | { |
diff --git a/src/keeper.c b/src/keeper.c index 19b9e1a..f4dde0a 100644 --- a/src/keeper.c +++ b/src/keeper.c | |||
@@ -580,7 +580,7 @@ int keepercall_count( lua_State* L) | |||
580 | */ | 580 | */ |
581 | 581 | ||
582 | // called as __gc for the keepers array userdata | 582 | // called as __gc for the keepers array userdata |
583 | void close_keepers( Universe* U, lua_State* L) | 583 | void close_keepers( Universe* U) |
584 | { | 584 | { |
585 | if( U->keepers != NULL) | 585 | if( U->keepers != NULL) |
586 | { | 586 | { |
@@ -611,15 +611,8 @@ void close_keepers( Universe* U, lua_State* L) | |||
611 | } | 611 | } |
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 | AllocatorDefinition* const allocD = &U->internal_allocator; |
615 | #if USE_LUA_STATE_ALLOCATOR() | 615 | allocD->allocF( allocD->allocUD, U->keepers, sizeof( Keepers) + (nbKeepers - 1) * sizeof( Keeper), 0); |
616 | { | ||
617 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | ||
618 | allocD->allocF( allocD->allocUD, U->keepers, sizeof( Keepers) + (nbKeepers - 1) * sizeof( Keeper), 0); | ||
619 | } | ||
620 | #else // USE_LUA_STATE_ALLOCATOR() | ||
621 | free(U->keepers); | ||
622 | #endif // USE_LUA_STATE_ALLOCATOR() | ||
623 | U->keepers = NULL; | 616 | U->keepers = NULL; |
624 | } | 617 | } |
625 | } | 618 | } |
@@ -653,15 +646,10 @@ void init_keepers( Universe* U, lua_State* L) | |||
653 | // Keepers contains an array of 1 s_Keeper, adjust for the actual number of keeper states | 646 | // Keepers contains an array of 1 s_Keeper, adjust for the actual number of keeper states |
654 | { | 647 | { |
655 | size_t const bytes = sizeof( Keepers) + (nb_keepers - 1) * sizeof( Keeper); | 648 | 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 | ||
657 | #if USE_LUA_STATE_ALLOCATOR() | ||
658 | { | 649 | { |
659 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 650 | AllocatorDefinition* const allocD = &U->internal_allocator; |
660 | U->keepers = (Keepers*) allocD->allocF( allocD->allocUD, NULL, 0, bytes); | 651 | U->keepers = (Keepers*) allocD->allocF( allocD->allocUD, NULL, 0, bytes); |
661 | } | 652 | } |
662 | #else // USE_LUA_STATE_ALLOCATOR() | ||
663 | U->keepers = (Keepers*)malloc(bytes); | ||
664 | #endif // USE_LUA_STATE_ALLOCATOR() | ||
665 | if( U->keepers == NULL) | 653 | if( U->keepers == NULL) |
666 | { | 654 | { |
667 | (void) luaL_error( L, "init_keepers() failed while creating keeper array; out of memory"); | 655 | (void) luaL_error( L, "init_keepers() failed while creating keeper array; out of memory"); |
diff --git a/src/keeper.h b/src/keeper.h index 8c09322..d30aa36 100644 --- a/src/keeper.h +++ b/src/keeper.h | |||
@@ -27,7 +27,7 @@ struct s_Keepers | |||
27 | typedef struct s_Keepers Keepers; | 27 | typedef struct s_Keepers Keepers; |
28 | 28 | ||
29 | void init_keepers( Universe* U, lua_State* L); | 29 | void init_keepers( Universe* U, lua_State* L); |
30 | void close_keepers( Universe* U, lua_State* L); | 30 | void close_keepers( Universe* U); |
31 | 31 | ||
32 | Keeper* which_keeper( Keepers* keepers_, ptrdiff_t magic_); | 32 | Keeper* which_keeper( Keepers* keepers_, ptrdiff_t magic_); |
33 | Keeper* keeper_acquire( Keepers* keepers_, ptrdiff_t magic_); | 33 | Keeper* keeper_acquire( Keepers* keepers_, ptrdiff_t magic_); |
diff --git a/src/lanes.c b/src/lanes.c index 9f6a4d6..0aab244 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -253,15 +253,10 @@ static void lane_cleanup( Lane* s) | |||
253 | } | 253 | } |
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 | ||
257 | #if USE_LUA_STATE_ALLOCATOR() | ||
258 | { | 256 | { |
259 | AllocatorDefinition* const allocD = &s->U->protected_allocator.definition; | 257 | AllocatorDefinition* const allocD = &s->U->internal_allocator; |
260 | allocD->allocF(allocD->allocUD, s, sizeof(Lane), 0); | 258 | allocD->allocF(allocD->allocUD, s, sizeof(Lane), 0); |
261 | } | 259 | } |
262 | #else // USE_LUA_STATE_ALLOCATOR() | ||
263 | free(s); | ||
264 | #endif // USE_LUA_STATE_ALLOCATOR() | ||
265 | } | 260 | } |
266 | 261 | ||
267 | /* | 262 | /* |
@@ -584,7 +579,7 @@ static int selfdestruct_gc( lua_State* L) | |||
584 | U->timer_deep = NULL; | 579 | U->timer_deep = NULL; |
585 | } | 580 | } |
586 | 581 | ||
587 | close_keepers( U, L); | 582 | close_keepers( U); |
588 | 583 | ||
589 | // remove the protected allocator, if any | 584 | // remove the protected allocator, if any |
590 | cleanup_allocator_function( U, L); | 585 | cleanup_allocator_function( U, L); |
@@ -1231,15 +1226,10 @@ LUAG_FUNC( lane_new) | |||
1231 | // | 1226 | // |
1232 | // a Lane full userdata needs a single uservalue | 1227 | // a Lane full userdata needs a single uservalue |
1233 | ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs priority globals package required gc_cb lane | 1228 | ud = lua_newuserdatauv( L, sizeof( Lane*), 1); // func libs priority globals package required gc_cb lane |
1234 | // don't hijack the state allocator when running LuaJIT because it looks like LuaJIT does not expect it and might invalidate the memory unexpectedly | ||
1235 | #if USE_LUA_STATE_ALLOCATOR() | ||
1236 | { | 1229 | { |
1237 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 1230 | AllocatorDefinition* const allocD = &U->internal_allocator; |
1238 | s = *ud = (Lane*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(Lane)); | 1231 | s = *ud = (Lane*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(Lane)); |
1239 | } | 1232 | } |
1240 | #else // USE_LUA_STATE_ALLOCATOR() | ||
1241 | s = *ud = (Lane*) malloc(sizeof(Lane)); | ||
1242 | #endif // USE_LUA_STATE_ALLOCATOR() | ||
1243 | if( s == NULL) | 1233 | if( s == NULL) |
1244 | { | 1234 | { |
1245 | return luaL_error( L, "could not create lane: out of memory"); | 1235 | return luaL_error( L, "could not create lane: out of memory"); |
diff --git a/src/lanes.h b/src/lanes.h index 20524e6..420b31d 100644 --- a/src/lanes.h +++ b/src/lanes.h | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #define LANES_VERSION_MAJOR 3 | 13 | #define LANES_VERSION_MAJOR 3 |
14 | #define LANES_VERSION_MINOR 16 | 14 | #define LANES_VERSION_MINOR 16 |
15 | #define LANES_VERSION_PATCH 0 | 15 | #define LANES_VERSION_PATCH 1 |
16 | 16 | ||
17 | #define LANES_MIN_VERSION_REQUIRED(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR>MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR>MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH>=PATCH)))) | 17 | #define LANES_MIN_VERSION_REQUIRED(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR>MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR>MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH>=PATCH)))) |
18 | #define LANES_VERSION_LESS_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR<MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR<MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH<PATCH)))) | 18 | #define LANES_VERSION_LESS_THAN(MAJOR, MINOR, PATCH) ((LANES_VERSION_MAJOR<MAJOR) || (LANES_VERSION_MAJOR==MAJOR && (LANES_VERSION_MINOR<MINOR || (LANES_VERSION_MINOR==MINOR && LANES_VERSION_PATCH<PATCH)))) |
diff --git a/src/lanes.lua b/src/lanes.lua index 0858ad7..cbcf74f 100644 --- a/src/lanes.lua +++ b/src/lanes.lua | |||
@@ -77,7 +77,9 @@ lanes.configure = function( settings_) | |||
77 | demote_full_userdata = nil, | 77 | demote_full_userdata = nil, |
78 | verbose_errors = false, | 78 | verbose_errors = false, |
79 | -- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes | 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 | allocator = (package.loaded.jit and jit.version) and "protected" or nil, |
81 | -- it looks also like LuaJIT allocator may not appreciate direct use of its allocator for other purposes than the VM operation | ||
82 | internal_allocator = (package.loaded.jit and jit.version) and "libc" or "allocator" | ||
81 | } | 83 | } |
82 | local boolean_param_checker = function( val_) | 84 | local boolean_param_checker = function( val_) |
83 | -- non-'boolean-false' should be 'boolean-true' or nil | 85 | -- non-'boolean-false' should be 'boolean-true' or nil |
@@ -94,6 +96,10 @@ lanes.configure = function( settings_) | |||
94 | -- can be nil, "protected", or a function | 96 | -- can be nil, "protected", or a function |
95 | return val_ and (type( val_) == "function" or val_ == "protected") or true | 97 | return val_ and (type( val_) == "function" or val_ == "protected") or true |
96 | end, | 98 | end, |
99 | internal_allocator = function( val_) | ||
100 | -- can be "libc" or "allocator" | ||
101 | return val_ == "libc" or val_ == "allocator" | ||
102 | end, | ||
97 | on_state_create = function( val_) | 103 | on_state_create = function( val_) |
98 | -- on_state_create may be nil or a function | 104 | -- on_state_create may be nil or a function |
99 | return val_ and type( val_) == "function" or true | 105 | return val_ and type( val_) == "function" or true |
diff --git a/src/linda.c b/src/linda.c index 637f909..390816b 100644 --- a/src/linda.c +++ b/src/linda.c | |||
@@ -794,17 +794,12 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
794 | * One can use any memory allocation scheme. | 794 | * One can use any memory allocation scheme. |
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 | ||
798 | #if USE_LUA_STATE_ALLOCATOR() | ||
799 | { | 797 | { |
800 | Universe* const U = universe_get(L); | 798 | Universe* const U = universe_get(L); |
801 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 799 | AllocatorDefinition* const allocD = &U->internal_allocator; |
802 | 800 | ||
803 | s = (struct s_Linda*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(struct s_Linda) + name_len); // terminating 0 is already included | 801 | s = (struct s_Linda*)allocD->allocF(allocD->allocUD, NULL, 0, sizeof(struct s_Linda) + name_len); // terminating 0 is already included |
804 | } | 802 | } |
805 | #else // USE_LUA_STATE_ALLOCATOR() | ||
806 | s = (struct s_Linda*)malloc(sizeof(struct s_Linda) + name_len); // terminating 0 is already included | ||
807 | #endif // USE_LUA_STATE_ALLOCATOR() | ||
808 | if( s) | 803 | if( s) |
809 | { | 804 | { |
810 | s->prelude.magic.value = DEEP_VERSION.value; | 805 | s->prelude.magic.value = DEEP_VERSION.value; |
@@ -837,17 +832,12 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
837 | // There aren't any lanes waiting on these lindas, since all proxies have been gc'ed. Right? | 832 | // There aren't any lanes waiting on these lindas, since all proxies have been gc'ed. Right? |
838 | SIGNAL_FREE( &linda->read_happened); | 833 | SIGNAL_FREE( &linda->read_happened); |
839 | SIGNAL_FREE( &linda->write_happened); | 834 | 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 | ||
841 | #if USE_LUA_STATE_ALLOCATOR() | ||
842 | { | 835 | { |
843 | Universe* const U = universe_get(L); | 836 | Universe* const U = universe_get(L); |
844 | AllocatorDefinition* const allocD = &U->protected_allocator.definition; | 837 | AllocatorDefinition* const allocD = &U->internal_allocator; |
845 | 838 | ||
846 | allocD->allocF(allocD->allocUD, linda, sizeof(struct s_Linda) + strlen(linda->name), 0); | 839 | allocD->allocF(allocD->allocUD, linda, sizeof(struct s_Linda) + strlen(linda->name), 0); |
847 | } | 840 | } |
848 | #else // USE_LUA_STATE_ALLOCATOR() | ||
849 | free(linda); | ||
850 | #endif // USE_LUA_STATE_ALLOCATOR() | ||
851 | return NULL; | 841 | return NULL; |
852 | } | 842 | } |
853 | 843 | ||
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index 3ed234a..05a46b5 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h | |||
@@ -99,7 +99,4 @@ extern char const* debugspew_indent; | |||
99 | 99 | ||
100 | #define LUAG_FUNC( func_name) int LG_##func_name( lua_State* L) | 100 | #define LUAG_FUNC( func_name) int LG_##func_name( lua_State* L) |
101 | 101 | ||
102 | // 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 | ||
103 | #define USE_LUA_STATE_ALLOCATOR() 1 // (LUAJIT_FLAVOR()==0) | ||
104 | |||
105 | #endif // MACROS_AND_UTILS_H | 102 | #endif // MACROS_AND_UTILS_H |
diff --git a/src/tools.c b/src/tools.c index 626da2b..5a6ae92 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -155,6 +155,20 @@ void luaG_dump( lua_State* L) | |||
155 | 155 | ||
156 | // ################################################################################################ | 156 | // ################################################################################################ |
157 | 157 | ||
158 | static void* libc_lua_Alloc(void* ud, void* ptr, size_t osize, size_t nsize) | ||
159 | { | ||
160 | (void)ud; (void)osize; /* not used */ | ||
161 | if (nsize == 0) | ||
162 | { | ||
163 | free(ptr); | ||
164 | return NULL; | ||
165 | } | ||
166 | else | ||
167 | { | ||
168 | return realloc(ptr, nsize); | ||
169 | } | ||
170 | } | ||
171 | |||
158 | static void* protected_lua_Alloc( void *ud, void *ptr, size_t osize, size_t nsize) | 172 | static void* protected_lua_Alloc( void *ud, void *ptr, size_t osize, size_t nsize) |
159 | { | 173 | { |
160 | void* p; | 174 | void* p; |
@@ -217,6 +231,22 @@ void initialize_allocator_function( Universe* U, lua_State* L) | |||
217 | U->protected_allocator.definition.allocF = lua_getallocf( L, &U->protected_allocator.definition.allocUD); | 231 | U->protected_allocator.definition.allocF = lua_getallocf( L, &U->protected_allocator.definition.allocUD); |
218 | } | 232 | } |
219 | lua_pop( L, 1); // settings | 233 | lua_pop( L, 1); // settings |
234 | STACK_MID(L, 0); | ||
235 | |||
236 | lua_getfield( L, -1, "internal_allocator"); // settings "libc"|"allocator" | ||
237 | { | ||
238 | char const* allocator = lua_tostring( L, -1); | ||
239 | if (stricmp(allocator, "libc") == 0) | ||
240 | { | ||
241 | U->internal_allocator.allocF = libc_lua_Alloc; | ||
242 | U->internal_allocator.allocUD = NULL; | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | U->internal_allocator = U->protected_allocator.definition; | ||
247 | } | ||
248 | } | ||
249 | lua_pop( L, 1); // settings | ||
220 | STACK_END( L, 0); | 250 | STACK_END( L, 0); |
221 | } | 251 | } |
222 | 252 | ||
@@ -1337,17 +1367,17 @@ static void copy_cached_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua | |||
1337 | 1367 | ||
1338 | if( lua_isnil( L2, -1)) // function is unknown | 1368 | if( lua_isnil( L2, -1)) // function is unknown |
1339 | { | 1369 | { |
1340 | lua_pop( L2, 1); // ... {cache} ... p | 1370 | lua_pop( L2, 1); // ... {cache} ... p |
1341 | 1371 | ||
1342 | // Set to 'true' for the duration of creation; need to find self-references | 1372 | // Set to 'true' for the duration of creation; need to find self-references |
1343 | // via upvalues | 1373 | // via upvalues |
1344 | // | 1374 | // |
1345 | // pushes a copy of the func, stores a reference in the cache | 1375 | // pushes a copy of the func, stores a reference in the cache |
1346 | copy_func( U, L2, L2_cache_i, L, i, mode_, upName_); // ... {cache} ... function | 1376 | copy_func( U, L2, L2_cache_i, L, i, mode_, upName_); // ... {cache} ... function |
1347 | } | 1377 | } |
1348 | else // found function in the cache | 1378 | else // found function in the cache |
1349 | { | 1379 | { |
1350 | lua_remove( L2, -2); // ... {cache} ... function | 1380 | lua_remove( L2, -2); // ... {cache} ... function |
1351 | } | 1381 | } |
1352 | STACK_END( L2, 1); | 1382 | STACK_END( L2, 1); |
1353 | ASSERT_L( lua_isfunction( L2, -1)); | 1383 | ASSERT_L( lua_isfunction( L2, -1)); |
@@ -1725,9 +1755,7 @@ static bool_t inter_copy_function( Universe* U, lua_State* L2, uint_t L2_cache_i | |||
1725 | { | 1755 | { |
1726 | DEBUGSPEW_CODE( fprintf( stderr, "FUNCTION %s\n", upName_)); | 1756 | DEBUGSPEW_CODE( fprintf( stderr, "FUNCTION %s\n", upName_)); |
1727 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1757 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1728 | STACK_CHECK( L2, 0); | ||
1729 | copy_cached_func( U, L2, L2_cache_i, L, source_i_, mode_, upName_); // ... f | 1758 | copy_cached_func( U, L2, L2_cache_i, L, source_i_, mode_, upName_); // ... f |
1730 | STACK_END( L2, 1); | ||
1731 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1759 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
1732 | } | 1760 | } |
1733 | STACK_END( L2, 1); | 1761 | STACK_END( L2, 1); |
diff --git a/src/universe.h b/src/universe.h index ba00e87..03c78cf 100644 --- a/src/universe.h +++ b/src/universe.h | |||
@@ -63,6 +63,8 @@ struct s_Universe | |||
63 | // contains a mutex and the original allocator definition | 63 | // contains a mutex and the original allocator definition |
64 | ProtectedAllocator protected_allocator; | 64 | ProtectedAllocator protected_allocator; |
65 | 65 | ||
66 | AllocatorDefinition internal_allocator; | ||
67 | |||
66 | Keepers* keepers; | 68 | Keepers* keepers; |
67 | 69 | ||
68 | // Initialized by 'init_once_LOCKED()': the deep userdata Linda object | 70 | // Initialized by 'init_once_LOCKED()': the deep userdata Linda object |