Easy SIOF-proofing
authorBen Maurer <bmaurer@fb.com>
Mon, 28 Sep 2015 17:58:44 +0000 (10:58 -0700)
committerfacebook-github-bot-1 <folly-bot@fb.com>
Mon, 28 Sep 2015 18:20:20 +0000 (11:20 -0700)
Summary: These classes are likely to be used as static variables and can
easily be constructed with constexpr.

One that we really ought to fix is SpinLock. Sadly we have a bunch of
implementations of it some of which need initialization.

Reviewed By: @meyering

Differential Revision: D2459355

folly/Baton.h
folly/LifoSem.h
folly/RWSpinLock.h
folly/SharedMutex.h

index 7922ffd0246578f4b1c5375f14b05d3f5e7e9d1a..6737efc52b64e1086c6643257d9daf0e1675eb51 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <stdint.h>
 #include <atomic>
-#include <boost/noncopyable.hpp>
 #include <errno.h>
 #include <assert.h>
 
@@ -44,8 +43,11 @@ namespace folly {
 /// a much more restrictive lifecycle we can also add a bunch of assertions
 /// that can help to catch race conditions ahead of time.
 template <template<typename> class Atom = std::atomic>
-struct Baton : boost::noncopyable {
-  Baton() : state_(INIT) {}
+struct Baton {
+  constexpr Baton() : state_(INIT) {}
+
+  Baton(Baton const&) = delete;
+  Baton& operator=(Baton const&) = delete;
 
   /// It is an error to destroy a Baton on which a thread is currently
   /// wait()ing.  In practice this means that the waiter usually takes
index 24b37c8f411492c5f79b470d4f23ddd54f28499a..b0af517c68b0f9047a766243a8f30eeab6363b9c 100644 (file)
@@ -313,12 +313,15 @@ class LifoSemHead {
 /// See LifoSemNode for more information on how to make your own.
 template <typename Handoff,
           template<typename> class Atom = std::atomic>
-struct LifoSemBase : boost::noncopyable {
+struct LifoSemBase {
 
   /// Constructor
-  explicit LifoSemBase(uint32_t initialValue = 0)
+  constexpr explicit LifoSemBase(uint32_t initialValue = 0)
     : head_(LifoSemHead::fresh(initialValue)) {}
 
+  LifoSemBase(LifoSemBase const&) = delete;
+  LifoSemBase& operator=(LifoSemBase const&) = delete;
+
   /// Silently saturates if value is already 2^32-1
   void post() {
     auto idx = incrOrPop(1);
@@ -591,7 +594,7 @@ struct LifoSemBase : boost::noncopyable {
 
 template <template<typename> class Atom, class BatonType>
 struct LifoSemImpl : public detail::LifoSemBase<BatonType, Atom> {
-  explicit LifoSemImpl(uint32_t v = 0)
+  constexpr explicit LifoSemImpl(uint32_t v = 0)
     : detail::LifoSemBase<BatonType, Atom>(v) {}
 };
 
index 09914e8a6dd75b7d6197479d59211743c0b10469..a054d51be2161d8071390b4ed051b5c7a1df99e5 100644 (file)
@@ -141,7 +141,6 @@ pthread_rwlock_t Read        728698     24us       101ns     7.28ms     194us
 #include <atomic>
 #include <string>
 #include <algorithm>
-#include <boost/noncopyable.hpp>
 
 #include <sched.h>
 #include <glog/logging.h>
@@ -165,10 +164,13 @@ namespace folly {
  * UpgradeLockable concepts except the TimedLockable related locking/unlocking
  * interfaces.
  */
-class RWSpinLock : boost::noncopyable {
+class RWSpinLock {
   enum : int32_t { READER = 4, UPGRADED = 2, WRITER = 1 };
  public:
-  RWSpinLock() : bits_(0) {}
+  constexpr RWSpinLock() : bits_(0) {}
+
+  RWSpinLock(RWSpinLock const&) = delete;
+  RWSpinLock& operator=(RWSpinLock const&) = delete;
 
   // Lockable Concept
   void lock() {
@@ -505,7 +507,7 @@ struct RWTicketIntTrait<32> {
 
 
 template<size_t kBitWidth, bool kFavorWriter=false>
-class RWTicketSpinLockT : boost::noncopyable {
+class RWTicketSpinLockT {
   typedef detail::RWTicketIntTrait<kBitWidth> IntTraitType;
   typedef typename detail::RWTicketIntTrait<kBitWidth>::FullInt FullInt;
   typedef typename detail::RWTicketIntTrait<kBitWidth>::HalfInt HalfInt;
@@ -513,6 +515,7 @@ class RWTicketSpinLockT : boost::noncopyable {
     QuarterInt;
 
   union RWTicket {
+    constexpr RWTicket() : whole(0) {}
     FullInt whole;
     HalfInt readWrite;
     __extension__ struct {
@@ -537,9 +540,10 @@ class RWTicketSpinLockT : boost::noncopyable {
 
  public:
 
-  RWTicketSpinLockT() {
-    store_release(&ticket.whole, FullInt(0));
-  }
+  constexpr RWTicketSpinLockT() {}
+
+  RWTicketSpinLockT(RWTicketSpinLockT const&) = delete;
+  RWTicketSpinLockT& operator=(RWTicketSpinLockT const&) = delete;
 
   void lock() {
     if (kFavorWriter) {
index 796323dd0f175d67a578cbe43fbd9367ae656c06..ebe8d794c385b4ead4cae7e99835f3aea6e96bbb 100644 (file)
@@ -237,7 +237,7 @@ class SharedMutexImpl {
   class UpgradeHolder;
   class WriteHolder;
 
-  SharedMutexImpl() : state_(0) {}
+  constexpr SharedMutexImpl() : state_(0) {}
 
   SharedMutexImpl(const SharedMutexImpl&) = delete;
   SharedMutexImpl(SharedMutexImpl&&) = delete;