From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on gnuweeb.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NO_DNS_FOR_FROM,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.6 Received: from localhost.localdomain (unknown [180.246.144.41]) by gnuweeb.org (Postfix) with ESMTPSA id 28C6A80932; Tue, 16 Aug 2022 16:53:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=default; t=1660668811; bh=P+G3jUSjgB8UKCqmEEc87atluci7ah7Bg7bjTCCxxwc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hMf47drUm9CYAkNJeAOuIG94f48aScNx+g4LXtJTF1Mmj8gXUGhlHX8LtvNpJP2kE FsnYp6U0+v6bLWm/7s7tIcsbPBxtXVRwu9PAryHmZ0DC0cA1dIIuLi0TB1dpAEnVGy FFEnIeNZHIbvfSaoQoVUcp3Ahy2ItzZKEAOyNfuiG9PiLNHCcM384Y4uj8HnfDAMWt tivSr0Ku/Ib0TXS2n4ObY4CwJjTT5blNuEikY//xqqmrvF/iVzslzDinBwb9dSYbCA bPzUmQOh9waNxRHOBhG6dSsyNdDbLsbyyIppG0g2QYfY8Y5hMjXFPnNcKVGH1w5JR9 jqGkt0aZRQlWg== From: Ammar Faizi To: Alviro Iskandar Setiawan Cc: Ammar Faizi , GNU/Weeb Mailing List Subject: [PATCH ncns v1 2/4] chnet: ring: Improve `PostCQE()` waiting mechanism Date: Tue, 16 Aug 2022 23:53:12 +0700 Message-Id: <20220816165314.3875649-3-ammarfaizi2@gnuweeb.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220816165314.3875649-1-ammarfaizi2@gnuweeb.org> References: <20220816165314.3875649-1-ammarfaizi2@gnuweeb.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Don't use sleep(1) in a loop to wait for the CQE slot be free, instead, use a conditional variable to reduce the loop cycle and also to reduce the latency because the wake up doesn't need to wait for a full second. It just waits until it's signaled whenever the CQE slot becomes available again. Signed-off-by: Ammar Faizi --- chnet/chnet_ring.cc | 42 +++++++++++++++++++++++++++++++++++++++++- chnet/chnet_ring.h | 12 +++++++----- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/chnet/chnet_ring.cc b/chnet/chnet_ring.cc index 966e60e..c9a3da5 100644 --- a/chnet/chnet_ring.cc +++ b/chnet/chnet_ring.cc @@ -34,6 +34,7 @@ CNRingCtx::CNRingCtx(uint32_t entry) state_ = new CNRingState(sq_max, cq_max, 2); state_->cqe_to_wait_.store(0, std::memory_order_relaxed); + state_->nr_post_cqe_wait_.store(0, std::memory_order_relaxed); sq_head_.store(0, std::memory_order_relaxed); sq_tail_.store(0, std::memory_order_relaxed); cq_head_.store(0, std::memory_order_relaxed); @@ -128,16 +129,54 @@ bool CNRingCtx::TryPostCQE(CNRingSQE *sqe, int64_t res) return true; } +void CNRingCtx::WaitForCQEFreeSlot(void) +{ + std::unique_lock lock(state_->post_cqe_lock_); + + state_->nr_post_cqe_wait_++; + state_->post_cqe_cond_.wait(lock, [this]{ + bool ret; + + state_->cqe_lock_.lock(); + ret = !!GetCQENoTailIncrement(); + state_->cqe_lock_.unlock(); + return ret; + }); + state_->nr_post_cqe_wait_--; +} + void CNRingCtx::PostCQE(CNRingSQE *sqe, int64_t res) { while (1) { if (TryPostCQE(sqe, res)) break; - sleep(1); + WaitForCQEFreeSlot(); + } +} + +void CNRingCtx::NotifyWaitCQEFreeSlot(void) +{ + uint32_t nr_wait = state_->nr_post_cqe_wait_.load(); + + if (unlikely(nr_wait)) { + state_->post_cqe_lock_.lock(); + if (nr_wait == 1) + state_->post_cqe_cond_.notify_one(); + else + state_->post_cqe_cond_.notify_all(); + state_->post_cqe_lock_.unlock(); } } +void CNRingCtx::CQAdvance(uint32_t n) +{ + state_->cqe_lock_.lock(); + cq_head_ += n; + state_->cqe_lock_.unlock(); + NotifyWaitCQEFreeSlot(); +} + /* * Use this when the caller is not allowed to block. */ @@ -335,6 +374,7 @@ void CNRingCtx::WaitCQE(uint32_t to_wait) if (to_wait > max_to_wait) to_wait = max_to_wait; + NotifyWaitCQEFreeSlot(); if (to_wait <= cqe_size()) return; diff --git a/chnet/chnet_ring.h b/chnet/chnet_ring.h index b0cfc50..f41d75b 100644 --- a/chnet/chnet_ring.h +++ b/chnet/chnet_ring.h @@ -109,6 +109,10 @@ public: std::mutex cqe_lock_; std::condition_variable cqe_cond_; std::atomic cqe_to_wait_; + + std::mutex post_cqe_lock_; + std::condition_variable post_cqe_cond_; + std::atomic nr_post_cqe_wait_; }; #endif @@ -124,11 +128,7 @@ public: void PostCQE(CNRingSQE *sqe, int64_t res); void CallPostCQE(CNRingSQE *sqe, int64_t res); - - inline void CQAdvance(uint32_t n) - { - cq_head_ += n; - } + void CQAdvance(uint32_t n); inline CNRingCQE *HeadCQE(void) { @@ -158,6 +158,8 @@ private: bool TryPostCQE(CNRingSQE *sqe, int64_t res); CNRingCQE *GetCQENoTailIncrement(void); void NotifyCQEWaiter(void); + void NotifyWaitCQEFreeSlot(void); + void WaitForCQEFreeSlot(void); void IssueSQE(CNRingSQE *sqe); void IssueNopSQE(CNRingSQE *sqe); -- Ammar Faizi