Use Fiber locals for TAO Fiber-locals
authorAndrii Grynenko <andrii@fb.com>
Fri, 3 Apr 2015 00:29:35 +0000 (17:29 -0700)
committerViswanath Sivakumar <viswanath@fb.com>
Fri, 10 Apr 2015 03:33:37 +0000 (20:33 -0700)
Summary:
This simplifies TAO fibers locals, using FiberManager based fiber-local storage.
This depends on D1958135.

Test Plan: integration tests

Reviewed By: bwatling@fb.com

Subscribers: alikhtarov

FB internal diff: D1962214

Signature: t1:1962214:1427997755:b546b9039382a7600f234b0a2a60cc96da34e662

folly/experimental/fibers/Fiber-inl.h
folly/experimental/fibers/Fiber.h
folly/experimental/fibers/FiberManager-inl.h
folly/experimental/fibers/FiberManager.h

index 8823caf6cf5dd43c48c7794ce40c6fa59797c72e..9ba00115335c49cb2a6b2f51f1bac0d46e2046b9 100644 (file)
@@ -39,12 +39,6 @@ inline void* Fiber::getUserBuffer() {
   return &userBuffer_;
 }
 
-template <typename G>
-void Fiber::setReadyFunction(G&& func) {
-  assert(state_ == INVALID || state_ == NOT_STARTED);
-  readyFunc_ = std::move(func);
-}
-
 template <typename T>
 T& Fiber::LocalData::get() {
   if (data_) {
index e3a38d554fe2e82c0f12dd21cd471b3b4f827431..df9668d64e1665fa74ad8403b36db5bca725bf3c 100644 (file)
@@ -75,9 +75,6 @@ class Fiber {
   template <typename F, typename G>
   void setFunctionFinally(F&& func, G&& finally);
 
-  template <typename G>
-  void setReadyFunction(G&& func);
-
   static void fiberFuncHelper(intptr_t fiber);
   void fiberFunc();
 
@@ -101,8 +98,6 @@ class Fiber {
   FContext fcontext_;           /**< current task execution context */
   intptr_t data_;               /**< Used to keep some data with the Fiber */
   std::function<void()> func_;  /**< task function */
-  std::function<void()> readyFunc_; /**< function to be executed before jumping
-                                         to this fiber */
 
   /**
    * Points to next fiber in remote ready list
index cf963ee063e9b87805ed1e450d4b4a581dee2f40..4fe0f24fdad2bce183e1d26a92af3b6de13e3ec4 100644 (file)
@@ -46,9 +46,6 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
   while (fiber->state_ == Fiber::NOT_STARTED ||
          fiber->state_ == Fiber::READY_TO_RUN) {
     activeFiber_ = fiber;
-    if (fiber->readyFunc_) {
-      fiber->readyFunc_();
-    }
     jumpContext(&mainContext_, &fiber->fcontext_, fiber->data_);
     if (fiber->state_ == Fiber::AWAITING_IMMEDIATE) {
       try {
@@ -198,22 +195,6 @@ void FiberManager::addTask(F&& func) {
   ensureLoopScheduled();
 }
 
-template <typename F, typename G>
-void FiberManager::addTaskReadyFunc(F&& func, G&& readyFunc) {
-  auto fiber = getFiber();
-  if (currentFiber_) {
-    fiber->localData_ = currentFiber_->localData_;
-  }
-
-  fiber->setFunction(std::forward<F>(func));
-  fiber->setReadyFunction(std::forward<G>(readyFunc));
-
-  fiber->data_ = reinterpret_cast<intptr_t>(fiber);
-  readyFibers_.push_back(*fiber);
-
-  ensureLoopScheduled();
-}
-
 template <typename F>
 void FiberManager::addTaskRemote(F&& func) {
   auto task = [&]() {
@@ -402,8 +383,16 @@ inline bool FiberManager::hasActiveFiber() {
 
 template <typename T>
 T& FiberManager::local() {
-  assert(getFiberManager().currentFiber_ != nullptr);
-  return currentFiber_->localData_.get<T>();
+  if (currentFiber_) {
+    return currentFiber_->localData_.get<T>();
+  }
+  return localThread<T>();
+}
+
+template <typename T>
+T& FiberManager::localThread() {
+  static thread_local T t;
+  return t;
 }
 
 template <typename F>
index e0fbf71c80765f796b6d87f89ea71e9cb8763f16..bddfac99d26f473da2e7aab8c3b2eebf67c2692f 100644 (file)
@@ -135,18 +135,6 @@ class FiberManager {
   template <typename F>
   void addTask(F&& func);
 
-  /**
-   * Add a new task to be executed, along with a function readyFunc_ which needs
-   * to be executed just before jumping to the ready fiber
-   *
-   * @param func Task functor; must have a signature of `T func()` for some T.
-   * @param readyFunc functor that needs to be executed just before jumping to
-   *                  ready fiber on the main context. This can for example be
-   *                  used to set up state before starting or resuming a fiber.
-   */
-  template <typename F, typename G>
-  void addTaskReadyFunc(F&& func, G&& readyFunc);
-
   /**
    * Add a new task to be executed. Safe to call from other threads.
    *
@@ -189,6 +177,9 @@ class FiberManager {
   template <typename T>
   T& local();
 
+  template <typename T>
+  static T& localThread();
+
   /**
    * @return How many fiber objects (and stacks) has this manager allocated.
    */
@@ -403,7 +394,11 @@ inline runInMainContext(F&& func) {
  */
 template <typename T>
 T& local() {
-  return FiberManager::getFiberManager().local<T>();
+  auto fm = FiberManager::getFiberManagerUnsafe();
+  if (fm) {
+    return fm->local<T>();
+  }
+  return FiberManager::localThread<T>();
 }
 
 }}