Add writeAndGetCursor to LockFreeRingBuffer
authorDelyan Kratunov <delyank@fb.com>
Fri, 30 Oct 2015 21:59:54 +0000 (14:59 -0700)
committerfacebook-github-bot-4 <folly-bot@fb.com>
Fri, 30 Oct 2015 23:20:22 +0000 (16:20 -0700)
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
folly/experimental/test/LockFreeRingBufferTest.cpp

index 8d7bcc01be8033fc07a683590d42c3367e44e046..0a2d10f3eaaa48659a412584670687cb7789c5e7 100644 (file)
@@ -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
index 30fb074efbd6c24609cf95878681c6be76085899..4b2447d3e1e6a915d41c9967ecc9119175614858 100644 (file)
@@ -226,4 +226,21 @@ TEST(LockFreeRingBuffer, currentTailRange) {
   EXPECT_TRUE(midvalue == 1 || midvalue == 2);
 }
 
+TEST(LockFreeRingBuffer, cursorFromWrites) {
+  const int capacity = 3;
+  LockFreeRingBuffer<int> rb(capacity);
+
+  // Workaround for template deduction failure
+  auto (&cursorValue)(value<int, std::atomic>);
+
+  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