Getting fibers to build with boost 1.61
authorMarcelo Juchem <Marcelo.juchem@fb.com>
Tue, 18 Oct 2016 20:49:17 +0000 (13:49 -0700)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Tue, 18 Oct 2016 20:53:37 +0000 (13:53 -0700)
Summary: This diff adapts the fibers code to the modified `fcontext` API from Boost 1.61

Reviewed By: Orvid

Differential Revision: D4035769

fbshipit-source-id: 54a97294d33c2901af78b8dec95baaefa085c4f5

folly/fibers/BoostContextCompatibility.h
folly/fibers/Fiber.cpp
folly/fibers/Fiber.h
folly/fibers/FiberManagerInternal-inl.h
folly/fibers/FiberManagerInternal.h
folly/m4/ax_boost_context.m4

index 4aede8f81dc65fa60783bb2920756e5b81d383ba..031e18e2525002b16125c72b9591e8dc77987e2c 100644 (file)
  */
 #pragma once
 
-#include <boost/context/fcontext.hpp>
 #include <boost/version.hpp>
 
+#if BOOST_VERSION >= 106100
+#include <boost/context/detail/fcontext.hpp>
+#else
+#include <boost/context/fcontext.hpp>
+#endif
+
 /**
  * Wrappers for different versions of boost::context library
  * API reference for different versions
@@ -34,12 +39,28 @@ namespace fibers {
 
 struct FContext {
  public:
-#if BOOST_VERSION >= 105200
+#if BOOST_VERSION >= 106100
+  using ContextStruct = boost::context::detail::fcontext_t;
+#elif BOOST_VERSION >= 105200
   using ContextStruct = boost::context::fcontext_t;
 #else
   using ContextStruct = boost::ctx::fcontext_t;
 #endif
 
+#if BOOST_VERSION >= 106100
+  using FiberArg = boost::context::detail::transfer_t;
+  using FiberData = void*;
+  static void* getFiber(FiberArg arg) {
+    return arg.fctx;
+  }
+#else
+  using FiberArg = intptr_t;
+  using FiberData = intptr_t;
+  static FiberArg getFiber(FiberArg arg) {
+    return arg;
+  }
+#endif
+
   void* stackLimit() const {
     return stackLimit_;
   }
@@ -60,17 +81,24 @@ struct FContext {
   ContextStruct context_;
 #endif
 
-  friend intptr_t
-  jumpContext(FContext* oldC, FContext::ContextStruct* newC, intptr_t p);
-  friend intptr_t
-  jumpContext(FContext::ContextStruct* oldC, FContext* newC, intptr_t p);
+  friend FiberData
+  jumpContext(FContext* oldC, FContext::ContextStruct* newC, FiberData p);
+  friend FiberData
+  jumpContext(FContext::ContextStruct* oldC, FContext* newC, FiberData p);
   friend FContext
-  makeContext(void* stackLimit, size_t stackSize, void (*fn)(intptr_t));
+  makeContext(void* stackLimit, size_t stackSize, void (*fn)(FiberArg));
 };
 
-inline intptr_t
-jumpContext(FContext* oldC, FContext::ContextStruct* newC, intptr_t p) {
-#if BOOST_VERSION >= 105600
+inline FContext::FiberData jumpContext(
+    FContext* oldC,
+    FContext::ContextStruct* newC,
+    FContext::FiberData p) {
+#if BOOST_VERSION >= 106100
+  boost::context::detail::transfer_t result =
+      boost::context::detail::jump_fcontext(*newC, p);
+  oldC->context_ = result.fctx;
+  return result.data;
+#elif BOOST_VERSION >= 105600
   return boost::context::jump_fcontext(&oldC->context_, *newC, p);
 #elif BOOST_VERSION >= 105200
   return boost::context::jump_fcontext(oldC->context_, newC, p);
@@ -79,22 +107,34 @@ jumpContext(FContext* oldC, FContext::ContextStruct* newC, intptr_t p) {
 #endif
 }
 
-inline intptr_t
-jumpContext(FContext::ContextStruct* oldC, FContext* newC, intptr_t p) {
-#if BOOST_VERSION >= 105200
+inline FContext::FiberData jumpContext(
+    FContext::ContextStruct* oldC,
+    FContext* newC,
+    FContext::FiberData p) {
+#if BOOST_VERSION >= 106100
+  boost::context::detail::transfer_t result =
+      boost::context::detail::jump_fcontext(newC->context_, p);
+  *oldC = result.fctx;
+  return result.data;
+#elif BOOST_VERSION >= 105200
   return boost::context::jump_fcontext(oldC, newC->context_, p);
 #else
   return jump_fcontext(oldC, &newC->context_, p);
 #endif
 }
 
-inline FContext
-makeContext(void* stackLimit, size_t stackSize, void (*fn)(intptr_t)) {
+inline FContext makeContext(
+    void* stackLimit,
+    size_t stackSize,
+    void (*fn)(FContext::FiberArg)) {
   FContext res;
   res.stackLimit_ = stackLimit;
   res.stackBase_ = static_cast<unsigned char*>(stackLimit) + stackSize;
 
-#if BOOST_VERSION >= 105200
+#if BOOST_VERSION >= 106100
+  res.context_ =
+      boost::context::detail::make_fcontext(res.stackBase_, stackSize, fn);
+#elif BOOST_VERSION >= 105200
   res.context_ = boost::context::make_fcontext(res.stackBase_, stackSize, fn);
 #else
   res.context_.fc_stack.limit = stackLimit;
index aba1d44065a16860df7bff01c013b3238ee86b79..9d68a47c9dae65365152f8c94c77595cd8b5e690 100644 (file)
@@ -50,7 +50,7 @@ static size_t nonMagicInBytes(const FContext& context) {
 
 } // anonymous namespace
 
-void Fiber::setData(intptr_t data) {
+void Fiber::setData(FContext::FiberData data) {
   DCHECK_EQ(state_, AWAITING);
   data_ = data;
   state_ = READY_TO_RUN;
@@ -121,8 +121,8 @@ void Fiber::recordStackPosition() {
   VLOG(4) << "Stack usage: " << currentPosition;
 }
 
-void Fiber::fiberFuncHelper(intptr_t fiber) {
-  reinterpret_cast<Fiber*>(fiber)->fiberFunc();
+void Fiber::fiberFuncHelper(FContext::FiberArg fiber) {
+  reinterpret_cast<Fiber*>(FContext::getFiber(fiber))->fiberFunc();
 }
 
 void Fiber::fiberFunc() {
@@ -170,8 +170,8 @@ void Fiber::fiberFunc() {
   }
 }
 
-intptr_t Fiber::preempt(State state) {
-  intptr_t ret;
+FContext::FiberData Fiber::preempt(State state) {
+  FContext::FiberData ret;
 
   auto preemptImpl = [&]() mutable {
     DCHECK_EQ(fiberManager_.activeFiber_, this);
index 062be3b5db18693cc9c69277d37512f81568b342..b9568e9e62801ec7eabfa4e4399f241b104bc868 100644 (file)
@@ -49,7 +49,7 @@ class Fiber {
    *
    * @param data this data will be returned by await() when task is resumed.
    */
