proxygen
folly::fibers::Fiber Class Reference

Fiber object used by FiberManager to execute tasks. More...

#include <Fiber.h>

Classes

class  LocalData
 

Public Member Functions

void resume ()
 
 Fiber (const Fiber &)=delete
 
Fiberoperator= (const Fiber &)=delete
 
 ~Fiber ()
 
std::pair< void *, size_t > getStack () const
 

Private Types

enum  State {
  INVALID, NOT_STARTED, READY_TO_RUN, RUNNING,
  AWAITING, AWAITING_IMMEDIATE, YIELDED
}
 

Private Member Functions

 Fiber (FiberManager &fiberManager)
 
void init (bool recordStackUsed)
 
template<typename F >
void setFunction (F &&func)
 
template<typename F , typename G >
void setFunctionFinally (F &&func, G &&finally)
 
void fiberFunc ()
 
void preempt (State state)
 
void recordStackPosition ()
 
void * getUserBuffer ()
 

Private Attributes

State state_ {INVALID}
 
FiberManagerfiberManager_
 
size_t fiberStackSize_
 
unsigned char * fiberStackLimit_
 
FiberImpl fiberImpl_
 
std::shared_ptr< RequestContextrcontext_
 
folly::Function< void()> func_
 
bool recordStackUsed_ {false}
 
bool stackFilledWithMagic_ {false}
 
folly::AtomicIntrusiveLinkedListHook< FibernextRemoteReady_
 
std::aligned_storage< kUserBufferSize >::type userBuffer_
 
folly::Function< void()> resultFunc_
 
folly::Function< void()> finallyFunc_
 
LocalData localData_
 
folly::IntrusiveListHook listHook_
 
folly::IntrusiveListHook globalListHook_
 
std::thread::id threadId_ {}
 

Static Private Attributes

static constexpr size_t kUserBufferSize = 256
 

Friends

class Baton
 
class FiberManager
 

Detailed Description

Fiber object used by FiberManager to execute tasks.

Each Fiber object can be executing at most one task at a time. In active phase it is running the task function and keeps its context. Fiber is also used to pass data to blocked task and thus unblock it. Each Fiber may be associated with a single FiberManager.

Definition at line 45 of file Fiber.h.

Member Enumeration Documentation

Enumerator
INVALID 

Does't have task function

NOT_STARTED 

Has task function, not started

READY_TO_RUN 

Was started, blocked, then unblocked

RUNNING 

Is running right now

AWAITING 

Is currently blocked

AWAITING_IMMEDIATE 

Was preempted to run an immediate function, and will be resumed right away

YIELDED 

The fiber yielded execution voluntarily

Definition at line 67 of file Fiber.h.

Constructor & Destructor Documentation

folly::fibers::Fiber::Fiber ( const Fiber )
delete
folly::fibers::Fiber::~Fiber ( )

Definition at line 104 of file Fiber.cpp.

References folly::fibers::GuardPageAllocator::deallocate(), fiberManager_, fiberStackLimit_, fiberStackSize_, and folly::fibers::FiberManager::stackAllocator_.

104  {
105 #ifdef FOLLY_SANITIZE_ADDRESS
106  if (asanFakeStack_ != nullptr) {
107  fiberManager_.freeFakeStack(asanFakeStack_);
108  }
109  fiberManager_.unpoisonFiberStack(this);
110 #endif
112 }
void deallocate(unsigned char *limit, size_t size)
unsigned char * fiberStackLimit_
Definition: Fiber.h:111
size_t fiberStackSize_
Definition: Fiber.h:110
FiberManager & fiberManager_
Definition: Fiber.h:109
folly::fibers::Fiber::Fiber ( FiberManager fiberManager)
explicitprivate

Member Function Documentation

void folly::fibers::Fiber::fiberFunc ( )
private

Definition at line 128 of file Fiber.cpp.

References folly::fibers::FiberManager::deactivateFiber(), folly::fibers::FiberManager::exceptionCallback_, fiberManager_, fiberStackLimit_, fiberStackSize_, finallyFunc_, func_, INVALID, max, NOT_STARTED, folly::fibers::FiberManager::options_, recordStackUsed_, resultFunc_, RUNNING, folly::fibers::FiberManager::stackHighWatermark_, folly::fibers::FiberManager::Options::stackSize, state_, threadId_, and UNLIKELY.

