aboutsummaryrefslogtreecommitdiff
path: root/src/keeper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/keeper.cpp')
-rw-r--r--src/keeper.cpp36
1 files changed, 11 insertions, 25 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp
index cad9207..c8c470f 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -811,22 +811,6 @@ KeeperCallResult keeper_call(KeeperState const K_, keeper_api_t const func_, lua
811// ################################################################################################# 811// #################################################################################################
812// ################################################################################################# 812// #################################################################################################
813 813
814void* Keeper::operator new[](size_t size_, Universe* U_) noexcept
815{
816 // size_ is the memory for the element count followed by the elements themselves
817 return U_->internalAllocator.alloc(size_);
818}
819
820// #################################################################################################
821
822// can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception
823void Keeper::operator delete[](void* p_, Universe* U_)
824{
825 U_->internalAllocator.free(p_, *static_cast<size_t*>(p_) * sizeof(Keeper) + sizeof(size_t));
826}
827
828// #################################################################################################
829
830// only used by linda:dump() and linda:__towatch() for debugging purposes 814// only used by linda:dump() and linda:__towatch() for debugging purposes
831// table is populated as follows: 815// table is populated as follows:
832// { 816// {
@@ -927,7 +911,7 @@ void Keepers::DeleteKV::operator()(Keeper* const k_) const
927 for (auto& _k : std::span<Keeper>(k_, count)) { 911 for (auto& _k : std::span<Keeper>(k_, count)) {
928 _k.~Keeper(); 912 _k.~Keeper();
929 } 913 }
930 U->internalAllocator.free(k_, count * sizeof(Keeper)); 914 U.internalAllocator.free(k_, count * sizeof(Keeper));
931} 915}
932 916
933// ################################################################################################# 917// #################################################################################################
@@ -959,8 +943,8 @@ void Keepers::collectGarbage()
959 // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists 943 // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists
960 // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success 944 // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success
961 // which is early-outed with a keepers->nbKeepers null-check 945 // which is early-outed with a keepers->nbKeepers null-check
962 for (size_t const _i : std::ranges::iota_view{ size_t{ 0 }, _kv.nbKeepers }) { 946 for (Keeper& _k : std::span<Keeper>{ _kv.keepers.get(), _kv.nbKeepers }) {
963 _gcOneKeeper(_kv.keepers[_i]); 947 _gcOneKeeper(_k);
964 } 948 }
965 } 949 }
966} 950}
@@ -996,9 +980,8 @@ void Keepers::close()
996 // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists 980 // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists
997 // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success 981 // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success
998 // which is early-outed with a keepers->nbKeepers null-check 982 // which is early-outed with a keepers->nbKeepers null-check
999 size_t const _nbKeepers{ std::exchange(_kv.nbKeepers, size_t{ 0 }) }; 983 for (Keeper& _k : std::span<Keeper>{ _kv.keepers.get(), std::exchange(_kv.nbKeepers, size_t{ 0 }) }) {
1000 for (size_t const _i : std::ranges::iota_view{ size_t{ 0 }, _nbKeepers }) { 984 if (!_closeOneKeeper(_k)) {
1001 if (!_closeOneKeeper(_kv.keepers[_i])) {
1002 // detected partial init: destroy only the mutexes that got initialized properly 985 // detected partial init: destroy only the mutexes that got initialized properly
1003 break; 986 break;
1004 } 987 }
@@ -1137,11 +1120,14 @@ void Keepers::initialize(Universe& U_, lua_State* L_, size_t const nbKeepers_, i
1137 1120
1138 default: 1121 default:
1139 KV& _kv = keeper_array.emplace<KV>( 1122 KV& _kv = keeper_array.emplace<KV>(
1140 std::unique_ptr<Keeper[], DeleteKV>{ new(&U_) Keeper[nbKeepers_], DeleteKV{ &U_, nbKeepers_ } }, 1123 std::unique_ptr<Keeper, DeleteKV>{ static_cast<Keeper*>(U_.internalAllocator.alloc(sizeof(Keeper) * nbKeepers_)), DeleteKV{ U_, nbKeepers_ } },
1141 nbKeepers_ 1124 nbKeepers_
1142 ); 1125 );
1143 for (size_t const _i : std::ranges::iota_view{ size_t{ 0 }, nbKeepers_ }) { 1126 // fak. std::ranges::views::enumerate is c++23 (would help having item and index iterated over simultaneously)
1144 _initOneKeeper(_kv.keepers[_i], static_cast<int>(_i)); 1127 int _i{};
1128 for (Keeper& _k : std::span<Keeper>{ _kv.keepers.get(), nbKeepers_ }) {
1129 new (&_k) Keeper{};
1130 _initOneKeeper(_k, _i++);
1145 } 1131 }
1146 } 1132 }
1147} 1133}