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 @@
#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
......
......@@ -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) {}
};
......
......@@ -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) {
......
......@@ -237,7 +237,7 @@ class SharedMutexImpl {
class UpgradeHolder;
class WriteHolder;
SharedMutexImpl() : state_(0) {}
constexpr SharedMutexImpl() : state_(0) {}
SharedMutexImpl(const 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