aboutsummaryrefslogtreecommitdiff
path: root/src/keeper.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/keeper.hpp')
-rw-r--r--src/keeper.hpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/keeper.hpp b/src/keeper.hpp
new file mode 100644
index 0000000..2354c2e
--- /dev/null
+++ b/src/keeper.hpp
@@ -0,0 +1,90 @@
1#pragma once
2
3#include "uniquekey.hpp"
4
5// forwards
6class Linda;
7enum class LookupMode;
8class Universe;
9
10DECLARE_UNIQUE_TYPE(KeeperState,lua_State*);
11DECLARE_UNIQUE_TYPE(LindaLimit, int);
12DECLARE_UNIQUE_TYPE(KeeperIndex, int);
13
14// #################################################################################################
15
16struct Keeper
17{
18 std::mutex mutex;
19 KeeperState K{ static_cast<lua_State*>(nullptr) };
20
21 [[nodiscard]] static void* operator new[](size_t size_, Universe* U_) noexcept;
22 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception
23 static void operator delete[](void* p_, Universe* U_);
24
25
26 ~Keeper() = default;
27 Keeper() = default;
28 // non-copyable, non-movable
29 Keeper(Keeper const&) = delete;
30 Keeper(Keeper const&&) = delete;
31 Keeper& operator=(Keeper const&) = delete;
32 Keeper& operator=(Keeper const&&) = delete;
33
34 [[nodiscard]] static int PushLindaStorage(Linda& linda_, DestState L_);
35};
36
37// #################################################################################################
38
39struct Keepers
40{
41 private:
42 struct DeleteKV
43 {
44 Universe* U{};
45 size_t count{};
46 void operator()(Keeper* k_) const;
47 };
48 // can't use std::vector<Keeper> because Keeper contains a mutex, so we need a raw memory buffer
49 struct KV
50 {
51 std::unique_ptr<Keeper[], DeleteKV> keepers;
52 size_t nbKeepers{};
53 };
54 std::variant<std::monostate, Keeper, KV> keeper_array;
55 std::atomic_flag isClosing;
56
57 public:
58 int gc_threshold{ 0 };
59
60 public:
61 // can only be instanced as a data member
62 static void* operator new(size_t size_) = delete;
63
64 Keepers() = default;
65 void close();
66 [[nodiscard]] Keeper* getKeeper(KeeperIndex idx_);
67 [[nodiscard]] int getNbKeepers() const;
68 void initialize(Universe& U_, lua_State* L_, size_t nbKeepers_, int gc_threshold_);
69};
70
71// #################################################################################################
72
73// xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator
74static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" };
75
76using keeper_api_t = lua_CFunction;
77#define KEEPER_API(_op) keepercall_##_op
78
79// lua_Cfunctions to run inside a keeper state
80[[nodiscard]] int keepercall_count(lua_State* L_);
81[[nodiscard]] int keepercall_destruct(lua_State* L_);
82[[nodiscard]] int keepercall_get(lua_State* L_);
83[[nodiscard]] int keepercall_limit(lua_State* L_);
84[[nodiscard]] int keepercall_receive(lua_State* L_);
85[[nodiscard]] int keepercall_receive_batched(lua_State* L_);
86[[nodiscard]] int keepercall_send(lua_State* L_);
87[[nodiscard]] int keepercall_set(lua_State* L_);
88
89DECLARE_UNIQUE_TYPE(KeeperCallResult, std::optional<int>);
90[[nodiscard]] KeeperCallResult keeper_call(KeeperState K_, keeper_api_t func_, lua_State* L_, Linda* linda_, StackIndex starting_index_);