Flat combining: Add lock holder with deferred option. Minor fixes.
authorMaged Michael <magedmichael@fb.com>
Thu, 27 Apr 2017 13:59:10 +0000 (06:59 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 27 Apr 2017 14:09:13 +0000 (07:09 -0700)
Summary: Added a lock holder with deferred option for cases where the caller may want to call try_lock() later.

Reviewed By: djwatson

Differential Revision: D4949736

fbshipit-source-id: 31e0dc349dc3af9d04a33878e26cef1e48cce674

folly/experimental/flat_combining/FlatCombining.h
folly/experimental/flat_combining/test/FlatCombiningTest.cpp
folly/experimental/flat_combining/test/FlatCombiningTestHelpers.h

index 5f67859..3c951ec 100644 (file)
@@ -236,7 +236,7 @@ class FlatCombining {
   ///   on the request records (if 0, then kDefaultMaxops)
   explicit FlatCombining(
       const bool dedicated = true,
-      uint32_t numRecs = 0, // number of combining records
+      const uint32_t numRecs = 0, // number of combining records
       const uint32_t maxOps = 0 // hint of max ops per combining session
       )
       : numRecs_(numRecs == 0 ? kDefaultNumRecs : numRecs),
@@ -277,13 +277,6 @@ class FlatCombining {
     m_.lock();
   }
 
-  // Give the caller exclusive access through a lock holder.
-  // No need for explicit release.
-  template <typename LockHolder>
-  void acquireExclusive(LockHolder& l) {
-    l = LockHolder(m_);
-  }
-
   // Try to give the caller exclusive access. Returns true iff successful.
   bool tryExclusive() {
     return m_.try_lock();
@@ -294,6 +287,21 @@ class FlatCombining {
     m_.unlock();
   }
 
+  // Give the lock holder ownership of the mutex and exclusive access.
+  // No need for explicit release.
+  template <typename LockHolder>
+  void holdLock(LockHolder& l) {
+    l = LockHolder(m_);
+  }
+
+  // Give the caller's lock holder ownership of the mutex but without
+  // exclusive access. The caller can later use the lock holder to try
+  // to acquire exclusive access.
+  template <typename LockHolder>
+  void holdLock(LockHolder& l, std::defer_lock_t) {
+    l = LockHolder(m_, std::defer_lock);
+  }
+
   // Execute an operation without combining
   template <typename OpFunc>
   void requestNoFC(OpFunc& opFn) {
@@ -556,6 +564,7 @@ class FlatCombining {
     if (!dedicated_) {
       while (isPending()) {
         clearPending();
+        ++sessions_;
         combined_ += combiningSession();
       }
     }
index ff745b2..570a6ef 100644 (file)
@@ -19,6 +19,8 @@
 #include <folly/portability/GTest.h>
 #include <glog/logging.h>
 
+#include <mutex>
+
 using namespace folly::test;
 
 constexpr int LINES = 5;
@@ -34,6 +36,22 @@ struct Params {
 
 class FlatCombiningTest : public ::testing::TestWithParam<Params> {};
 
+TEST(FlatCombiningTest, lock_holder) {
+  folly::FcSimpleExample<> ex(10);
+  {
+    std::unique_lock<std::mutex> l;
+    ex.holdLock(l);
+    CHECK(l.owns_lock());
+  }
+  {
+    std::unique_lock<std::mutex> l;
+    ex.holdLock(l, std::defer_lock);
+    CHECK(l.try_lock());
+  }
+  CHECK(ex.tryExclusive());
+  ex.releaseExclusive();
+}
+
 TEST_P(FlatCombiningTest, combining) {
   Params p = GetParam();
   for (auto n : nthr) {
index 07742e1..623563e 100644 (file)
@@ -107,7 +107,7 @@ uint64_t fc_test(
         // test of exclusive access through a lock holder
         {
           std::unique_lock<Mutex> l;
-          ex.acquireExclusive(l);
+          ex.holdLock(l);
           CHECK(!mutex);
           mutex = true;
           VLOG(2) << tid << " " << ex.getVal() << " ...........";