From: Xuehan Xu Date: Mon, 19 Aug 2024 10:22:01 +0000 (+0800) Subject: crimson/common/tri_mutex: also wake up waiters when demoting X-Git-Tag: testing/wip-vshankar-testing-20240826.122843-debug~3^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=f956fbcf96039cd0cb4651480a82c3d797808497;p=ceph-ci.git crimson/common/tri_mutex: also wake up waiters when demoting Fixes: https://tracker.ceph.com/issues/67604 Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/common/tri_mutex.cc b/src/crimson/common/tri_mutex.cc index f6aabc8fd7e..9c6a64724be 100644 --- a/src/crimson/common/tri_mutex.cc +++ b/src/crimson/common/tri_mutex.cc @@ -75,7 +75,8 @@ void tri_mutex::unlock_for_read() DEBUGDPP("", *this); assert(readers > 0); if (--readers == 0) { - wake(); + assert(!readers && !writers && !exclusively_used); + wake(type_t::none); } } @@ -85,7 +86,9 @@ void tri_mutex::demote_to_read() DEBUGDPP("", *this); assert(exclusively_used); exclusively_used = false; + assert(!readers && !writers && !exclusively_used); ++readers; + wake(type_t::read); } seastar::future<> tri_mutex::lock_for_write() @@ -118,7 +121,8 @@ void tri_mutex::unlock_for_write() DEBUGDPP("", *this); assert(writers > 0); if (--writers == 0) { - wake(); + assert(!readers && !writers && !exclusively_used); + wake(type_t::none); } } @@ -128,7 +132,9 @@ void tri_mutex::demote_to_write() DEBUGDPP("", *this); assert(exclusively_used); exclusively_used = false; + assert(!readers && !writers && !exclusively_used); ++writers; + wake(type_t::write); } // for exclusive users @@ -163,7 +169,8 @@ void tri_mutex::unlock_for_excl() DEBUGDPP("", *this); assert(exclusively_used); exclusively_used = false; - wake(); + assert(!readers && !writers && !exclusively_used); + wake(type_t::none); } bool tri_mutex::is_acquired() const @@ -181,23 +188,22 @@ bool tri_mutex::is_acquired() const } } -void tri_mutex::wake() +void tri_mutex::wake(type_t type_to_wake) { LOG_PREFIX(tri_mutex::wake()); DEBUGDPP("", *this); - assert(!readers && !writers && !exclusively_used); - type_t type = type_t::none; + assert(type_to_wake != type_t::exclusive); while (!waiters.empty()) { auto& waiter = waiters.front(); - if (type == type_t::exclusive) { + if (type_to_wake == type_t::exclusive) { break; - } if (type == type_t::none) { - type = waiter.type; - } else if (type != waiter.type) { + } if (type_to_wake == type_t::none) { + type_to_wake = waiter.type; + } else if (type_to_wake != waiter.type) { // to be woken in the next batch break; } - switch (type) { + switch (type_to_wake) { case type_t::read: ++readers; break; diff --git a/src/crimson/common/tri_mutex.h b/src/crimson/common/tri_mutex.h index 04d156183f6..dd366243fb2 100644 --- a/src/crimson/common/tri_mutex.h +++ b/src/crimson/common/tri_mutex.h @@ -106,7 +106,6 @@ public: } private: - void wake(); unsigned readers = 0; unsigned writers = 0; bool exclusively_used = false; @@ -116,6 +115,7 @@ private: exclusive, none, }; + void wake(type_t); struct waiter_t { waiter_t(seastar::promise<>&& pr, type_t type) : pr(std::move(pr)), type(type)