aboutsummaryrefslogtreecommitdiff
path: root/src/linda.h
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-10-28 18:09:51 +0100
committerBenoit Germain <benoit.germain@ubisoft.com>2024-10-28 18:09:51 +0100
commit3cf9c3c9d076d5822595834bdbf5153d4e923c67 (patch)
tree13ff16c05ff047a569b90e8981bdc349fd573c6e /src/linda.h
parentdf60f71fe943686deed8ca0f85c6d597570ab030 (diff)
downloadlanes-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.h103
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
7struct Keeper;
8
9// #################################################################################################
10
11// xxh64 of string "kLindaBatched" generated at https://www.pelock.com/products/hash-calculator
12static constexpr UniqueKey kLindaBatched{ 0xB8234DF772646567ull, "linda.batched" };
13
14// #################################################################################################
15
16DECLARE_UNIQUE_TYPE(LindaGroup, int);
17
18class 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};