diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-28 14:40:07 +0100 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-28 14:40:07 +0100 |
commit | 23a8f1ed5b24c05ac203fc7f30a03f7fc52c0cbd (patch) | |
tree | 5f4c071e3a039a07d82d59c3b7be956aa62b6074 | |
parent | 2f049249c8d861193e348e042a203a034982adc1 (diff) | |
download | lanes-23a8f1ed5b24c05ac203fc7f30a03f7fc52c0cbd.tar.gz lanes-23a8f1ed5b24c05ac203fc7f30a03f7fc52c0cbd.tar.bz2 lanes-23a8f1ed5b24c05ac203fc7f30a03f7fc52c0cbd.zip |
C++ migration: Linda is a proper class with overloaded operator new/delete
-rw-r--r-- | src/deep.cpp | 21 | ||||
-rw-r--r-- | src/keeper.cpp | 6 | ||||
-rw-r--r-- | src/keeper.h | 8 | ||||
-rw-r--r-- | src/linda.cpp | 28 |
4 files changed, 34 insertions, 29 deletions
diff --git a/src/deep.cpp b/src/deep.cpp index 74ecfb8..652b19d 100644 --- a/src/deep.cpp +++ b/src/deep.cpp | |||
@@ -32,21 +32,22 @@ THE SOFTWARE. | |||
32 | =============================================================================== | 32 | =============================================================================== |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "compat.h" | ||
36 | #include "deep.h" | ||
37 | #include "tools.h" | ||
38 | #include "uniquekey.h" | ||
39 | #include "universe.h" | ||
40 | |||
41 | #include <bit> | ||
42 | #include <cassert> | ||
43 | #include <ctype.h> | ||
35 | #include <stdio.h> | 44 | #include <stdio.h> |
36 | #include <assert.h> | ||
37 | #include <string.h> | 45 | #include <string.h> |
38 | #include <ctype.h> | ||
39 | #include <stdlib.h> | 46 | #include <stdlib.h> |
40 | #if !defined(__APPLE__) | 47 | #if !defined(__APPLE__) |
41 | #include <malloc.h> | 48 | #include <malloc.h> |
42 | #endif | 49 | #endif |
43 | 50 | ||
44 | #include "compat.h" | ||
45 | #include "deep.h" | ||
46 | #include "tools.h" | ||
47 | #include "universe.h" | ||
48 | #include "uniquekey.h" | ||
49 | |||
50 | /*-- Metatable copying --*/ | 51 | /*-- Metatable copying --*/ |
51 | 52 | ||
52 | /*---=== Deep userdata ===---*/ | 53 | /*---=== Deep userdata ===---*/ |
@@ -227,7 +228,7 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup | |||
227 | prelude->m_refcount.fetch_add(1, std::memory_order_relaxed); // one more proxy pointing to this deep data | 228 | prelude->m_refcount.fetch_add(1, std::memory_order_relaxed); // one more proxy pointing to this deep data |
228 | 229 | ||
229 | // Get/create metatable for 'idfunc' (in this state) | 230 | // Get/create metatable for 'idfunc' (in this state) |
230 | lua_pushlightuserdata( L, (void*)(ptrdiff_t)(prelude->idfunc)); // DPC proxy idfunc | 231 | lua_pushlightuserdata( L, std::bit_cast<void*>(prelude->idfunc)); // DPC proxy idfunc |
231 | get_deep_lookup( L); // DPC proxy metatable? | 232 | get_deep_lookup( L); // DPC proxy metatable? |
232 | 233 | ||
233 | if( lua_isnil( L, -1)) // // No metatable yet. | 234 | if( lua_isnil( L, -1)) // // No metatable yet. |
@@ -269,7 +270,7 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup | |||
269 | 270 | ||
270 | // Memorize for later rounds | 271 | // Memorize for later rounds |
271 | lua_pushvalue( L, -1); // DPC proxy metatable metatable | 272 | lua_pushvalue( L, -1); // DPC proxy metatable metatable |
272 | lua_pushlightuserdata( L, (void*)(ptrdiff_t)(prelude->idfunc)); // DPC proxy metatable metatable idfunc | 273 | lua_pushlightuserdata( L, std::bit_cast<void*>(prelude->idfunc)); // DPC proxy metatable metatable idfunc |
273 | set_deep_lookup( L); // DPC proxy metatable | 274 | set_deep_lookup( L); // DPC proxy metatable |
274 | 275 | ||
275 | // 2 - cause the target state to require the module that exported the idfunc | 276 | // 2 - cause the target state to require the module that exported the idfunc |
diff --git a/src/keeper.cpp b/src/keeper.cpp index 1919a68..9c41b1c 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
@@ -207,7 +207,7 @@ static void push_table(lua_State* L, int idx_) | |||
207 | 207 | ||
208 | // ################################################################################################## | 208 | // ################################################################################################## |
209 | 209 | ||
210 | int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, ptrdiff_t magic_) | 210 | int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, uintptr_t magic_) |
211 | { | 211 | { |
212 | Keeper* const K = which_keeper( U->keepers, magic_); | 212 | Keeper* const K = which_keeper( U->keepers, magic_); |
213 | lua_State* const KL = K ? K->L : nullptr; | 213 | lua_State* const KL = K ? K->L : nullptr; |
@@ -731,7 +731,7 @@ void init_keepers(Universe* U, lua_State* L) | |||
731 | // ################################################################################################## | 731 | // ################################################################################################## |
732 | 732 | ||
733 | // should be called only when inside a keeper_acquire/keeper_release pair (see linda_protected_call) | 733 | // should be called only when inside a keeper_acquire/keeper_release pair (see linda_protected_call) |
734 | Keeper* which_keeper(Keepers* keepers_, ptrdiff_t magic_) | 734 | Keeper* which_keeper(Keepers* keepers_, uintptr_t magic_) |
735 | { | 735 | { |
736 | int const nbKeepers{ keepers_->nb_keepers }; | 736 | int const nbKeepers{ keepers_->nb_keepers }; |
737 | unsigned int i = (unsigned int)((magic_ >> KEEPER_MAGIC_SHIFT) % nbKeepers); | 737 | unsigned int i = (unsigned int)((magic_ >> KEEPER_MAGIC_SHIFT) % nbKeepers); |
@@ -740,7 +740,7 @@ Keeper* which_keeper(Keepers* keepers_, ptrdiff_t magic_) | |||
740 | 740 | ||
741 | // ################################################################################################## | 741 | // ################################################################################################## |
742 | 742 | ||
743 | Keeper* keeper_acquire(Keepers* keepers_, ptrdiff_t magic_) | 743 | Keeper* keeper_acquire(Keepers* keepers_, uintptr_t magic_) |
744 | { | 744 | { |
745 | int const nbKeepers{ keepers_->nb_keepers }; | 745 | int const nbKeepers{ keepers_->nb_keepers }; |
746 | // can be 0 if this happens during main state shutdown (lanes is being GC'ed -> no keepers) | 746 | // can be 0 if this happens during main state shutdown (lanes is being GC'ed -> no keepers) |
diff --git a/src/keeper.h b/src/keeper.h index 5f52fa0..fc0aa6b 100644 --- a/src/keeper.h +++ b/src/keeper.h | |||
@@ -28,18 +28,18 @@ struct Keepers | |||
28 | Keeper keeper_array[1]; | 28 | Keeper keeper_array[1]; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static constexpr ptrdiff_t KEEPER_MAGIC_SHIFT{ 3 }; | 31 | static constexpr uintptr_t KEEPER_MAGIC_SHIFT{ 3 }; |
32 | // crc64/we of string "NIL_SENTINEL" generated at http://www.nitrxgen.net/hashgen/ | 32 | // crc64/we of string "NIL_SENTINEL" generated at http://www.nitrxgen.net/hashgen/ |
33 | static constexpr UniqueKey NIL_SENTINEL{ 0x7eaafa003a1d11a1ull }; | 33 | static constexpr UniqueKey NIL_SENTINEL{ 0x7eaafa003a1d11a1ull }; |
34 | 34 | ||
35 | void init_keepers(Universe* U, lua_State* L); | 35 | void init_keepers(Universe* U, lua_State* L); |
36 | void close_keepers(Universe* U); | 36 | void close_keepers(Universe* U); |
37 | 37 | ||
38 | Keeper* which_keeper(Keepers* keepers_, ptrdiff_t magic_); | 38 | Keeper* which_keeper(Keepers* keepers_, uintptr_t magic_); |
39 | Keeper* keeper_acquire(Keepers* keepers_, ptrdiff_t magic_); | 39 | Keeper* keeper_acquire(Keepers* keepers_, uintptr_t magic_); |
40 | void keeper_release(Keeper* K); | 40 | void keeper_release(Keeper* K); |
41 | void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_); | 41 | void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_); |
42 | int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, ptrdiff_t magic_); | 42 | int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, uintptr_t magic_); |
43 | 43 | ||
44 | using keeper_api_t = lua_CFunction; | 44 | using keeper_api_t = lua_CFunction; |
45 | #define KEEPER_API(_op) keepercall_##_op | 45 | #define KEEPER_API(_op) keepercall_##_op |
diff --git a/src/linda.cpp b/src/linda.cpp index e1633b0..dc5864b 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
@@ -50,7 +50,7 @@ THE SOFTWARE. | |||
50 | * Actual data is kept within a keeper state, which is hashed by the 'Linda' | 50 | * Actual data is kept within a keeper state, which is hashed by the 'Linda' |
51 | * pointer (which is same to all userdatas pointing to it). | 51 | * pointer (which is same to all userdatas pointing to it). |
52 | */ | 52 | */ |
53 | struct Linda : public DeepPrelude // Deep userdata MUST start with this header | 53 | class Linda : public DeepPrelude // Deep userdata MUST start with this header |
54 | { | 54 | { |
55 | private: | 55 | private: |
56 | 56 | ||
@@ -61,19 +61,28 @@ struct Linda : public DeepPrelude // Deep userdata MUST start with this header | |||
61 | size_t len{ 0 }; | 61 | size_t len{ 0 }; |
62 | char* name{ nullptr }; | 62 | char* name{ nullptr }; |
63 | }; | 63 | }; |
64 | // depending on the name length, it is either embedded inside the Linda, or allocated separately | ||
65 | std::variant<AllocatedName, EmbeddedName> m_name; | ||
64 | 66 | ||
65 | public: | 67 | public: |
66 | 68 | ||
67 | SIGNAL_T read_happened; | 69 | SIGNAL_T read_happened; |
68 | SIGNAL_T write_happened; | 70 | SIGNAL_T write_happened; |
69 | Universe* const U; // the universe this linda belongs to | 71 | Universe* const U; // the universe this linda belongs to |
70 | ptrdiff_t const group; // a group to control keeper allocation between lindas | 72 | uintptr_t const group; // a group to control keeper allocation between lindas |
71 | CancelRequest simulate_cancel{ CancelRequest::None }; | 73 | CancelRequest simulate_cancel{ CancelRequest::None }; |
72 | std::variant<AllocatedName, EmbeddedName> m_name; | ||
73 | 74 | ||
74 | public: | 75 | public: |
75 | 76 | ||
76 | Linda(Universe* U_, ptrdiff_t group_, char const* name_, size_t len_) | 77 | // a fifo full userdata has one uservalue, the table that holds the actual fifo contents |
78 | static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internal_allocator.alloc(size_); } | ||
79 | // always embedded somewhere else or "in-place constructed" as a full userdata | ||
80 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | ||
81 | static void operator delete(void* p_, Universe* U_) { U_->internal_allocator.free(p_, sizeof(Linda)); } | ||
82 | // this one is for us, to make sure memory is freed by the correct allocator | ||
83 | static void operator delete(void* p_) { static_cast<Linda*>(p_)->U->internal_allocator.free(p_, sizeof(Linda)); } | ||
84 | |||
85 | Linda(Universe* U_, uintptr_t group_, char const* name_, size_t len_) | ||
77 | : U{ U_ } | 86 | : U{ U_ } |
78 | , group{ group_ << KEEPER_MAGIC_SHIFT } | 87 | , group{ group_ << KEEPER_MAGIC_SHIFT } |
79 | { | 88 | { |
@@ -122,7 +131,7 @@ struct Linda : public DeepPrelude // Deep userdata MUST start with this header | |||
122 | 131 | ||
123 | public: | 132 | public: |
124 | 133 | ||
125 | ptrdiff_t hashSeed() const { return group ? group : std::bit_cast<ptrdiff_t>(this); } | 134 | uintptr_t hashSeed() const { return group ? group : std::bit_cast<uintptr_t>(this); } |
126 | 135 | ||
127 | char const* getName() const | 136 | char const* getName() const |
128 | { | 137 | { |
@@ -887,11 +896,7 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
887 | * just don't use L's allocF because we don't know which state will get the honor of GCing the linda | 896 | * just don't use L's allocF because we don't know which state will get the honor of GCing the linda |
888 | */ | 897 | */ |
889 | Universe* const U{ universe_get(L) }; | 898 | Universe* const U{ universe_get(L) }; |
890 | Linda* s{ static_cast<Linda*>(U->internal_allocator.alloc(sizeof(Linda))) }; // terminating 0 is already included | 899 | Linda* s{ new (U) Linda{ U, linda_group, linda_name, name_len } }; |
891 | if (s) | ||
892 | { | ||
893 | s->Linda::Linda(U, linda_group, linda_name, name_len); | ||
894 | } | ||
895 | return s; | 900 | return s; |
896 | } | 901 | } |
897 | 902 | ||
@@ -909,8 +914,7 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
909 | } | 914 | } |
910 | keeper_release( K); | 915 | keeper_release( K); |
911 | 916 | ||
912 | linda->Linda::~Linda(); | 917 | delete linda; // operator delete overload ensures things go as expected |
913 | linda->U->internal_allocator.free(linda, sizeof(Linda)); | ||
914 | return nullptr; | 918 | return nullptr; |
915 | } | 919 | } |
916 | 920 | ||