diff options
Diffstat (limited to 'src/linda.cpp')
-rw-r--r-- | src/linda.cpp | 72 |
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 }; | |||
53 | Linda::Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_) | 53 | Linda::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 | ||
63 | Linda::~Linda() | 63 | Linda::~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 | ||
94 | char const* Linda::getName() const | 94 | char 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 | } |