diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2023-08-09 12:15:54 +0200 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2023-08-09 12:15:54 +0200 |
commit | ad7258f68ce525845508fc0c4a329c282982ffa0 (patch) | |
tree | f6eb169911eef0a776f3b3b00eeb2b7d824ebbd7 | |
parent | d73f4cee37b0a43edadf9709289798ee4bfccc0e (diff) | |
download | lanes-ad7258f68ce525845508fc0c4a329c282982ffa0.tar.gz lanes-ad7258f68ce525845508fc0c4a329c282982ffa0.tar.bz2 lanes-ad7258f68ce525845508fc0c4a329c282982ffa0.zip |
new .internal_allocator configuration IUNTESTED)
new configuration option .internal_allocator to help LuaJIT users. THIS IS YET UNTESTED, USE AT YOUR OWN RISKS.
-rw-r--r-- | .vs/Lanes/FileContentIndex/7013d1f4-51ff-4696-9603-47b7bcd2f51f.vsidx | bin | 0 -> 400863 bytes | |||
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | docs/index.html | 34 | ||||
-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 |
13 files changed, 83 insertions, 62 deletions
diff --git a/.vs/Lanes/FileContentIndex/7013d1f4-51ff-4696-9603-47b7bcd2f51f.vsidx b/.vs/Lanes/FileContentIndex/7013d1f4-51ff-4696-9603-47b7bcd2f51f.vsidx new file mode 100644 index 0000000..7c4c705 --- /dev/null +++ b/.vs/Lanes/FileContentIndex/7013d1f4-51ff-4696-9603-47b7bcd2f51f.vsidx | |||
Binary files differ | |||
@@ -1,5 +1,9 @@ | |||
1 | CHANGES: | 1 | CHANGES: |
2 | 2 | ||
3 | CHANGE 156: BGe 9-Aug-23 | ||
4 | * new configuration option .internal_allocator to help LuaJIT users. | ||
5 | * internal version bumped to 3.16.1 | ||
6 | |||
3 | CHANGE 155: BGe 28-Jul-23 | 7 | CHANGE 155: BGe 28-Jul-23 |
4 | * tweaks to linux thread priority management: do nothing if not super-user. if super-user, do nothing if nothing is provided (instead of trying to force a prio when LINUX_SCHED_RR is defined). | 8 | * tweaks to linux thread priority management: do nothing if not super-user. if super-user, do nothing if nothing is provided (instead of trying to force a prio when LINUX_SCHED_RR is defined). |
5 | 9 | ||
diff --git a/docs/index.html b/docs/index.html index 0e1a30b..b1c514d 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -64,13 +64,13 @@ | |||
64 | <font size="-1"> | 64 | <font size="-1"> |
65 | <p> | 65 | <p> |
66 | <br/> | 66 | <br/> |
67 | <i>Copyright © 2007-22 Asko Kauppi, Benoit Germain. All rights reserved.</i> | 67 | <i>Copyright © 2007-23 Asko Kauppi, Benoit Germain. All rights reserved.</i> |
68 | <br/> | 68 | <br/> |
69 | Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1, 5.2, 5.3 and 5.4. | 69 | Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1, 5.2, 5.3 and 5.4. |
70 | </p> | 70 | </p> |
71 | 71 | ||
72 | <p> | 72 | <p> |
73 | This document was revised on 8-Feb-22, and applies to version <tt>3.16.0</tt>. | 73 | This document was revised on 9-Aug-23, and applies to version <tt>3.16.1</tt>. |
74 | </p> | 74 | </p> |
75 | </font> | 75 | </font> |
76 | </center> | 76 | </center> |
@@ -338,9 +338,9 @@ | |||
338 | <tt>nil</tt>/<tt>"protected"</tt>/function | 338 | <tt>nil</tt>/<tt>"protected"</tt>/function |
339 | </td> | 339 | </td> |
340 | <td> | 340 | <td> |
341 | (Since v3.13.0)<br/> | 341 | (Since v3.13.0)<br /> |
342 | If <tt>nil</tt>, Lua states are created with <tt>lua_newstate()</tt> and reuse the allocator from the master state.<br/> | 342 | If <tt>nil</tt>, Lua states are created with <tt>lua_newstate()</tt> and reuse the allocator from the master state.<br /> |
343 | If <tt>"protected"</tt>, The default allocator obtained from <tt>lua_getallocf()</tt> in the master state is wrapped inside a critical section and used in all newly created states.<br/> | 343 | If <tt>"protected"</tt>, The default allocator obtained from <tt>lua_getallocf()</tt> in the master state is wrapped inside a critical section and used in all newly created states.<br /> |
344 | If a <tt>function</tt>, this function is called prior to creating the state. It should return a full userdata containing the following structure: | 344 | If a <tt>function</tt>, this function is called prior to creating the state. It should return a full userdata containing the following structure: |
345 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> | 345 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> |
346 | <tr> | 346 | <tr> |
@@ -356,6 +356,22 @@ | |||
356 | </tr> | 356 | </tr> |
357 | 357 | ||
358 | <tr valign=top> | 358 | <tr valign=top> |
359 | <td id="internal_allocator"> | ||
360 | <code>.internal_allocator</code> | ||
361 | </td> | ||
362 | <td> | ||
363 | <tt>"libc"</tt>/<tt>"allocator"</tt> | ||
364 | </td> | ||
365 | <td> | ||
366 | (Since v3.16.1)<br /> | ||
367 | Controls which allocator is used for Lanest internal allocations (for keeper and deep userdata management). | ||
368 | If <tt>"libc"</tt>, Lanes uses <tt>realloc</tt> and <tt>free</tt>.<br /> | ||
369 | If <tt>"allocator"</tt>, Lanes uses whatever was obtained from the <tt>"allocator"</tt> setting.<br /> | ||
370 | This option is mostly useful for embedders that want control all memory allocations, but have issues when Lanes tries to use the Lua State allocator for internal purposes (especially with LuaJIT). | ||
371 | </td> | ||
372 | </tr> | ||
373 | |||
374 | <tr valign=top> | ||
359 | <td id="demote_full_userdata"> | 375 | <td id="demote_full_userdata"> |
360 | <code>.demote_full_userdata</code> | 376 | <code>.demote_full_userdata</code> |
361 | </td> | 377 | </td> |
@@ -390,18 +406,18 @@ | |||
390 | </td> | 406 | </td> |
391 | <td> | 407 | <td> |
392 | If provided, will be called in every created Lua state right after initializing the base libraries. | 408 | If provided, will be called in every created Lua state right after initializing the base libraries. |
393 | <br/> | 409 | <br /> |
394 | Keeper states will call it as well, but only if it is a C function (keeper states are not able to execute any user Lua code). | 410 | Keeper states will call it as well, but only if it is a C function (keeper states are not able to execute any user Lua code). |
395 | <br/> | 411 | <br /> |
396 | Typical usage is twofold: | 412 | Typical usage is twofold: |
397 | <ul> | 413 | <ul> |
398 | <li>Tweak <tt>package.loaders</tt></li> | 414 | <li>Tweak <tt>package.loaders</tt></li> |
399 | <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> | 415 | <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> |
400 | </ul> | 416 | </ul> |
401 | That way, all changes in the state can be properly taken into account when building the function lookup database. Default is <tt>nil</tt>. | 417 | That way, all changes in the state can be properly taken into account when building the function lookup database. Default is <tt>nil</tt>. |
402 | <br/> | 418 | <br /> |
403 | (Since version 3.7.6) If <tt>on_state_create()</tt> is a Lua function, it will be transfered normally before the call. | 419 | (Since version 3.7.6) If <tt>on_state_create()</tt> is a Lua function, it will be transfered normally before the call. |
404 | <br/> | 420 | <br /> |
405 | If it is a C function, a C closure will be reconstructed in the created state from the C pointer. Lanes will raise an error if the function has upvalues. | 421 | If it is a C function, a C closure will be reconstructed in the created state from the C pointer. Lanes will raise an error if the function has upvalues. |
406 | </td> | 422 | </td> |
407 | </tr> | 423 | </tr> |
@@ -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 |