From d0e3acee1b3e266e532c398f65e8760dcdd95a88 Mon Sep 17 00:00:00 2001 From: Delyan Kratunov Date: Fri, 30 Oct 2015 14:59:54 -0700 Subject: [PATCH] Add writeAndGetCursor to LockFreeRingBuffer Summary: New API - write an entry and advance a cursor to the just-written slot. Reviewed By: ritzau, yfeldblum Differential Revision: D2599388 fb-gh-sync-id: f3ebfae97de0341f01ffc80ab10221313d02087c --- folly/experimental/LockFreeRingBuffer.h | 10 ++++++++++ .../test/LockFreeRingBufferTest.cpp | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/folly/experimental/LockFreeRingBuffer.h b/folly/experimental/LockFreeRingBuffer.h index 8d7bcc01..0a2d10f3 100644 --- a/folly/experimental/LockFreeRingBuffer.h +++ b/folly/experimental/LockFreeRingBuffer.h @@ -101,6 +101,16 @@ public: slots_[idx(ticket)].write(turn(ticket), value); } + /// Perform a single write of an object of type T. + /// Writes can block iff a previous writer has not yet completed a write + /// for the same slot (before the most recent wrap-around). + /// Returns a Cursor pointing to the just-written T. + Cursor writeAndGetCursor(T& value) noexcept { + uint64_t ticket = ticket_.fetch_add(1); + slots_[idx(ticket)].write(turn(ticket), value); + return Cursor(ticket); + } + /// Read the value at the cursor. /// Returns true if the read succeeded, false otherwise. If the return /// value is false, dest is to be considered partially read and in an diff --git a/folly/experimental/test/LockFreeRingBufferTest.cpp b/folly/experimental/test/LockFreeRingBufferTest.cpp index 30fb074e..4b2447d3 100644 --- a/folly/experimental/test/LockFreeRingBufferTest.cpp +++ b/folly/experimental/test/LockFreeRingBufferTest.cpp @@ -226,4 +226,21 @@ TEST(LockFreeRingBuffer, currentTailRange) { EXPECT_TRUE(midvalue == 1 || midvalue == 2); } +TEST(LockFreeRingBuffer, cursorFromWrites) { + const int capacity = 3; + LockFreeRingBuffer rb(capacity); + + // Workaround for template deduction failure + auto (&cursorValue)(value); + + int val = 0xfaceb00c; + EXPECT_EQ(0, cursorValue(rb.writeAndGetCursor(val))); + EXPECT_EQ(1, cursorValue(rb.writeAndGetCursor(val))); + EXPECT_EQ(2, cursorValue(rb.writeAndGetCursor(val))); + + // Check that rb is giving out actual cursors and not just + // pointing to the current slot. + EXPECT_EQ(3, cursorValue(rb.writeAndGetCursor(val))); +} + } // namespace folly -- 2.34.1