Referenced by Fiber(), and init().

128  {
129 #ifdef FOLLY_SANITIZE_ADDRESS
130  fiberManager_.registerFinishSwitchStackWithAsan(
131  nullptr, &asanMainStackBase_, &asanMainStackSize_);
132 #endif
133 
134  while (true) {
135  DCHECK_EQ(state_, NOT_STARTED);
136 
137  threadId_ = localThreadId();
138  state_ = RUNNING;
139 
140  try {
141  if (resultFunc_) {
142  DCHECK(finallyFunc_);
143  DCHECK(!func_);
144 
145  resultFunc_();
146  } else {
147  DCHECK(func_);
148  func_();
149  }
150  } catch (...) {
152  std::current_exception(), "running Fiber func_/resultFunc_");
153  }
154 
155  if (UNLIKELY(recordStackUsed_)) {
158  nonMagicInBytes(fiberStackLimit_, fiberStackSize_));
159  VLOG(3) << "Max stack usage: " << fiberManager_.stackHighWatermark_;
160  CHECK(
163  << "Fiber stack overflow";
164  }
165 
166  state_ = INVALID;
167 
169  }
170 }
LogLevel max
Definition: LogLevel.cpp:31
unsigned char * fiberStackLimit_
Definition: Fiber.h:111
size_t fiberStackSize_
Definition: Fiber.h:110
folly::Function< void()> resultFunc_
Definition: Fiber.h:128
FiberManager & fiberManager_
Definition: Fiber.h:109
folly::Function< void()> func_
Definition: Fiber.h:114
folly::Function< void()> finallyFunc_
Definition: Fiber.h:129
std::thread::id threadId_
Definition: Fiber.h:178
bool recordStackUsed_
Definition: Fiber.h:115
#define UNLIKELY(x)
Definition: Likely.h:48
std::pair<void*, size_t> folly::fibers::Fiber::getStack ( ) const
inline

Retrieve this fiber's base stack and stack size.

Returns
This fiber's stack pointer and stack size.

Definition at line 62 of file Fiber.h.

References fiberStackLimit_, and fiberStackSize_.

Referenced by folly::fibers::FiberManager::activateFiber(), and folly::fibers::FiberManager::FibersPoolResizer::operator()().

62  {
64  }
unsigned char * fiberStackLimit_
Definition: Fiber.h:111
size_t fiberStackSize_
Definition: Fiber.h:110
void * folly::fibers::Fiber::getUserBuffer ( )
inlineprivate

Definition at line 38 of file Fiber-inl.h.

References userBuffer_.

38  {
39  return &userBuffer_;
40 }
std::aligned_storage< kUserBufferSize >::type userBuffer_
Definition: Fiber.h:124
void folly::fibers::Fiber::init ( bool  recordStackUsed)
private

Definition at line 78 of file Fiber.cpp.

References fiberFunc(), fiberImpl_, fiberStackLimit_, fiberStackSize_, recordStackUsed_, stackFilledWithMagic_, uint64_t, and UNLIKELY.

Referenced by folly::fibers::FiberManager::getFiber().

78  {
79 // It is necessary to disable the logic for ASAN because we change
80 // the fiber's stack.
81 #ifndef FOLLY_SANITIZE_ADDRESS
82  recordStackUsed_ = recordStackUsed;
84  CHECK_EQ(
85  reinterpret_cast<intptr_t>(fiberStackLimit_) % sizeof(uint64_t), 0u);
86  CHECK_EQ(fiberStackSize_ % sizeof(uint64_t), 0u);
87  std::fill(
88  reinterpret_cast<uint64_t*>(fiberStackLimit_),
89  reinterpret_cast<uint64_t*>(fiberStackLimit_ + fiberStackSize_),
90  kMagic8Bytes);
91 
92  stackFilledWithMagic_ = true;
93 
94  // newer versions of boost allocate context on fiber stack,
95  // need to create a new one
96  fiberImpl_ =
97  FiberImpl([this] { fiberFunc(); }, fiberStackLimit_, fiberStackSize_);
98  }
99 #else
100  (void)recordStackUsed;
101 #endif
102 }
FiberImpl fiberImpl_
Definition: Fiber.h:112
unsigned char * fiberStackLimit_
Definition: Fiber.h:111
size_t fiberStackSize_
Definition: Fiber.h:110
bool stackFilledWithMagic_
Definition: Fiber.h:116
bool recordStackUsed_
Definition: Fiber.h:115
#define UNLIKELY(x)
Definition: Likely.h:48
Fiber& folly::fibers::Fiber::operator= ( const Fiber )
delete
void folly::fibers::Fiber::preempt ( State  state)
private

