aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/deep.cpp21
-rw-r--r--src/keeper.cpp6
-rw-r--r--src/keeper.h8
-rw-r--r--src/linda.cpp28
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
210int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, ptrdiff_t magic_) 210int 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)
734Keeper* which_keeper(Keepers* keepers_, ptrdiff_t magic_) 734Keeper* 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
743Keeper* keeper_acquire(Keepers* keepers_, ptrdiff_t magic_) 743Keeper* 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
31static constexpr ptrdiff_t KEEPER_MAGIC_SHIFT{ 3 }; 31static 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/
33static constexpr UniqueKey NIL_SENTINEL{ 0x7eaafa003a1d11a1ull }; 33static constexpr UniqueKey NIL_SENTINEL{ 0x7eaafa003a1d11a1ull };
34 34
35void init_keepers(Universe* U, lua_State* L); 35void init_keepers(Universe* U, lua_State* L);
36void close_keepers(Universe* U); 36void close_keepers(Universe* U);
37 37
38Keeper* which_keeper(Keepers* keepers_, ptrdiff_t magic_); 38Keeper* which_keeper(Keepers* keepers_, uintptr_t magic_);
39Keeper* keeper_acquire(Keepers* keepers_, ptrdiff_t magic_); 39Keeper* keeper_acquire(Keepers* keepers_, uintptr_t magic_);
40void keeper_release(Keeper* K); 40void keeper_release(Keeper* K);
41void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_); 41void keeper_toggle_nil_sentinels(lua_State* L, int val_i_, LookupMode const mode_);
42int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, ptrdiff_t magic_); 42int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, uintptr_t magic_);
43 43
44using keeper_api_t = lua_CFunction; 44using 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*/
53struct Linda : public DeepPrelude // Deep userdata MUST start with this header 53class 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