diff options
Diffstat (limited to 'src/keeper.cpp')
-rw-r--r-- | src/keeper.cpp | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index 244cb6a..937d190 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
@@ -652,12 +652,18 @@ void init_keepers(Universe* U, lua_State* L) | |||
652 | { | 652 | { |
653 | STACK_CHECK_START_REL(L, 0); // L K | 653 | STACK_CHECK_START_REL(L, 0); // L K |
654 | lua_getfield(L, 1, "nb_keepers"); // nb_keepers | 654 | lua_getfield(L, 1, "nb_keepers"); // nb_keepers |
655 | int nb_keepers{ static_cast<int>(lua_tointeger(L, -1)) }; | 655 | int const nb_keepers{ static_cast<int>(lua_tointeger(L, -1)) }; |
656 | lua_pop(L, 1); // | 656 | lua_pop(L, 1); // |
657 | if (nb_keepers < 1) | 657 | if (nb_keepers < 1) |
658 | { | 658 | { |
659 | std::ignore = luaL_error(L, "Bad number of keepers (%d)", nb_keepers); | 659 | std::ignore = luaL_error(L, "Bad number of keepers (%d)", nb_keepers); |
660 | } | 660 | } |
661 | STACK_CHECK(L, 0); | ||
662 | |||
663 | lua_getfield(L, 1, "keepers_gc_threshold"); // keepers_gc_threshold | ||
664 | int const keepers_gc_threshold{ static_cast<int>(lua_tointeger(L, -1)) }; | ||
665 | lua_pop(L, 1); // | ||
666 | STACK_CHECK(L, 0); | ||
661 | 667 | ||
662 | // Keepers contains an array of 1 Keeper, adjust for the actual number of keeper states | 668 | // Keepers contains an array of 1 Keeper, adjust for the actual number of keeper states |
663 | { | 669 | { |
@@ -668,6 +674,7 @@ void init_keepers(Universe* U, lua_State* L) | |||
668 | std::ignore = luaL_error(L, "init_keepers() failed while creating keeper array; out of memory"); | 674 | std::ignore = luaL_error(L, "init_keepers() failed while creating keeper array; out of memory"); |
669 | } | 675 | } |
670 | memset(U->keepers, 0, bytes); | 676 | memset(U->keepers, 0, bytes); |
677 | U->keepers->gc_threshold = keepers_gc_threshold; | ||
671 | U->keepers->nb_keepers = nb_keepers; | 678 | U->keepers->nb_keepers = nb_keepers; |
672 | } | 679 | } |
673 | for (int i = 0; i < nb_keepers; ++i) // keepersUD | 680 | for (int i = 0; i < nb_keepers; ++i) // keepersUD |
@@ -685,6 +692,11 @@ void init_keepers(Universe* U, lua_State* L) | |||
685 | // therefore, we need a recursive mutex. | 692 | // therefore, we need a recursive mutex. |
686 | MUTEX_RECURSIVE_INIT(&U->keepers->keeper_array[i].keeper_cs); | 693 | MUTEX_RECURSIVE_INIT(&U->keepers->keeper_array[i].keeper_cs); |
687 | 694 | ||
695 | if (U->keepers->gc_threshold >= 0) | ||
696 | { | ||
697 | lua_gc(K, LUA_GCSTOP, 0); | ||
698 | } | ||
699 | |||
688 | STACK_CHECK_START_ABS(K, 0); | 700 | STACK_CHECK_START_ABS(K, 0); |
689 | 701 | ||
690 | // copy the universe pointer in the keeper itself | 702 | // copy the universe pointer in the keeper itself |
@@ -735,8 +747,12 @@ void init_keepers(Universe* U, lua_State* L) | |||
735 | Keeper* which_keeper(Keepers* keepers_, uintptr_t magic_) | 747 | Keeper* which_keeper(Keepers* keepers_, uintptr_t magic_) |
736 | { | 748 | { |
737 | int const nbKeepers{ keepers_->nb_keepers }; | 749 | int const nbKeepers{ keepers_->nb_keepers }; |
738 | unsigned int i = (unsigned int)((magic_ >> KEEPER_MAGIC_SHIFT) % nbKeepers); | 750 | if (nbKeepers) |
739 | return &keepers_->keeper_array[i]; | 751 | { |
752 | unsigned int i = (unsigned int) ((magic_ >> KEEPER_MAGIC_SHIFT) % nbKeepers); | ||
753 | return &keepers_->keeper_array[i]; | ||
754 | } | ||
755 | return nullptr; | ||
740 | } | 756 | } |
741 | 757 | ||
742 | // ################################################################################################## | 758 | // ################################################################################################## |
@@ -745,11 +761,7 @@ Keeper* keeper_acquire(Keepers* keepers_, uintptr_t magic_) | |||
745 | { | 761 | { |
746 | int const nbKeepers{ keepers_->nb_keepers }; | 762 | int const nbKeepers{ keepers_->nb_keepers }; |
747 | // can be 0 if this happens during main state shutdown (lanes is being GC'ed -> no keepers) | 763 | // can be 0 if this happens during main state shutdown (lanes is being GC'ed -> no keepers) |
748 | if( nbKeepers == 0) | 764 | if (nbKeepers) |
749 | { | ||
750 | return nullptr; | ||
751 | } | ||
752 | else | ||
753 | { | 765 | { |
754 | /* | 766 | /* |
755 | * Any hashing will do that maps pointers to 0..GNbKeepers-1 | 767 | * Any hashing will do that maps pointers to 0..GNbKeepers-1 |
@@ -765,6 +777,7 @@ Keeper* keeper_acquire(Keepers* keepers_, uintptr_t magic_) | |||
765 | //++ K->count; | 777 | //++ K->count; |
766 | return K; | 778 | return K; |
767 | } | 779 | } |
780 | return nullptr; | ||
768 | } | 781 | } |
769 | 782 | ||
770 | // ################################################################################################## | 783 | // ################################################################################################## |
@@ -843,5 +856,30 @@ int keeper_call(Universe* U, lua_State* K, keeper_api_t func_, lua_State* L, voi | |||
843 | } | 856 | } |
844 | // whatever happens, restore the stack to where it was at the origin | 857 | // whatever happens, restore the stack to where it was at the origin |
845 | lua_settop(K, Ktos); | 858 | lua_settop(K, Ktos); |
859 | |||
860 | // don't do this for this particular function, as it is only called during Linda destruction, and we don't want to raise an error, ever | ||
861 | if (func_ != KEEPER_API(clear)) [[unlikely]] | ||
862 | { | ||
863 | // since keeper state GC is stopped, let's run a step once in a while if required | ||
864 | int const gc_threshold{ U->keepers->gc_threshold }; | ||
865 | if (gc_threshold == 0) [[unlikely]] | ||
866 | { | ||
867 | lua_gc(K, LUA_GCSTEP, 0); | ||
868 | } | ||
869 | else if (gc_threshold > 0) [[likely]] | ||
870 | { | ||
871 | int const gc_usage{ lua_gc(K, LUA_GCCOUNT, 0) }; | ||
872 | if (gc_usage >= gc_threshold) | ||
873 | { | ||
874 | lua_gc(K, LUA_GCCOLLECT, 0); | ||
875 | int const gc_usage_after{ lua_gc(K, LUA_GCCOUNT, 0) }; | ||
876 | if (gc_usage_after > gc_threshold) [[unlikely]] | ||
877 | { | ||
878 | luaL_error(L, "Keeper GC threshold is too low, need at least %d", gc_usage_after); | ||
879 | } | ||
880 | } | ||
881 | } | ||
882 | } | ||
883 | |||
846 | return retvals; | 884 | return retvals; |
847 | } | 885 | } |