From: Maged Michael Date: Sat, 25 Mar 2017 10:28:15 +0000 (-0700) Subject: (folly) Add lock holder interface to flat combining. Change an assert to a static_assert. X-Git-Tag: v2017.03.27.00~1 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=2e0f52d25a6e165f406a922c2ab657b43e315eae (folly) Add lock holder interface to flat combining. Change an assert to a static_assert. Summary: Two changes: - Add a lock holder interface to enable users to move exclusive access and implicitly release the held lock. - Change an assert to a static_assert to check at compile time if a provided function fits in the Function structure without dynamic allocation. Reviewed By: djwatson Differential Revision: D4770229 fbshipit-source-id: 89408164c08d7660231a6ca4e37637dd688356cd --- diff --git a/folly/experimental/flat_combining/FlatCombining.h b/folly/experimental/flat_combining/FlatCombining.h index 9c033503..445d29a3 100644 --- a/folly/experimental/flat_combining/FlatCombining.h +++ b/folly/experimental/flat_combining/FlatCombining.h @@ -197,15 +197,16 @@ class FlatCombining { template void setFn(Func&& fn) { + static_assert( + std::is_nothrow_constructible< + folly::Function, + _t>>::value, + "Try using a smaller function object that can fit in folly::Function " + "without allocation, or use the custom interface of requestFC() to " + "manage the requested function's arguments and results explicitly " + "in a custom request structure without allocation."); fn_ = std::forward(fn); assert(fn_); - // If the following assertion is triggered, the user should - // either change the provided function, i.e., fn, to fit in - // folly::Function without allocation or use the custom - // interface to request combining for fn and manage its - // arguments (and results, if any) explicitly in a custom - // request structure. - assert(!fn_.hasAllocatedMemory()); } void clearFn() { @@ -276,6 +277,13 @@ class FlatCombining { m_.lock(); } + // Give the caller exclusive access through a lock holder. + // No need for explicit release. + template + void acquireExclusive(LockHolder& l) { + l = LockHolder(m_); + } + // Try to give the caller exclusive access. Returns true iff successful. bool tryExclusive() { return m_.try_lock(); diff --git a/folly/experimental/flat_combining/test/FlatCombiningTestHelpers.h b/folly/experimental/flat_combining/test/FlatCombiningTestHelpers.h index f9b4980d..07742e12 100644 --- a/folly/experimental/flat_combining/test/FlatCombiningTestHelpers.h +++ b/folly/experimental/flat_combining/test/FlatCombiningTestHelpers.h @@ -104,7 +104,21 @@ uint64_t fc_test( } if (excl) { - // test of unstructured exclusive access + // test of exclusive access through a lock holder + { + std::unique_lock l; + ex.acquireExclusive(l); + CHECK(!mutex); + mutex = true; + VLOG(2) << tid << " " << ex.getVal() << " ..........."; + using namespace std::chrono_literals; + /* sleep override */ // for coverage + std::this_thread::sleep_for(10ms); + VLOG(2) << tid << " " << ex.getVal() << " ==========="; + CHECK(mutex); + mutex = false; + } + // test of explicit acquisition and release of exclusive access ex.acquireExclusive(); { CHECK(!mutex);