From 56e2da569ebd3781cb4f42fa650377f14c461547 Mon Sep 17 00:00:00 2001 From: Huiba Li Date: Fri, 14 Jun 2024 14:34:19 +0800 Subject: [PATCH] Manual pr 0.6 0.7 (#509) * FIX: lockfree MPMC queue should not fail to pop/push when queue is not empty/full (#504) * FIX: lockfree MPMC queue should not fail to pop/push when queue is not empty/full Signed-off-by: Coldwings * Old CI image not able to access repo, change to preset image Signed-off-by: Coldwings --- .github/workflows/ci.linux.x86-64.yml | 10 ++++---- common/lockfree_queue.h | 28 +++++++--------------- examples/sync-primitive/sync-primitive.cpp | 2 +- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.linux.x86-64.yml b/.github/workflows/ci.linux.x86-64.yml index 453dff50..5adc2347 100644 --- a/.github/workflows/ci.linux.x86-64.yml +++ b/.github/workflows/ci.linux.x86-64.yml @@ -45,7 +45,7 @@ jobs: runs-on: ubuntu-latest container: image: ghcr.io/coldwings/photon-ut-base:latest - options: --cpus 4 + options: --cpus 4 --privileged steps: - uses: szenius/set-timezone@v1.2 with: @@ -86,7 +86,7 @@ jobs: runs-on: ubuntu-latest container: image: ghcr.io/coldwings/photon-ut-base:latest - options: --cpus 4 + options: --cpus 4 --privileged steps: - uses: szenius/set-timezone@v1.2 with: @@ -127,7 +127,7 @@ jobs: runs-on: ubuntu-latest container: image: ghcr.io/coldwings/photon-ut-base:latest - options: --cpus 4 + options: --cpus 4 --privileged steps: - uses: szenius/set-timezone@v1.2 with: @@ -168,7 +168,7 @@ jobs: runs-on: ubuntu-latest container: image: ghcr.io/coldwings/photon-ut-base:latest - options: --cpus 4 + options: --cpus 4 --privileged steps: - uses: szenius/set-timezone@v1.2 with: @@ -209,7 +209,7 @@ jobs: runs-on: ubuntu-latest container: image: ghcr.io/coldwings/photon-ut-base:latest - options: --cpus 4 + options: --cpus 4 --privileged steps: - uses: szenius/set-timezone@v1.2 with: diff --git a/common/lockfree_queue.h b/common/lockfree_queue.h index 2d91d123..62f917b0 100644 --- a/common/lockfree_queue.h +++ b/common/lockfree_queue.h @@ -181,7 +181,7 @@ class LockfreeMPMCRingQueue : public LockfreeRingQueueBase { using Base::empty; using Base::full; - bool push_weak(const T& x) { + bool push(const T& x) { auto t = tail.load(std::memory_order_acquire); for (;;) { auto& slot = slots[idx(t)]; @@ -194,15 +194,16 @@ class LockfreeMPMCRingQueue : public LockfreeRingQueueBase { } } else { auto const prevTail = t; + auto h = head.load(std::memory_order_acquire); t = tail.load(std::memory_order_acquire); - if (t == prevTail) { + if (t == prevTail && Base::check_full(h, t)) { return false; } } } } - bool pop_weak(T& x) { + bool pop(T& x) { auto h = head.load(std::memory_order_acquire); for (;;) { auto& slot = slots[idx(h)]; @@ -215,28 +216,15 @@ class LockfreeMPMCRingQueue : public LockfreeRingQueueBase { } } else { auto const prevHead = h; + auto t = tail.load(std::memory_order_acquire); h = head.load(std::memory_order_acquire); - if (h == prevHead) { + if (h == prevHead && Base::check_empty(h, t)) { return false; } } } } - bool push(const T& x) { - do { - if (push_weak(x)) return true; - } while (!full()); - return false; - } - - bool pop(T& x) { - do { - if (pop_weak(x)) return true; - } while (!empty()); - return false; - } - template void send(const T& x) { static_assert(std::is_base_of::value, @@ -538,8 +526,8 @@ namespace common { * and load balancing. * Watch out that `recv` should run in photon environment (because it has to) * use photon semaphore to be notified that new item has sended. `send` could - * running in photon or std::thread environment (needs to set template `Pause` as - * `ThreadPause`). + * running in photon or std::thread environment (needs to set template `Pause` + * as `ThreadPause`). * * @tparam QueueType shoulde be one of LockfreeMPMCRingQueue, * LockfreeBatchMPMCRingQueue, or LockfreeSPSCRingQueue, with their own template diff --git a/examples/sync-primitive/sync-primitive.cpp b/examples/sync-primitive/sync-primitive.cpp index 173e8ea4..131493b5 100644 --- a/examples/sync-primitive/sync-primitive.cpp +++ b/examples/sync-primitive/sync-primitive.cpp @@ -109,7 +109,7 @@ int main() { while (true) { func_1us(); Message* m; - bool ok = ring.pop_weak(m); + bool ok = ring.pop(m); if (!ok) continue; m->start = std::chrono::steady_clock::now();