Switch out of fiber context into the main context, performing necessary housekeeping for the new state.

Parameters
stateNew state, must not be RUNNING.

Definition at line 172 of file Fiber.cpp.

References folly::fibers::FiberManager::activeFiber_, folly::fibers::FiberManager::deactivateFiber(), fiberManager_, folly::fibers::FiberManager::preemptRunner_, READY_TO_RUN, recordStackPosition(), folly::fibers::InlineFunctionRunner::run(), RUNNING, and state_.

Referenced by folly::fibers::FiberManager::runInMainContext(), folly::fibers::Baton::waitFiber(), and folly::fibers::FiberManager::yield().

172  {
173  auto preemptImpl = [&]() mutable {
174  DCHECK_EQ(fiberManager_.activeFiber_, this);
175  DCHECK_EQ(state_, RUNNING);
176  DCHECK_NE(state, RUNNING);
177  DCHECK(!std::current_exception());
178 
179  state_ = state;
180 
182 
184 
185  DCHECK_EQ(fiberManager_.activeFiber_, this);
186  DCHECK_EQ(state_, READY_TO_RUN);
187  state_ = RUNNING;
188  };
189 
191  fiberManager_.preemptRunner_->run(std::ref(preemptImpl));
192  } else {
193  preemptImpl();
194  }
195 }
virtual void run(folly::Function< void()> func)=0
InlineFunctionRunner * preemptRunner_
void recordStackPosition()
Definition: Fiber.cpp:114
FiberManager & fiberManager_
Definition: Fiber.h:109
state
Definition: http_parser.c:272
void folly::fibers::Fiber::recordStackPosition ( )
private

Examines how much of the stack we used at this moment and registers with the FiberManager (for monitoring).

Definition at line 114 of file Fiber.cpp.

References fiberManager_, fiberStackLimit_, fiberStackSize_, max, and folly::fibers::FiberManager::stackHighWatermark_.

Referenced by preempt().

114  {
115  // For ASAN builds, functions may run on fake stack.
116  // So we cannot get meaningful stack position.
117 #ifndef FOLLY_SANITIZE_ADDRESS
118  int stackDummy;
119  auto currentPosition = static_cast<size_t>(
121  static_cast<unsigned char*>(static_cast<void*>(&stackDummy)));
123  std::max(fiberManager_.stackHighWatermark_, currentPosition);
124  VLOG(4) << "Stack usage: " << currentPosition;
125 #endif
126 }
LogLevel max
Definition: LogLevel.cpp:31
unsigned char * fiberStackLimit_
Definition: Fiber.h:111
size_t fiberStackSize_
Definition: Fiber.h:110
FiberManager & fiberManager_
Definition: Fiber.h:109
void folly::fibers::Fiber::resume ( )

Resume the blocked task

Definition at line 54 of file Fiber.cpp.

References AWAITING, folly::fibers::FiberManager::ensureLoopScheduled(), fiberManager_, LIKELY, folly::fibers::FiberManager::observer_, READY_TO_RUN, folly::fibers::FiberManager::readyFibers_, folly::fibers::FiberManager::remoteReadyInsert(), folly::ExecutionObserver::runnable(), state_, and threadId_.

Referenced by folly::fibers::Baton::FiberWaiter::post().

54  {
55  DCHECK_EQ(state_, AWAITING);
57 
59  fiberManager_.observer_->runnable(reinterpret_cast<uintptr_t>(this));
60  }
61 
62  if (LIKELY(threadId_ == localThreadId())) {
63  fiberManager_.readyFibers_.push_back(*this);
65  } else {
67  }
68 }
#define LIKELY(x)
Definition: Likely.h:47
virtual void runnable(uintptr_t id) noexcept=0
void remoteReadyInsert(Fiber *fiber)
FiberManager & fiberManager_
Definition: Fiber.h:109
std::thread::id threadId_
Definition: Fiber.h:178
template<typename F >
void folly::fibers::Fiber::setFunction ( F &&  func)
private

