proxygen
folly::futures::Barrier Class Reference

#include <Barrier.h>

Classes

struct  ControlBlock
 
struct  ControlBlockAndPromise
 

Public Member Functions

 Barrier (uint32_t n)
 
 ~Barrier ()
 
folly::Future< bool > wait ()
 

Private Types

typedef folly::Promise< bool > BoolPromise
 

Private Member Functions

ControlBlockallocateControlBlock ()
 
void freeControlBlock (ControlBlock *b)
 

Static Private Member Functions

static BoolPromisepromises (ControlBlock *cb)
 
static size_t controlBlockSize (size_t n)
 

Private Attributes

uint32_t size_
 
std::atomic< ControlBlock * > controlBlock_
 

Static Private Attributes

static constexpr uint64_t kReaderShift = 32
 
static constexpr uint64_t kReader = uint64_t(1) << kReaderShift
 
static constexpr uint64_t kValueMask = kReader - 1
 

Detailed Description

Definition at line 45 of file Barrier.h.

Member Typedef Documentation

Definition at line 53 of file Barrier.h.

Constructor & Destructor Documentation

folly::futures::Barrier::Barrier ( uint32_t  n)
explicit

Definition at line 23 of file Barrier.cpp.

std::atomic< ControlBlock * > controlBlock_
Definition: Barrier.h:94
ControlBlock * allocateControlBlock()
Definition: Barrier.cpp:41
folly::futures::Barrier::~Barrier ( )

Definition at line 26 of file Barrier.cpp.

References controlBlock_, freeControlBlock(), i, kReaderShift, kValueMask, promises(), uint32_t, and val.

26  {
27  auto block = controlBlock_.load(std::memory_order_relaxed);
28  auto prev = block->valueAndReaderCount.load(std::memory_order_relaxed);
29  DCHECK_EQ(prev >> kReaderShift, 0u);
30  auto val = prev & kValueMask;
31  auto p = promises(block);
32 
33  for (uint32_t i = 0; i < val; ++i) {
34  p[i].setException(
35  folly::make_exception_wrapper<std::runtime_error>("Barrier destroyed"));
36  }
37 
39 }
static constexpr uint64_t kReaderShift
Definition: Barrier.h:55
double val
Definition: String.cpp:273
std::atomic< ControlBlock * > controlBlock_
Definition: Barrier.h:94
static BoolPromise * promises(ControlBlock *cb)
Definition: Barrier.h:82
static constexpr uint64_t kValueMask
Definition: Barrier.h:57
void freeControlBlock(ControlBlock *b)
Definition: Barrier.cpp:64

Member Function Documentation

auto folly::futures::Barrier::allocateControlBlock ( )
private

Definition at line 41 of file Barrier.cpp.

References controlBlockSize(), i, promises(), size_, and uint32_t.

Referenced by controlBlockSize(), and wait().

41  {
42  auto storage = malloc(controlBlockSize(size_));
43  if (!storage) {
44  throw_exception<std::bad_alloc>();
45  }
46  auto block = ::new (storage) ControlBlock();
47 
48  auto p = promises(block);
49  uint32_t i = 0;
50  try {
51  for (i = 0; i < size_; ++i) {
52  new (p + i) BoolPromise();
53  }
54  } catch (...) {
55  for (; i != 0; --i) {
56  p[i - 1].~BoolPromise();
57  }
58  throw;
59  }
60 
61  return block;
62 }
folly::Promise< bool > BoolPromise
Definition: Barrier.h:53
static size_t controlBlockSize(size_t n)
Definition: Barrier.h:86
static BoolPromise * promises(ControlBlock *cb)
Definition: Barrier.h:82
static size_t folly::futures::Barrier::controlBlockSize ( size_t  n)
inlinestaticprivate

Definition at line 86 of file Barrier.h.

References allocateControlBlock(), b, freeControlBlock(), and promises().

Referenced by allocateControlBlock().

86  {
87  return offsetof(ControlBlockAndPromise, promises) + n * sizeof(BoolPromise);
88  }
folly::Promise< bool > BoolPromise
Definition: Barrier.h:53
static BoolPromise * promises(ControlBlock *cb)
Definition: Barrier.h:82
void folly::futures::Barrier::freeControlBlock ( ControlBlock b)
private

