aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/keeper.cpp98
-rw-r--r--src/lanes.cpp7
-rw-r--r--src/macros_and_utils.h6
3 files changed, 59 insertions, 52 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp
index e0a9fdc..cb2b0a9 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -60,7 +60,8 @@ class keeper_fifo
60 int count{ 0 }; 60 int count{ 0 };
61 int limit{ -1 }; 61 int limit{ -1 };
62 62
63 static void* operator new(size_t size_, lua_State* L) noexcept { return lua_newuserdatauv(L, size_, 1); } 63 // a fifo full userdata has one uservalue, the table that holds the actual fifo contents
64 static void* operator new(size_t size_, lua_State* L) noexcept { return lua_newuserdatauv<keeper_fifo>(L, 1); }
64 // always embedded somewhere else or "in-place constructed" as a full userdata 65 // always embedded somewhere else or "in-place constructed" as a full userdata
65 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception 66 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception
66 static void operator delete(void* p_, lua_State* L){ ASSERT_L(!"should never be called") }; 67 static void operator delete(void* p_, lua_State* L){ ASSERT_L(!"should never be called") };
@@ -94,16 +95,16 @@ static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_)
94 95
95// in: nothing 96// in: nothing
96// out: { first = 1, count = 0, limit = -1} 97// out: { first = 1, count = 0, limit = -1}
97static void fifo_new(lua_State* L) 98static keeper_fifo* fifo_new(lua_State* L)
98{ 99{
99 STACK_GROW(L, 2); 100 STACK_GROW(L, 2);
100 STACK_CHECK_START_REL(L, 0); 101 STACK_CHECK_START_REL(L, 0);
101 // a fifo full userdata has one uservalue, the table that holds the actual fifo contents 102 keeper_fifo* const fifo{ new (L) keeper_fifo{} };
102 [[maybe_unused]] keeper_fifo* const fifo{ new (L) keeper_fifo{} };
103 STACK_CHECK(L, 1); 103 STACK_CHECK(L, 1);
104 lua_newtable(L); 104 lua_newtable(L);
105 lua_setiuservalue(L, -2, CONTENTS_TABLE); 105 lua_setiuservalue(L, -2, CONTENTS_TABLE);
106 STACK_CHECK(L, 1); 106 STACK_CHECK(L, 1);
107 return fifo;
107} 108}
108 109
109// ################################################################################################## 110// ##################################################################################################
@@ -145,7 +146,8 @@ static void fifo_peek(lua_State* L, keeper_fifo* fifo_, int count_)
145// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number) 146// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number)
146static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_) 147static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_)
147{ 148{
148 int const fifo_idx = lua_gettop(L); // ... fifo 149 ASSERT_L(lua_istable(L, -1));
150 int const fifo_idx{ lua_gettop(L) }; // ... fifotbl
149 // each iteration pushes a value on the stack! 151 // each iteration pushes a value on the stack!
150 STACK_GROW(L, count_ + 2); 152 STACK_GROW(L, count_ + 2);
151 // skip first item, we will push it last 153 // skip first item, we will push it last
@@ -153,21 +155,22 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_)
153 { 155 {
154 int const at{ fifo_->first + i }; 156 int const at{ fifo_->first + i };
155 // push item on the stack 157 // push item on the stack
156 lua_rawgeti(L, fifo_idx, at); // ... fifo val 158 lua_rawgeti(L, fifo_idx, at); // ... fifotbl val
157 // remove item from the fifo 159 // remove item from the fifo
158 lua_pushnil(L); // ... fifo val nil 160 lua_pushnil(L); // ... fifotbl val nil
159 lua_rawseti(L, fifo_idx, at); // ... fifo val 161 lua_rawseti(L, fifo_idx, at); // ... fifotbl val
160 } 162 }
161 // now process first item 163 // now process first item
162 { 164 {
163 int const at{ fifo_->first }; 165 int const at{ fifo_->first };
164 lua_rawgeti(L, fifo_idx, at); // ... fifo vals val 166 lua_rawgeti(L, fifo_idx, at); // ... fifotbl vals val
165 lua_pushnil(L); // ... fifo vals val nil 167 lua_pushnil(L); // ... fifotbl vals val nil
166 lua_rawseti(L, fifo_idx, at); // ... fifo vals val 168 lua_rawseti(L, fifo_idx, at); // ... fifotbl vals val
167 lua_replace(L, fifo_idx); // ... vals 169 lua_replace(L, fifo_idx); // ... vals
168 } 170 }
171
172 // avoid ever-growing indexes by resetting each time we detect the fifo is empty
169 { 173 {
170 // avoid ever-growing indexes by resetting each time we detect the fifo is empty
171 int const new_count{ fifo_->count - count_ }; 174 int const new_count{ fifo_->count - count_ };
172 fifo_->first = (new_count == 0) ? 1 : (fifo_->first + count_); 175 fifo_->first = (new_count == 0) ? 1 : (fifo_->first + count_);
173 fifo_->count = new_count; 176 fifo_->count = new_count;
@@ -228,21 +231,21 @@ int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, ptrdiff_t m
228 lua_newtable(L); // out 231 lua_newtable(L); // out
229 while( lua_next(KL, -2)) // storage key fifo 232 while( lua_next(KL, -2)) // storage key fifo
230 { 233 {
231 keeper_fifo* fifo = prepare_fifo_access(KL, -1); // storage key fifo 234 keeper_fifo* fifo = prepare_fifo_access(KL, -1); // storage key fifotbl
232 lua_pushvalue(KL, -2); // storage key fifo key 235 lua_pushvalue(KL, -2); // storage key fifotbl key
233 luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key fifo // out key 236 luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key fifotbl // out key
234 STACK_CHECK(L, 2); 237 STACK_CHECK(L, 2);
235 lua_newtable(L); // out key keyout 238 lua_newtable(L); // out key keyout
236 luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key // out key keyout fifo 239 luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key // out key keyout fifotbl
237 lua_pushinteger(L, fifo->first); // out key keyout fifo first 240 lua_pushinteger(L, fifo->first); // out key keyout fifotbl first
238 STACK_CHECK(L, 5); 241 STACK_CHECK(L, 5);
239 lua_setfield(L, -3, "first"); // out key keyout fifo 242 lua_setfield(L, -3, "first"); // out key keyout fifotbl
240 lua_pushinteger(L, fifo->count); // out key keyout fifo count 243 lua_pushinteger(L, fifo->count); // out key keyout fifobtl count
241 STACK_CHECK(L, 5); 244 STACK_CHECK(L, 5);
242 lua_setfield(L, -3, "count"); // out key keyout fifo 245 lua_setfield(L, -3, "count"); // out key keyout fifotbl
243 lua_pushinteger(L, fifo->limit); // out key keyout fifo limit 246 lua_pushinteger(L, fifo->limit); // out key keyout fifotbl limit
244 STACK_CHECK(L, 5); 247 STACK_CHECK(L, 5);
245 lua_setfield(L, -3, "limit"); // out key keyout fifo 248 lua_setfield(L, -3, "limit"); // out key keyout fifotbl
246 lua_setfield(L, -2, "fifo"); // out key keyout 249 lua_setfield(L, -2, "fifo"); // out key keyout
247 lua_rawset(L, -3); // out 250 lua_rawset(L, -3); // out
248 STACK_CHECK(L, 1); 251 STACK_CHECK(L, 1);
@@ -297,9 +300,9 @@ int keepercall_send(lua_State* L)
297 } 300 }
298 else 301 else
299 { 302 {
300 fifo = prepare_fifo_access(L, -1); 303 fifo = prepare_fifo_access(L, -1); // ud fifotbl
301 lua_replace(L, 2); // ud fifo ... 304 lua_replace(L, 2); // ud fifotbl ...
302 fifo_push(L, fifo, n); // ud fifo 305 fifo_push(L, fifo, n); // ud fifotbl
303 lua_settop(L, 0); // 306 lua_settop(L, 0); //
304 lua_pushboolean(L, 1); // true 307 lua_pushboolean(L, 1); // true
305 } 308 }
@@ -319,7 +322,7 @@ int keepercall_receive(lua_State* L)
319 { 322 {
320 lua_pushvalue(L, i); // fifos keys key[i] 323 lua_pushvalue(L, i); // fifos keys key[i]
321 lua_rawget(L, 1); // fifos keys fifo 324 lua_rawget(L, 1); // fifos keys fifo
322 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos keys fifo 325 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos keys fifotbl
323 if (fifo != nullptr && fifo->count > 0) 326 if (fifo != nullptr && fifo->count > 0)
324 { 327 {
325 fifo_pop(L, fifo, 1); // fifos keys val 328 fifo_pop(L, fifo, 1); // fifos keys val
@@ -358,7 +361,7 @@ int keepercall_receive_batched(lua_State* L)
358 lua_pushvalue(L, 1); // key fifos key 361 lua_pushvalue(L, 1); // key fifos key
359 lua_rawget(L, 2); // key fifos fifo 362 lua_rawget(L, 2); // key fifos fifo
360 lua_remove(L, 2); // key fifo 363 lua_remove(L, 2); // key fifo
361 keeper_fifo* const fifo{ prepare_fifo_access(L, 2) }; // key fifo 364 keeper_fifo* const fifo{ prepare_fifo_access(L, 2) }; // key fifotbl
362 if( fifo != nullptr && fifo->count >= min_count) 365 if( fifo != nullptr && fifo->count >= min_count)
363 { 366 {
364 fifo_pop(L, fifo, std::min( max_count, fifo->count)); // key ... 367 fifo_pop(L, fifo, std::min( max_count, fifo->count)); // key ...
@@ -391,8 +394,7 @@ int keepercall_limit(lua_State* L)
391 if (fifo == nullptr) 394 if (fifo == nullptr)
392 { // fifos key nil 395 { // fifos key nil
393 lua_pop(L, 1); // fifos key 396 lua_pop(L, 1); // fifos key
394 fifo_new(L); // fifos key fifo 397 fifo = fifo_new(L); // fifos key fifo
395 fifo = keeper_fifo::getPtr(L, -1);
396 lua_rawset(L, -3); // fifos 398 lua_rawset(L, -3); // fifos
397 } 399 }
398 // remove any clutter on the stack 400 // remove any clutter on the stack
@@ -477,10 +479,10 @@ int keepercall_set(lua_State* L)
477 fifo->first = 1; 479 fifo->first = 1;
478 fifo->count = 0; 480 fifo->count = 0;
479 } 481 }
480 fifo = prepare_fifo_access(L, -1); 482 fifo = prepare_fifo_access(L, -1); // fifos key [val [, ...]] fifotbl
481 // move the fifo below the values we want to store 483 // move the fifo below the values we want to store
482 lua_insert(L, 3); // fifos key fifo [val [, ...]] 484 lua_insert(L, 3); // fifos key fifotbl [val [, ...]]
483 fifo_push(L, fifo, count); // fifos key fifo 485 fifo_push(L, fifo, count); // fifos key fifotbl
484 } 486 }
485 return should_wake_writers ? (lua_pushboolean( L, 1), 1) : 0; 487 return should_wake_writers ? (lua_pushboolean( L, 1), 1) : 0;
486} 488}
@@ -500,13 +502,13 @@ int keepercall_get(lua_State* L)
500 push_table(L, 1); // ud key fifos 502 push_table(L, 1); // ud key fifos
501 lua_replace(L, 1); // fifos key 503 lua_replace(L, 1); // fifos key
502 lua_rawget(L, 1); // fifos fifo 504 lua_rawget(L, 1); // fifos fifo
503 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos fifo 505 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos fifotbl
504 if (fifo != nullptr && fifo->count > 0) 506 if (fifo != nullptr && fifo->count > 0)
505 { 507 {
506 lua_remove(L, 1); // fifo 508 lua_remove(L, 1); // fifotbl
507 count = std::min(count, fifo->count); 509 count = std::min(count, fifo->count);
508 // read <count> value off the fifo 510 // read <count> value off the fifo
509 fifo_peek(L, fifo, count); // fifo ... 511 fifo_peek(L, fifo, count); // fifotbl ...
510 return count; 512 return count;
511 } 513 }
512 // no fifo was ever registered for this key, or it is empty 514 // no fifo was ever registered for this key, or it is empty
@@ -528,7 +530,7 @@ int keepercall_count(lua_State* L)
528 lua_pushnil(L); // out fifos nil 530 lua_pushnil(L); // out fifos nil
529 while (lua_next(L, 2)) // out fifos key fifo 531 while (lua_next(L, 2)) // out fifos key fifo
530 { 532 {
531 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // out fifos key fifo 533 keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) };
532 lua_pop(L, 1); // out fifos key 534 lua_pop(L, 1); // out fifos key
533 lua_pushvalue(L, -1); // out fifos key key 535 lua_pushvalue(L, -1); // out fifos key key
534 lua_pushinteger(L, fifo->count); // out fifos key key count 536 lua_pushinteger(L, fifo->count); // out fifos key key count
@@ -547,7 +549,7 @@ int keepercall_count(lua_State* L)
547 } 549 }
548 else // the key is known 550 else // the key is known
549 { // fifos fifo 551 { // fifos fifo
550 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // fifos fifo 552 keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) };
551 lua_pushinteger(L, fifo->count); // fifos fifo count 553 lua_pushinteger(L, fifo->count); // fifos fifo count
552 lua_replace(L, -3); // count fifo 554 lua_replace(L, -3); // count fifo
553 lua_pop(L, 1); // count 555 lua_pop(L, 1); // count
@@ -556,26 +558,26 @@ int keepercall_count(lua_State* L)
556 558
557 // a variable number of keys is specified: return a table of their counts 559 // a variable number of keys is specified: return a table of their counts
558 default: // ud keys fifos 560 default: // ud keys fifos
559 lua_newtable(L); // ud keys fifos out 561 lua_newtable(L); // ud keys... fifos out
560 lua_replace(L, 1); // out keys fifos 562 lua_replace(L, 1); // out keys... fifos
561 // shifts all keys up in the stack. potentially slow if there are a lot of them, but then it should be bearable 563 // shifts all keys up in the stack. potentially slow if there are a lot of them, but then it should be bearable
562 lua_insert(L, 2); // out fifos keys 564 lua_insert(L, 2); // out fifos keys...
563 while (lua_gettop(L) > 2) 565 while (lua_gettop(L) > 2)
564 { 566 {
565 lua_pushvalue(L, -1); // out fifos keys key 567 lua_pushvalue(L, -1); // out fifos keys... key
566 lua_rawget(L, 2); // out fifos keys fifo|nil 568 lua_rawget(L, 2); // out fifos keys... fifo|nil
567 keeper_fifo* const fifo{ prepare_fifo_access(L, -1) }; // out fifos keys fifo|nil 569 keeper_fifo* const fifo{ keeper_fifo::getPtr(L, -1) };
568 lua_pop(L, 1); // out fifos keys 570 lua_pop(L, 1); // out fifos keys...
569 if (fifo != nullptr) // the key is known 571 if (fifo != nullptr) // the key is known
570 { 572 {
571 lua_pushinteger(L, fifo->count); // out fifos keys count 573 lua_pushinteger(L, fifo->count); // out fifos keys... count
572 lua_rawset(L, 1); // out fifos keys 574 lua_rawset(L, 1); // out fifos keys...
573 } 575 }
574 else // the key is unknown 576 else // the key is unknown
575 { 577 {
576 lua_pop(L, 1); // out fifos keys 578 lua_pop(L, 1); // out fifos keys...
577 } 579 }
578 } 580 } // all keys are exhausted // out fifos
579 lua_pop(L, 1); // out 581 lua_pop(L, 1); // out
580 } 582 }
581 ASSERT_L(lua_gettop(L) == 1); 583 ASSERT_L(lua_gettop(L) == 1);
diff --git a/src/lanes.cpp b/src/lanes.cpp
index df509ee..72652ef 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -572,7 +572,7 @@ static int selfdestruct_gc( lua_State* L)
572 // no need to mutex-protect this as all threads in the universe are gone at that point 572 // no need to mutex-protect this as all threads in the universe are gone at that point
573 if( U->timer_deep != nullptr) // test ins case some early internal error prevented Lanes from creating the deep timer 573 if( U->timer_deep != nullptr) // test ins case some early internal error prevented Lanes from creating the deep timer
574 { 574 {
575 int const prev_ref_count{ U->timer_deep->m_refcount.fetch_sub(1, std::memory_order_relaxed) }; 575 [[maybe_unused]] int const prev_ref_count{ U->timer_deep->m_refcount.fetch_sub(1, std::memory_order_relaxed) };
576 ASSERT_L(prev_ref_count == 1); // this should be the last reference 576 ASSERT_L(prev_ref_count == 1); // this should be the last reference
577 free_deep_prelude(L, U->timer_deep); 577 free_deep_prelude(L, U->timer_deep);
578 U->timer_deep = nullptr; 578 U->timer_deep = nullptr;
@@ -1212,7 +1212,7 @@ LUAG_FUNC( lane_new)
1212 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 1212 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
1213 // 1213 //
1214 // a Lane full userdata needs a single uservalue 1214 // a Lane full userdata needs a single uservalue
1215 Lane** const ud{ static_cast<Lane**>(lua_newuserdatauv(L, sizeof(Lane*), 1)) }; // func libs priority globals package required gc_cb lane 1215 Lane** const ud{ lua_newuserdatauv<Lane*>(L, 1) }; // func libs priority globals package required gc_cb lane
1216 Lane* const s{ *ud = static_cast<Lane*>(U->internal_allocator.alloc(sizeof(Lane))) }; // don't forget to store the pointer in the userdata! 1216 Lane* const s{ *ud = static_cast<Lane*>(U->internal_allocator.alloc(sizeof(Lane))) }; // don't forget to store the pointer in the userdata!
1217 if( s == nullptr) 1217 if( s == nullptr)
1218 { 1218 {
@@ -1915,8 +1915,7 @@ LUAG_FUNC( configure)
1915 STACK_CHECK( L, 2); 1915 STACK_CHECK( L, 2);
1916 1916
1917 { 1917 {
1918 char const* errmsg; 1918 char const* errmsg{ push_deep_proxy(L, U->timer_deep, 0, eLM_LaneBody) }; // settings M timer_deep
1919 errmsg = push_deep_proxy(L, U->timer_deep, 0, eLM_LaneBody); // settings M timer_deep
1920 if( errmsg != nullptr) 1919 if( errmsg != nullptr)
1921 { 1920 {
1922 return luaL_error( L, errmsg); 1921 return luaL_error( L, errmsg);
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h
index 23fa0e9..63bc8d1 100644
--- a/src/macros_and_utils.h
+++ b/src/macros_and_utils.h
@@ -147,3 +147,9 @@ auto lua_tolightuserdata(lua_State* L, int index_)
147 return static_cast<T*>(lua_touserdata(L, index_)); 147 return static_cast<T*>(lua_touserdata(L, index_));
148 } 148 }
149} 149}
150
151template <typename T>
152T* lua_newuserdatauv(lua_State* L, int nuvalue_)
153{
154 return static_cast<T*>(lua_newuserdatauv(L, sizeof(T), nuvalue_));
155}