aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/deep.c2
-rw-r--r--src/keeper.c20
-rw-r--r--src/keeper.h2
-rw-r--r--src/lanes.c16
-rw-r--r--src/lanes.h2
-rw-r--r--src/lanes.lua8
-rw-r--r--src/linda.c14
-rw-r--r--src/macros_and_utils.h3
-rw-r--r--src/tools.c38
-rw-r--r--src/universe.h2
10 files changed, 54 insertions, 53 deletions
diff --git a/src/deep.c b/src/deep.c
index c475dc5..9496477 100644
--- a/src/deep.c
+++ b/src/deep.c
@@ -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
583void close_keepers( Universe* U, lua_State* L) 583void 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
27typedef struct s_Keepers Keepers; 27typedef struct s_Keepers Keepers;
28 28
29void init_keepers( Universe* U, lua_State* L); 29void init_keepers( Universe* U, lua_State* L);
30void close_keepers( Universe* U, lua_State* L); 30void close_keepers( Universe* U);
31 31
32Keeper* which_keeper( Keepers* keepers_, ptrdiff_t magic_); 32Keeper* which_keeper( Keepers* keepers_, ptrdiff_t magic_);
33Keeper* keeper_acquire( Keepers* keepers_, ptrdiff_t magic_); 33Keeper* 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
158static 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
158static void* protected_lua_Alloc( void *ud, void *ptr, size_t osize, size_t nsize) 172static 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