Commit 739bdb1c authored by Ben Maurer's avatar Ben Maurer Committed by facebook-github-bot-1

Easy SIOF-proofing

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