aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-06-07 10:07:44 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-06-07 10:07:44 +0200
commit6a2d1112c3cf64b46f7c60d7878d5cc8101fc5cd (patch)
treeedc830d4507fc8b05c2202dcebb499d16563cb3d /src
parent57ca292c8844e566184e3f7e5c98fa98991684bd (diff)
downloadlanes-6a2d1112c3cf64b46f7c60d7878d5cc8101fc5cd.tar.gz
lanes-6a2d1112c3cf64b46f7c60d7878d5cc8101fc5cd.tar.bz2
lanes-6a2d1112c3cf64b46f7c60d7878d5cc8101fc5cd.zip
Debug code to help track linda gc during keeper operation
Diffstat (limited to 'src')
-rw-r--r--src/debug.h2
-rw-r--r--src/linda.cpp2
-rw-r--r--src/linda.h32
-rw-r--r--src/lindafactory.cpp2
4 files changed, 34 insertions, 4 deletions
diff --git a/src/debug.h b/src/debug.h
index a0a4b8d..99fe48a 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -15,6 +15,7 @@ inline void LUA_ASSERT_IMPL(lua_State* L_, bool cond_, char const* file_, int co
15} 15}
16 16
17#define LUA_ASSERT(L_, cond_) LUA_ASSERT_IMPL(L_, cond_, __FILE__, __LINE__, #cond_) 17#define LUA_ASSERT(L_, cond_) LUA_ASSERT_IMPL(L_, cond_, __FILE__, __LINE__, #cond_)
18#define LUA_ASSERT_CODE(code_) code_
18 19
19class StackChecker 20class StackChecker
20{ 21{
@@ -102,6 +103,7 @@ class StackChecker
102#else // HAVE_LUA_ASSERT() 103#else // HAVE_LUA_ASSERT()
103 104
104#define LUA_ASSERT(L_, c) nullptr // nothing 105#define LUA_ASSERT(L_, c) nullptr // nothing
106#define LUA_ASSERT_CODE(code_) nullptr
105 107
106#define STACK_CHECK_START_REL(L_, offset_) 108#define STACK_CHECK_START_REL(L_, offset_)
107#define STACK_CHECK_START_ABS(L_, offset_) 109#define STACK_CHECK_START_ABS(L_, offset_)
diff --git a/src/linda.cpp b/src/linda.cpp
index 8b6df8e..3449f89 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -181,6 +181,8 @@ int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_)
181 lua_State* const _KL{ _K ? _K->L : nullptr }; 181 lua_State* const _KL{ _K ? _K->L : nullptr };
182 if (_KL == nullptr) 182 if (_KL == nullptr)
183 return 0; 183 return 0;
184
185 LUA_ASSERT_CODE(auto const _koip{ _linda->startKeeperOperation(L_) });
184 // if we didn't do anything wrong, the keeper stack should be clean 186 // if we didn't do anything wrong, the keeper stack should be clean
185 LUA_ASSERT(L_, lua_gettop(_KL) == 0); 187 LUA_ASSERT(L_, lua_gettop(_KL) == 0);
186 188
diff --git a/src/linda.h b/src/linda.h
index 8db380a..809ade5 100644
--- a/src/linda.h
+++ b/src/linda.h
@@ -23,15 +23,39 @@ using LindaGroup = Unique<int>;
23class Linda 23class Linda
24: public DeepPrelude // Deep userdata MUST start with this header 24: public DeepPrelude // Deep userdata MUST start with this header
25{ 25{
26 public:
27 class KeeperOperationInProgress
28 {
29 private:
30 Linda& linda;
31 [[maybe_unused]] lua_State* const L; // just here for inspection while debugging
32
33 public:
34 KeeperOperationInProgress(Linda& linda_, lua_State* const L_)
35 : linda{ linda_ }
36 , L{ L_ }
37 {
38 [[maybe_unused]] int const _prev{ linda.keeperOperationCount.fetch_add(1, std::memory_order_seq_cst) };
39 }
40
41 public:
42 ~KeeperOperationInProgress()
43 {
44 [[maybe_unused]] int const _prev{ linda.keeperOperationCount.fetch_sub(1, std::memory_order_seq_cst) };
45 }
46 };
47
26 private: 48 private:
27 static constexpr size_t kEmbeddedNameLength = 24; 49 static constexpr size_t kEmbeddedNameLength = 24;
28 using EmbeddedName = std::array<char, kEmbeddedNameLength>; 50 using EmbeddedName = std::array<char, kEmbeddedNameLength>;
29 // depending on the name length, it is either embedded inside the Linda, or allocated separately 51 // depending on the name length, it is either embedded inside the Linda, or allocated separately
30 std::variant<std::string_view, EmbeddedName> nameVariant; 52 std::variant<std::string_view, EmbeddedName> nameVariant{};
53 // counts the keeper operations in progress
54 std::atomic<int> keeperOperationCount{};
31 55
32 public: 56 public:
33 std::condition_variable readHappened; 57 std::condition_variable readHappened{};
34 std::condition_variable writeHappened; 58 std::condition_variable writeHappened{};
35 Universe* const U{ nullptr }; // the universe this linda belongs to 59 Universe* const U{ nullptr }; // the universe this linda belongs to
36 int const keeperIndex{ -1 }; // the keeper associated to this linda 60 int const keeperIndex{ -1 }; // the keeper associated to this linda
37 CancelRequest cancelRequest{ CancelRequest::None }; 61 CancelRequest cancelRequest{ CancelRequest::None };
@@ -60,7 +84,9 @@ class Linda
60 public: 84 public:
61 [[nodiscard]] Keeper* acquireKeeper() const; 85 [[nodiscard]] Keeper* acquireKeeper() const;
62 [[nodiscard]] std::string_view getName() const; 86 [[nodiscard]] std::string_view getName() const;
87 [[nodiscard]] bool inKeeperOperation() const { return keeperOperationCount.load(std::memory_order_seq_cst) != 0; }
63 void releaseKeeper(Keeper* keeper_) const; 88 void releaseKeeper(Keeper* keeper_) const;
64 [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_); 89 [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_);
90 [[nodiscard]] KeeperOperationInProgress startKeeperOperation(lua_State* const L_) { return KeeperOperationInProgress{ *this, L_ }; };
65 [[nodiscard]] Keeper* whichKeeper() const { return U->keepers.getKeeper(keeperIndex); } 91 [[nodiscard]] Keeper* whichKeeper() const { return U->keepers.getKeeper(keeperIndex); }
66}; 92};
diff --git a/src/lindafactory.cpp b/src/lindafactory.cpp
index 3f4b9b0..6a2b000 100644
--- a/src/lindafactory.cpp
+++ b/src/lindafactory.cpp
@@ -69,7 +69,7 @@ void LindaFactory::createMetatable(lua_State* L_) const
69void LindaFactory::deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const 69void LindaFactory::deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const
70{ 70{
71 Linda* const _linda{ static_cast<Linda*>(o_) }; 71 Linda* const _linda{ static_cast<Linda*>(o_) };
72 LUA_ASSERT(L_, _linda); 72 LUA_ASSERT(L_, _linda && !_linda->inKeeperOperation());
73 Keeper* const _myK{ _linda->whichKeeper() }; 73 Keeper* const _myK{ _linda->whichKeeper() };
74 // if collected after the universe, keepers are already destroyed, and there is nothing to clear 74 // if collected after the universe, keepers are already destroyed, and there is nothing to clear
75 if (_myK) { 75 if (_myK) {