diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-10-28 18:09:51 +0100 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-10-28 18:09:51 +0100 |
commit | 3cf9c3c9d076d5822595834bdbf5153d4e923c67 (patch) | |
tree | 13ff16c05ff047a569b90e8981bdc349fd573c6e /src/linda.h | |
parent | df60f71fe943686deed8ca0f85c6d597570ab030 (diff) | |
download | lanes-3cf9c3c9d076d5822595834bdbf5153d4e923c67.tar.gz lanes-3cf9c3c9d076d5822595834bdbf5153d4e923c67.tar.bz2 lanes-3cf9c3c9d076d5822595834bdbf5153d4e923c67.zip |
Renamed lane.h → lane.hpp, linda.h → linda.hpp, threading.h → threading.hpp
Diffstat (limited to 'src/linda.h')
-rw-r--r-- | src/linda.h | 103 |
1 files changed, 0 insertions, 103 deletions
diff --git a/src/linda.h b/src/linda.h deleted file mode 100644 index 5b5f683..0000000 --- a/src/linda.h +++ /dev/null | |||
@@ -1,103 +0,0 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include "cancel.hpp" | ||
4 | #include "deep.hpp" | ||
5 | #include "universe.hpp" | ||
6 | |||
7 | struct Keeper; | ||
8 | |||
9 | // ################################################################################################# | ||
10 | |||
11 | // xxh64 of string "kLindaBatched" generated at https://www.pelock.com/products/hash-calculator | ||
12 | static constexpr UniqueKey kLindaBatched{ 0xB8234DF772646567ull, "linda.batched" }; | ||
13 | |||
14 | // ################################################################################################# | ||
15 | |||
16 | DECLARE_UNIQUE_TYPE(LindaGroup, int); | ||
17 | |||
18 | class Linda | ||
19 | : public DeepPrelude // Deep userdata MUST start with this header | ||
20 | { | ||
21 | public: | ||
22 | class KeeperOperationInProgress | ||
23 | { | ||
24 | private: | ||
25 | Linda& linda; | ||
26 | [[maybe_unused]] lua_State* const L; // just here for inspection while debugging | ||
27 | |||
28 | public: | ||
29 | KeeperOperationInProgress(Linda& linda_, lua_State* const L_) | ||
30 | : linda{ linda_ } | ||
31 | , L{ L_ } | ||
32 | { | ||
33 | [[maybe_unused]] UnusedInt const _prev{ linda.keeperOperationCount.fetch_add(1, std::memory_order_seq_cst) }; | ||
34 | } | ||
35 | |||
36 | public: | ||
37 | ~KeeperOperationInProgress() | ||
38 | { | ||
39 | [[maybe_unused]] UnusedInt const _prev{ linda.keeperOperationCount.fetch_sub(1, std::memory_order_seq_cst) }; | ||
40 | } | ||
41 | }; | ||
42 | |||
43 | enum class Status | ||
44 | { | ||
45 | Active, | ||
46 | Cancelled | ||
47 | }; | ||
48 | using enum Status; | ||
49 | |||
50 | private: | ||
51 | |||
52 | static constexpr size_t kEmbeddedNameLength = 24; | ||
53 | using EmbeddedName = std::array<char, kEmbeddedNameLength>; | ||
54 | // depending on the name length, it is either embedded inside the Linda, or allocated separately | ||
55 | std::variant<std::string_view, EmbeddedName> nameVariant{}; | ||
56 | // counts the keeper operations in progress | ||
57 | std::atomic<int> keeperOperationCount{}; | ||
58 | |||
59 | public: | ||
60 | std::condition_variable readHappened{}; | ||
61 | std::condition_variable writeHappened{}; | ||
62 | Universe* const U{ nullptr }; // the universe this linda belongs to | ||
63 | KeeperIndex const keeperIndex{ -1 }; // the keeper associated to this linda | ||
64 | Status cancelStatus{ Status::Active }; | ||
65 | |||
66 | public: | ||
67 | [[nodiscard]] static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internalAllocator.alloc(size_); } | ||
68 | // always embedded somewhere else or "in-place constructed" as a full userdata | ||
69 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | ||
70 | static void operator delete(void* p_, Universe* U_) { U_->internalAllocator.free(p_, sizeof(Linda)); } | ||
71 | // this one is for us, to make sure memory is freed by the correct allocator | ||
72 | static void operator delete(void* p_) { static_cast<Linda*>(p_)->U->internalAllocator.free(p_, sizeof(Linda)); } | ||
73 | |||
74 | ~Linda(); | ||
75 | Linda(Universe* U_, LindaGroup group_, std::string_view const& name_); | ||
76 | Linda() = delete; | ||
77 | // non-copyable, non-movable | ||
78 | Linda(Linda const&) = delete; | ||
79 | Linda(Linda const&&) = delete; | ||
80 | Linda& operator=(Linda const&) = delete; | ||
81 | Linda& operator=(Linda const&&) = delete; | ||
82 | |||
83 | private: | ||
84 | void freeAllocatedName(); | ||
85 | void setName(std::string_view const& name_); | ||
86 | |||
87 | public: | ||
88 | [[nodiscard]] Keeper* acquireKeeper() const; | ||
89 | [[nodiscard]] std::string_view getName() const; | ||
90 | [[nodiscard]] bool inKeeperOperation() const { return keeperOperationCount.load(std::memory_order_seq_cst) != 0; } | ||
91 | template <typename T = uintptr_t> | ||
92 | [[nodiscard]] T obfuscated() const | ||
93 | { | ||
94 | // xxh64 of string "kObfuscator" generated at https://www.pelock.com/products/hash-calculator | ||
95 | static constexpr UniqueKey kObfuscator{ 0x7B8AA1F99A3BD782ull }; | ||
96 | return std::bit_cast<T>(std::bit_cast<uintptr_t>(this) ^ kObfuscator.storage); | ||
97 | }; | ||
98 | void releaseKeeper(Keeper* keeper_) const; | ||
99 | [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_); | ||
100 | void pushCancelString(lua_State* L_) const; | ||
101 | [[nodiscard]] KeeperOperationInProgress startKeeperOperation(lua_State* const L_) { return KeeperOperationInProgress{ *this, L_ }; }; | ||
102 | [[nodiscard]] Keeper* whichKeeper() const { return U->keepers.getKeeper(keeperIndex); } | ||
103 | }; | ||