Definition at line 64 of file Barrier.cpp.

References bm::free(), i, promises(), size_, and uint32_t.

Referenced by controlBlockSize(), wait(), and ~Barrier().

64  {
65  auto p = promises(block);
66  for (uint32_t i = size_; i != 0; --i) {
67  p[i - 1].~BoolPromise();
68  }
69  free(block);
70 }
void free()
static BoolPromise * promises(ControlBlock *cb)
Definition: Barrier.h:82
static BoolPromise* folly::futures::Barrier::promises ( ControlBlock cb)
inlinestaticprivate

Definition at line 82 of file Barrier.h.

Referenced by allocateControlBlock(), controlBlockSize(), freeControlBlock(), wait(), and ~Barrier().

82  {
83  return reinterpret_cast<ControlBlockAndPromise*>(cb)->promises;
84  }
static BoolPromise * promises(ControlBlock *cb)
Definition: Barrier.h:82
folly::Future< bool > folly::futures::Barrier::wait ( )

Definition at line 72 of file Barrier.cpp.

References allocateControlBlock(), controlBlock_, freeControlBlock(), i, kReader, kValueMask, promises(), size_, uint32_t, and uint64_t.

Referenced by folly::futures::test::TEST(), TEST_F(), and TYPED_TEST().

72  {
73  // Load the current control block first. As we know there is at least
74  // one thread in the current epoch (us), this means that the value is
75  // < size_, so controlBlock_ can't change until we bump the value below.
76  auto block = controlBlock_.load(std::memory_order_acquire);
77  auto p = promises(block);
78 
79  // Bump the value and record ourselves as reader.
80  // This ensures that block stays allocated, as the reader count is > 0.
81  auto prev = block->valueAndReaderCount.fetch_add(
82  kReader + 1, std::memory_order_acquire);
83 
84  auto prevValue = static_cast<uint32_t>(prev & kValueMask);
85  DCHECK_LT(prevValue, size_);
86  auto future = p[prevValue].getFuture();
87 
88  if (prevValue + 1 == size_) {
89  // Need to reset the barrier before fulfilling any futures. This is
90  // when the epoch is flipped to the next.
91  controlBlock_.store(allocateControlBlock(), std::memory_order_release);
92 
93  p[0].setValue(true);
94  for (uint32_t i = 1; i < size_; ++i) {
95  p[i].setValue(false);
96  }
97  }
98 
99  // Free the control block if we're the last reader at max value.
100  prev =
101  block->valueAndReaderCount.fetch_sub(kReader, std::memory_order_acq_rel);
102  if (prev == (kReader | uint64_t(size_))) {
103  freeControlBlock(block);
104  }
105 
106  return future;
107 }
static constexpr uint64_t kReader
Definition: Barrier.h:56
std::atomic< ControlBlock * > controlBlock_
Definition: Barrier.h:94
static BoolPromise * promises(ControlBlock *cb)
Definition: Barrier.h:82
ControlBlock * allocateControlBlock()
Definition: Barrier.cpp:41
static constexpr uint64_t kValueMask
Definition: Barrier.h:57
void freeControlBlock(ControlBlock *b)
Definition: Barrier.cpp:64

Member Data Documentation

std::atomic<ControlBlock*> folly::futures::Barrier::controlBlock_
private

Definition at line 94 of file Barrier.h.

Referenced by wait(), and ~Barrier().

constexpr uint64_t folly::futures::Barrier::kReader = uint64_t(1) << kReaderShift
staticprivate

Definition at line 56 of file Barrier.h.

Referenced by wait().

constexpr uint64_t folly::futures::Barrier::kReaderShift = 32
staticprivate

Definition at line 55 of file Barrier.h.

Referenced by ~Barrier().

constexpr uint64_t folly::futures::Barrier::kValueMask = kReader - 1
staticprivate

Definition at line 57 of file Barrier.h.

Referenced by wait(), and ~Barrier().

uint32_t folly::futures::Barrier::size_
private

Definition at line 93 of file Barrier.h.

Referenced by allocateControlBlock(), freeControlBlock(), and wait().


The documentation for this class was generated from the following files: