aboutsummaryrefslogtreecommitdiff
path: root/src/linda.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/linda.cpp')
-rw-r--r--src/linda.cpp72
1 files changed, 36 insertions, 36 deletions
diff --git a/src/linda.cpp b/src/linda.cpp
index cda3a63..bbfbd69 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -53,7 +53,7 @@ static constexpr uintptr_t kPointerMagicShift{ 3 };
53Linda::Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_) 53Linda::Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_)
54: DeepPrelude{ LindaFactory::Instance } 54: DeepPrelude{ LindaFactory::Instance }
55, U{ U_ } 55, U{ U_ }
56, m_keeper_index{ (group_ ? group_ : static_cast<int>(std::bit_cast<uintptr_t>(this) >> kPointerMagicShift)) % U_->keepers->nb_keepers } 56, keeperIndex{ (group_ ? group_ : static_cast<int>(std::bit_cast<uintptr_t>(this) >> kPointerMagicShift)) % U_->keepers->nb_keepers }
57{ 57{
58 setName(name_, len_); 58 setName(name_, len_);
59} 59}
@@ -62,9 +62,9 @@ Linda::Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_)
62 62
63Linda::~Linda() 63Linda::~Linda()
64{ 64{
65 if (std::holds_alternative<AllocatedName>(m_name)) { 65 if (std::holds_alternative<AllocatedName>(nameVariant)) {
66 AllocatedName& name = std::get<AllocatedName>(m_name); 66 AllocatedName& name = std::get<AllocatedName>(nameVariant);
67 U->internal_allocator.free(name.name, name.len); 67 U->internalAllocator.free(name.name, name.len);
68 } 68 }
69} 69}
70 70
@@ -78,12 +78,12 @@ void Linda::setName(char const* name_, size_t len_)
78 } 78 }
79 ++len_; // don't forget terminating 0 79 ++len_; // don't forget terminating 0
80 if (len_ < kEmbeddedNameLength) { 80 if (len_ < kEmbeddedNameLength) {
81 m_name.emplace<EmbeddedName>(); 81 nameVariant.emplace<EmbeddedName>();
82 char* const name{ std::get<EmbeddedName>(m_name).data() }; 82 char* const name{ std::get<EmbeddedName>(nameVariant).data() };
83 memcpy(name, name_, len_); 83 memcpy(name, name_, len_);
84 } else { 84 } else {
85 AllocatedName& name = std::get<AllocatedName>(m_name); 85 AllocatedName& name = std::get<AllocatedName>(nameVariant);
86 name.name = static_cast<char*>(U->internal_allocator.alloc(len_)); 86 name.name = static_cast<char*>(U->internalAllocator.alloc(len_));
87 name.len = len_; 87 name.len = len_;
88 memcpy(name.name, name_, len_); 88 memcpy(name.name, name_, len_);
89 } 89 }
@@ -93,12 +93,12 @@ void Linda::setName(char const* name_, size_t len_)
93 93
94char const* Linda::getName() const 94char const* Linda::getName() const
95{ 95{
96 if (std::holds_alternative<AllocatedName>(m_name)) { 96 if (std::holds_alternative<AllocatedName>(nameVariant)) {
97 AllocatedName const& name = std::get<AllocatedName>(m_name); 97 AllocatedName const& name = std::get<AllocatedName>(nameVariant);
98 return name.name; 98 return name.name;
99 } 99 }
100 if (std::holds_alternative<EmbeddedName>(m_name)) { 100 if (std::holds_alternative<EmbeddedName>(nameVariant)) {
101 char const* const name{ std::get<EmbeddedName>(m_name).data() }; 101 char const* const name{ std::get<EmbeddedName>(nameVariant).data() };
102 return name; 102 return name;
103 } 103 }
104 return nullptr; 104 return nullptr;
@@ -241,9 +241,9 @@ LUAG_FUNC(linda_send)
241 STACK_CHECK_START_REL(KL, 0); 241 STACK_CHECK_START_REL(KL, 0);
242 for (bool try_again{ true };;) { 242 for (bool try_again{ true };;) {
243 if (lane != nullptr) { 243 if (lane != nullptr) {
244 cancel = lane->cancel_request; 244 cancel = lane->cancelRequest;
245 } 245 }
246 cancel = (cancel != CancelRequest::None) ? cancel : linda->simulate_cancel; 246 cancel = (cancel != CancelRequest::None) ? cancel : linda->cancelRequest;
247 // if user wants to cancel, or looped because of a timeout, the call returns without sending anything 247 // if user wants to cancel, or looped because of a timeout, the call returns without sending anything
248 if (!try_again || cancel != CancelRequest::None) { 248 if (!try_again || cancel != CancelRequest::None) {
249 pushed.emplace(0); 249 pushed.emplace(0);
@@ -262,7 +262,7 @@ LUAG_FUNC(linda_send)
262 262
263 if (ret) { 263 if (ret) {
264 // Wake up ALL waiting threads 264 // Wake up ALL waiting threads
265 linda->m_write_happened.notify_all(); 265 linda->writeHappened.notify_all();
266 break; 266 break;
267 } 267 }
268 268
@@ -280,11 +280,11 @@ LUAG_FUNC(linda_send)
280 LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case 280 LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case
281 lane->status = Lane::Waiting; 281 lane->status = Lane::Waiting;
282 LUA_ASSERT(L_, lane->waiting_on == nullptr); 282 LUA_ASSERT(L_, lane->waiting_on == nullptr);
283 lane->waiting_on = &linda->m_read_happened; 283 lane->waiting_on = &linda->readHappened;
284 } 284 }
285 // could not send because no room: wait until some data was read before trying again, or until timeout is reached 285 // could not send because no room: wait until some data was read before trying again, or until timeout is reached
286 std::unique_lock<std::mutex> keeper_lock{ K->m_mutex, std::adopt_lock }; 286 std::unique_lock<std::mutex> keeper_lock{ K->mutex, std::adopt_lock };
287 std::cv_status const status{ linda->m_read_happened.wait_until(keeper_lock, until) }; 287 std::cv_status const status{ linda->readHappened.wait_until(keeper_lock, until) };
288 keeper_lock.release(); // we don't want to release the lock! 288 keeper_lock.release(); // we don't want to release the lock!
289 try_again = (status == std::cv_status::no_timeout); // detect spurious wakeups 289 try_again = (status == std::cv_status::no_timeout); // detect spurious wakeups
290 if (lane != nullptr) { 290 if (lane != nullptr) {
@@ -390,9 +390,9 @@ LUAG_FUNC(linda_receive)
390 STACK_CHECK_START_REL(KL, 0); 390 STACK_CHECK_START_REL(KL, 0);
391 for (bool try_again{ true };;) { 391 for (bool try_again{ true };;) {
392 if (lane != nullptr) { 392 if (lane != nullptr) {
393 cancel = lane->cancel_request; 393 cancel = lane->cancelRequest;
394 } 394 }
395 cancel = (cancel != CancelRequest::None) ? cancel : linda->simulate_cancel; 395 cancel = (cancel != CancelRequest::None) ? cancel : linda->cancelRequest;
396 // if user wants to cancel, or looped because of a timeout, the call returns without sending anything 396 // if user wants to cancel, or looped because of a timeout, the call returns without sending anything
397 if (!try_again || cancel != CancelRequest::None) { 397 if (!try_again || cancel != CancelRequest::None) {
398 pushed.emplace(0); 398 pushed.emplace(0);
@@ -410,7 +410,7 @@ LUAG_FUNC(linda_receive)
410 keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper); 410 keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper);
411 // To be done from within the 'K' locking area 411 // To be done from within the 'K' locking area
412 // 412 //
413 linda->m_read_happened.notify_all(); 413 linda->readHappened.notify_all();
414 break; 414 break;
415 } 415 }
416 416
@@ -427,11 +427,11 @@ LUAG_FUNC(linda_receive)
427 LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case 427 LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case
428 lane->status = Lane::Waiting; 428 lane->status = Lane::Waiting;
429 LUA_ASSERT(L_, lane->waiting_on == nullptr); 429 LUA_ASSERT(L_, lane->waiting_on == nullptr);
430 lane->waiting_on = &linda->m_write_happened; 430 lane->waiting_on = &linda->writeHappened;
431 } 431 }
432 // not enough data to read: wakeup when data was sent, or when timeout is reached 432 // not enough data to read: wakeup when data was sent, or when timeout is reached
433 std::unique_lock<std::mutex> keeper_lock{ K->m_mutex, std::adopt_lock }; 433 std::unique_lock<std::mutex> keeper_lock{ K->mutex, std::adopt_lock };
434 std::cv_status const status{ linda->m_write_happened.wait_until(keeper_lock, until) }; 434 std::cv_status const status{ linda->writeHappened.wait_until(keeper_lock, until) };
435 keeper_lock.release(); // we don't want to release the lock! 435 keeper_lock.release(); // we don't want to release the lock!
436 try_again = (status == std::cv_status::no_timeout); // detect spurious wakeups 436 try_again = (status == std::cv_status::no_timeout); // detect spurious wakeups
437 if (lane != nullptr) { 437 if (lane != nullptr) {
@@ -483,7 +483,7 @@ LUAG_FUNC(linda_set)
483 483
484 Keeper* const K{ linda->whichKeeper() }; 484 Keeper* const K{ linda->whichKeeper() };
485 KeeperCallResult pushed; 485 KeeperCallResult pushed;
486 if (linda->simulate_cancel == CancelRequest::None) { 486 if (linda->cancelRequest == CancelRequest::None) {
487 if (has_value) { 487 if (has_value) {
488 // convert nils to some special non-nil sentinel in sent values 488 // convert nils to some special non-nil sentinel in sent values
489 keeper_toggle_nil_sentinels(L_, 3, LookupMode::ToKeeper); 489 keeper_toggle_nil_sentinels(L_, 3, LookupMode::ToKeeper);
@@ -494,12 +494,12 @@ LUAG_FUNC(linda_set)
494 494
495 if (has_value) { 495 if (has_value) {
496 // we put some data in the slot, tell readers that they should wake 496 // we put some data in the slot, tell readers that they should wake
497 linda->m_write_happened.notify_all(); // To be done from within the 'K' locking area 497 linda->writeHappened.notify_all(); // To be done from within the 'K' locking area
498 } 498 }
499 if (pushed.value() == 1) { 499 if (pushed.value() == 1) {
500 // the key was full, but it is no longer the case, tell writers they should wake 500 // the key was full, but it is no longer the case, tell writers they should wake
501 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1); 501 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1);
502 linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area 502 linda->readHappened.notify_all(); // To be done from within the 'K' locking area
503 } 503 }
504 } 504 }
505 } else { // linda is cancelled 505 } else { // linda is cancelled
@@ -553,7 +553,7 @@ LUAG_FUNC(linda_get)
553 check_key_types(L_, 2, 2); 553 check_key_types(L_, 2, 2);
554 554
555 KeeperCallResult pushed; 555 KeeperCallResult pushed;
556 if (linda->simulate_cancel == CancelRequest::None) { 556 if (linda->cancelRequest == CancelRequest::None) {
557 Keeper* const K{ linda->whichKeeper() }; 557 Keeper* const K{ linda->whichKeeper() };
558 pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L_, linda, 2); 558 pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L_, linda, 2);
559 if (pushed.value_or(0) > 0) { 559 if (pushed.value_or(0) > 0) {
@@ -590,13 +590,13 @@ LUAG_FUNC(linda_limit)
590 check_key_types(L_, 2, 2); 590 check_key_types(L_, 2, 2);
591 591
592 KeeperCallResult pushed; 592 KeeperCallResult pushed;
593 if (linda->simulate_cancel == CancelRequest::None) { 593 if (linda->cancelRequest == CancelRequest::None) {
594 Keeper* const K{ linda->whichKeeper() }; 594 Keeper* const K{ linda->whichKeeper() };
595 pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L_, linda, 2); 595 pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L_, linda, 2);
596 LUA_ASSERT(L_, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads 596 LUA_ASSERT(L_, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads
597 if (pushed.value() == 1) { 597 if (pushed.value() == 1) {
598 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1); 598 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1);
599 linda->m_read_happened.notify_all(); // To be done from within the 'K' locking area 599 linda->readHappened.notify_all(); // To be done from within the 'K' locking area
600 } 600 }
601 } else { // linda is cancelled 601 } else { // linda is cancelled
602 // do nothing and return lanes.cancel_error 602 // do nothing and return lanes.cancel_error
@@ -623,16 +623,16 @@ LUAG_FUNC(linda_cancel)
623 // make sure we got 3 arguments: the linda, a key and a limit 623 // make sure we got 3 arguments: the linda, a key and a limit
624 luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); 624 luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments");
625 625
626 linda->simulate_cancel = CancelRequest::Soft; 626 linda->cancelRequest = CancelRequest::Soft;
627 if (strcmp(who, "both") == 0) { // tell everyone writers to wake up 627 if (strcmp(who, "both") == 0) { // tell everyone writers to wake up
628 linda->m_write_happened.notify_all(); 628 linda->writeHappened.notify_all();
629 linda->m_read_happened.notify_all(); 629 linda->readHappened.notify_all();
630 } else if (strcmp(who, "none") == 0) { // reset flag 630 } else if (strcmp(who, "none") == 0) { // reset flag
631 linda->simulate_cancel = CancelRequest::None; 631 linda->cancelRequest = CancelRequest::None;
632 } else if (strcmp(who, "read") == 0) { // tell blocked readers to wake up 632 } else if (strcmp(who, "read") == 0) { // tell blocked readers to wake up
633 linda->m_write_happened.notify_all(); 633 linda->writeHappened.notify_all();
634 } else if (strcmp(who, "write") == 0) { // tell blocked writers to wake up 634 } else if (strcmp(who, "write") == 0) { // tell blocked writers to wake up
635 linda->m_read_happened.notify_all(); 635 linda->readHappened.notify_all();
636 } else { 636 } else {
637 raise_luaL_error(L_, "unknown wake hint '%s'", who); 637 raise_luaL_error(L_, "unknown wake hint '%s'", who);
638 } 638 }