-  void setData(intptr_t data);
+  void setData(FContext::FiberData data);
 
   Fiber(const Fiber&) = delete;
   Fiber& operator=(const Fiber&) = delete;
@@ -97,7 +97,7 @@ class Fiber {
   template <typename F, typename G>
   void setFunctionFinally(F&& func, G&& finally);
 
-  static void fiberFuncHelper(intptr_t fiber);
+  static void fiberFuncHelper(FContext::FiberArg fiber);
   void fiberFunc();
 
   /**
@@ -108,7 +108,7 @@ class Fiber {
    *
    * @return The value passed back from the main context.
    */
-  intptr_t preempt(State state);
+  FContext::FiberData preempt(State state);
 
   /**
    * Examines how much of the stack we used at this moment and
@@ -118,7 +118,7 @@ class Fiber {
 
   FiberManager& fiberManager_; /**< Associated FiberManager */
   FContext fcontext_; /**< current task execution context */
-  intptr_t data_; /**< Used to keep some data with the Fiber */
+  FContext::FiberData data_; /**< Used to keep some data with the Fiber */
   std::shared_ptr<RequestContext> rcontext_; /**< current RequestContext */
   folly::Function<void()> func_; /**< task function */
   bool recordStackUsed_{false};
index abb7d70ffc03f5497116f8eb0f83289aad05c729..352817f856e788f9c48f5a487d22e80d1e3b91ba 100644 (file)
@@ -58,7 +58,7 @@ inline void FiberManager::ensureLoopScheduled() {
   loopController_->schedule();
 }
 
-inline intptr_t FiberManager::activateFiber(Fiber* fiber) {
+inline FContext::FiberData FiberManager::activateFiber(Fiber* fiber) {
   DCHECK_EQ(activeFiber_, (Fiber*)nullptr);
 
 #ifdef FOLLY_SANITIZE_ADDRESS
@@ -78,7 +78,7 @@ inline intptr_t FiberManager::activateFiber(Fiber* fiber) {
   return jumpContext(&mainContext_, &fiber->fcontext_, fiber->data_);
 }
 
-inline intptr_t FiberManager::deactivateFiber(Fiber* fiber) {
+inline FContext::FiberData FiberManager::deactivateFiber(Fiber* fiber) {
   DCHECK_EQ(activeFiber_, fiber);
 
 #ifdef FOLLY_SANITIZE_ADDRESS
@@ -229,7 +229,7 @@ inline bool FiberManager::loopUntilNoReady() {
       fiber->rcontext_ = std::move(task->rcontext);
 
       fiber->setFunction(std::move(task->func));
-      fiber->data_ = reinterpret_cast<intptr_t>(fiber);
+      fiber->data_ = reinterpret_cast<FContext::FiberData>(fiber);
       if (observer_) {
         observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
       }
@@ -299,7 +299,7 @@ void FiberManager::addTask(F&& func) {
     fiber->setFunction(std::ref(*funcLoc));
   }
 
-  fiber->data_ = reinterpret_cast<intptr_t>(fiber);
+  fiber->data_ = reinterpret_cast<FContext::FiberData>(fiber);
   readyFibers_.push_back(*fiber);
   if (observer_) {
     observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
@@ -434,7 +434,7 @@ void FiberManager::addTaskFinally(F&& func, G&& finally) {
     fiber->setFunctionFinally(std::ref(*funcLoc), std::ref(*finallyLoc));
   }
 
-  fiber->data_ = reinterpret_cast<intptr_t>(fiber);
+  fiber->data_ = reinterpret_cast<FContext::FiberData>(fiber);
   readyFibers_.push_back(*fiber);
   if (observer_) {
     observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
index 12669c7c9cfaa98de1b1ecbc65394e68f706e348..ea379c678bac1383997b6161c4355d8844621975 100644 (file)
@@ -341,8 +341,8 @@ class FiberManager : public ::folly::Executor {
     AtomicIntrusiveLinkedListHook<RemoteTask> nextRemoteTask;
   };
 
-  intptr_t activateFiber(Fiber* fiber);
-  intptr_t deactivateFiber(Fiber* fiber);
+  FContext::FiberData activateFiber(Fiber* fiber);
+  FContext::FiberData deactivateFiber(Fiber* fiber);
 
   typedef folly::IntrusiveList<Fiber, &Fiber::listHook_> FiberTailQueue;
   typedef folly::IntrusiveList<Fiber, &Fiber::globalListHook_>
index 46517c97cf360fb732e5523f114f9d5430c15136..0622a95c75221620547a3882af69104c9c50b247 100644 (file)
@@ -69,10 +69,17 @@ AC_DEFUN([AX_BOOST_CONTEXT],
                        CXXFLAGS_SAVE=$CXXFLAGS
 
                        AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-                               [[@%:@include <boost/context/fcontext.hpp>
-#include <boost/version.hpp>
+                               [[@%:@include <boost/version.hpp>
+#if BOOST_VERSION >= 106100
+# include <boost/context/detail/fcontext.hpp>
+#else
+# include <boost/context/fcontext.hpp>
+#endif
 ]],
-                               [[#if BOOST_VERSION >= 105600
+                               [[#if BOOST_VERSION >= 106100
+  boost::context::detail::fcontext_t fc =
+    boost::context::detail::make_fcontext(0, 0, 0);
+#elif BOOST_VERSION >= 105600
   boost::context::fcontext_t fc = boost::context::make_fcontext(0, 0, 0);
 #else
   boost::context::fcontext_t* fc = boost::context::make_fcontext(0, 0, 0);