Definition at line 24 of file Fiber-inl.h.

References func_, INVALID, NOT_STARTED, and state_.

Referenced by folly::fibers::FiberManager::loopUntilNoReadyImpl().

24  {
25  assert(state_ == INVALID);
26  func_ = std::forward<F>(func);
28 }
folly::Function< void()> func_
Definition: Fiber.h:114
template<typename F , typename G >
void folly::fibers::Fiber::setFunctionFinally ( F &&  func,
G &&  finally 
)
private

Definition at line 31 of file Fiber-inl.h.

References finallyFunc_, INVALID, NOT_STARTED, resultFunc_, and state_.

31  {
32  assert(state_ == INVALID);
33  resultFunc_ = std::forward<F>(resultFunc);
34  finallyFunc_ = std::forward<G>(finallyFunc);
36 }
folly::Function< void()> resultFunc_
Definition: Fiber.h:128
folly::Function< void()> finallyFunc_
Definition: Fiber.h:129

Friends And Related Function Documentation

friend class Baton
friend

Definition at line 80 of file Fiber.h.

friend class FiberManager
friend

Definition at line 81 of file Fiber.h.

Member Data Documentation

FiberImpl folly::fibers::Fiber::fiberImpl_
private

underlying fiber implementation

Definition at line 112 of file Fiber.h.

Referenced by folly::fibers::FiberManager::activateFiber(), folly::fibers::FiberManager::deactivateFiber(), and init().

FiberManager& folly::fibers::Fiber::fiberManager_
private

Associated FiberManager

Definition at line 109 of file Fiber.h.

Referenced by Fiber(), fiberFunc(), preempt(), recordStackPosition(), resume(), and ~Fiber().

unsigned char* folly::fibers::Fiber::fiberStackLimit_
private

Definition at line 111 of file Fiber.h.

Referenced by Fiber(), fiberFunc(), getStack(), init(), recordStackPosition(), and ~Fiber().

size_t folly::fibers::Fiber::fiberStackSize_
private

Definition at line 110 of file Fiber.h.

Referenced by Fiber(), fiberFunc(), getStack(), init(), recordStackPosition(), and ~Fiber().

folly::Function<void()> folly::fibers::Fiber::finallyFunc_
private
folly::Function<void()> folly::fibers::Fiber::func_
private

task function

Definition at line 114 of file Fiber.h.

Referenced by fiberFunc(), folly::fibers::FiberManager::runReadyFiber(), and setFunction().

folly::IntrusiveListHook folly::fibers::Fiber::globalListHook_
private

list hook for global list

Definition at line 177 of file Fiber.h.

constexpr size_t folly::fibers::Fiber::kUserBufferSize = 256
staticprivate

Definition at line 123 of file Fiber.h.

folly::IntrusiveListHook folly::fibers::Fiber::listHook_
private

list hook for different FiberManager queues

Definition at line 175 of file Fiber.h.

folly::AtomicIntrusiveLinkedListHook<Fiber> folly::fibers::Fiber::nextRemoteReady_
private

Points to next fiber in remote ready list

Definition at line 121 of file Fiber.h.

std::shared_ptr<RequestContext> folly::fibers::Fiber::rcontext_
private
bool folly::fibers::Fiber::recordStackUsed_ {false}
private

Definition at line 115 of file Fiber.h.

Referenced by fiberFunc(), and init().

folly::Function<void()> folly::fibers::Fiber::resultFunc_
private
bool folly::fibers::Fiber::stackFilledWithMagic_ {false}
private

Definition at line 116 of file Fiber.h.

Referenced by init().

State folly::fibers::Fiber::state_ {INVALID}
private
std::thread::id folly::fibers::Fiber::threadId_ {}
private

Definition at line 178 of file Fiber.h.

Referenced by fiberFunc(), and resume().

std::aligned_storage<kUserBufferSize>::type folly::fibers::Fiber::userBuffer_
private

Definition at line 124 of file Fiber.h.

Referenced by getUserBuffer().


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