proxygen
folly::fibers::Semaphore Class Reference

#include <Semaphore.h>

Public Member Functions

 Semaphore (size_t tokenCount)
 
 Semaphore (const Semaphore &)=delete
 
 Semaphore (Semaphore &&)=delete
 
Semaphoreoperator= (const Semaphore &)=delete
 
Semaphoreoperator= (Semaphore &&)=delete
 
void signal ()
 
void wait ()
 
size_t getCapacity () const
 

Private Member Functions

bool waitSlow ()
 
bool signalSlow ()
 

Private Attributes

size_t capacity_
 
std::atomic< int64_ttokens_
 
folly::Synchronized< std::queue< folly::fibers::Baton * > > waitList_
 

Detailed Description

Definition at line 28 of file Semaphore.h.

Constructor & Destructor Documentation

folly::fibers::Semaphore::Semaphore ( size_t  tokenCount)
inlineexplicit

Definition at line 30 of file Semaphore.h.

References getCapacity(), operator=(), signal(), signalSlow(), wait(), and waitSlow().

31  : capacity_(tokenCount), tokens_(int64_t(capacity_)) {}
std::atomic< int64_t > tokens_
Definition: Semaphore.h:56
folly::fibers::Semaphore::Semaphore ( const Semaphore )
delete
folly::fibers::Semaphore::Semaphore ( Semaphore &&  )
delete

Member Function Documentation

size_t folly::fibers::Semaphore::getCapacity ( ) const

Definition at line 97 of file Semaphore.cpp.

References capacity_.

Referenced by Semaphore().

97  {
98  return capacity_;
99 }
Semaphore& folly::fibers::Semaphore::operator= ( const Semaphore )
delete

Referenced by Semaphore().

Semaphore& folly::fibers::Semaphore::operator= ( Semaphore &&  )
delete
void folly::fibers::Semaphore::signal ( )

Definition at line 44 of file Semaphore.cpp.

References signalSlow(), and tokens_.

Referenced by Semaphore(), and TEST().

44  {
45  auto oldVal = tokens_.load(std::memory_order_acquire);
46  do {
47  if (oldVal == 0) {
48  if (signalSlow()) {
49  break;
50  }
51  }
52  } while (!tokens_.compare_exchange_weak(
53  oldVal,
54  oldVal + 1,
55  std::memory_order_release,
56  std::memory_order_acquire));
57 }
std::atomic< int64_t > tokens_
Definition: Semaphore.h:56
bool folly::fibers::Semaphore::signalSlow ( )
private

Definition at line 21 of file Semaphore.cpp.

References tokens_, and waitList_.

Referenced by Semaphore(), and signal().

21  {
22  // If we signalled a release, notify the waitlist
23  auto waitListLock = waitList_.wlock();
24  auto& waitList = *waitListLock;
25 
26  auto testVal = tokens_.load(std::memory_order_acquire);
27  if (testVal != 0) {
28  return false;
29  }
30 
31  if (waitList.empty()) {
32  // If the waitlist is now empty, ensure the token count increments
33  // No need for CAS here as we will always be under the mutex
34  CHECK(tokens_.compare_exchange_strong(
35  testVal, testVal + 1, std::memory_order_relaxed));
36  } else {
37  // trigger waiter if there is one
38  waitList.front()->post();
39  waitList.pop();
40  }
41  return true;
42 }
std::atomic< int64_t > tokens_
Definition: Semaphore.h:56
folly::Synchronized< std::queue< folly::fibers::Baton * > > waitList_
Definition: Semaphore.h:57
void folly::fibers::Semaphore::wait ( )

Definition at line 80 of file Semaphore.cpp.

References tokens_, and waitSlow().

Referenced by Semaphore(), and TEST().

80  {
81  auto oldVal = tokens_.load(std::memory_order_acquire);
82  do {
83  if (oldVal == 0) {
84  // If waitSlow fails it is because the token is non-zero by the time
85  // the lock is taken, so we can just continue round the loop
86  if (waitSlow()) {
87  break;
88  }
89  }
90  } while (!tokens_.compare_exchange_weak(
91  oldVal,
92  oldVal - 1,
93  std::memory_order_release,
94  std::memory_order_acquire));
95 }
std::atomic< int64_t > tokens_
Definition: Semaphore.h:56
bool folly::fibers::Semaphore::waitSlow ( )
private

Definition at line 59 of file Semaphore.cpp.

References tokens_, folly::fibers::Baton::wait(), and waitList_.

Referenced by Semaphore(), and wait().

59  {
60  // Slow path, create a baton and acquire a mutex to update the wait list
61  folly::fibers::Baton waitBaton;
62 
63  {
64  auto waitListLock = waitList_.wlock();
65  auto& waitList = *waitListLock;
66 
67  auto testVal = tokens_.load(std::memory_order_acquire);
68  if (testVal != 0) {
69  return false;
70  }
71  // prepare baton and add to queue
72  waitList.push(&waitBaton);
73  }
74  // If we managed to create a baton, wait on it
75  // This has to be done here so the mutex has been released
76  waitBaton.wait();
77  return true;
78 }
std::atomic< int64_t > tokens_
Definition: Semaphore.h:56
folly::Synchronized< std::queue< folly::fibers::Baton * > > waitList_
Definition: Semaphore.h:57

Member Data Documentation

size_t folly::fibers::Semaphore::capacity_
private

Definition at line 54 of file Semaphore.h.

Referenced by getCapacity().

std::atomic<int64_t> folly::fibers::Semaphore::tokens_
private

Definition at line 56 of file Semaphore.h.

Referenced by signal(), signalSlow(), wait(), and waitSlow().

folly::Synchronized<std::queue<folly::fibers::Baton*> > folly::fibers::Semaphore::waitList_
private

Definition at line 57 of file Semaphore.h.

Referenced by signalSlow(), and waitSlow().


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