From 0b894c40e54e645bf1da19bcb9a28147ee2ce2b4 Mon Sep 17 00:00:00 2001 From: Marcelo Juchem Date: Tue, 18 Oct 2016 13:49:17 -0700 Subject: [PATCH] Getting fibers to build with boost 1.61 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 | 72 ++++++++++++++++++------ folly/fibers/Fiber.cpp | 10 ++-- folly/fibers/Fiber.h | 8 +-- folly/fibers/FiberManagerInternal-inl.h | 10 ++-- folly/fibers/FiberManagerInternal.h | 4 +- folly/m4/ax_boost_context.m4 | 13 ++++- 6 files changed, 82 insertions(+), 35 deletions(-) diff --git a/folly/fibers/BoostContextCompatibility.h b/folly/fibers/BoostContextCompatibility.h index 4aede8f8..031e18e2 100644 --- a/folly/fibers/BoostContextCompatibility.h +++ b/folly/fibers/BoostContextCompatibility.h @@ -15,9 +15,14 @@ */ #pragma once -#include #include +#if BOOST_VERSION >= 106100 +#include +#else +#include +#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(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; diff --git a/folly/fibers/Fiber.cpp b/folly/fibers/Fiber.cpp index aba1d440..9d68a47c 100644 --- a/folly/fibers/Fiber.cpp +++ b/folly/fibers/Fiber.cpp @@ -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)->fiberFunc(); +void Fiber::fiberFuncHelper(FContext::FiberArg fiber) { + reinterpret_cast(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); diff --git a/folly/fibers/Fiber.h b/folly/fibers/Fiber.h index 062be3b5..b9568e9e 100644 --- a/folly/fibers/Fiber.h +++ b/folly/fibers/Fiber.h @@ -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 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 rcontext_; /**< current RequestContext */ folly::Function func_; /**< task function */ bool recordStackUsed_{false}; diff --git a/folly/fibers/FiberManagerInternal-inl.h b/folly/fibers/FiberManagerInternal-inl.h index abb7d70f..352817f8 100644 --- a/folly/fibers/FiberManagerInternal-inl.h +++ b/folly/fibers/FiberManagerInternal-inl.h @@ -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(fiber); + fiber->data_ = reinterpret_cast(fiber); if (observer_) { observer_->runnable(reinterpret_cast(fiber)); } @@ -299,7 +299,7 @@ void FiberManager::addTask(F&& func) { fiber->setFunction(std::ref(*funcLoc)); } - fiber->data_ = reinterpret_cast(fiber); + fiber->data_ = reinterpret_cast(fiber); readyFibers_.push_back(*fiber); if (observer_) { observer_->runnable(reinterpret_cast(fiber)); @@ -434,7 +434,7 @@ void FiberManager::addTaskFinally(F&& func, G&& finally) { fiber->setFunctionFinally(std::ref(*funcLoc), std::ref(*finallyLoc)); } - fiber->data_ = reinterpret_cast(fiber); + fiber->data_ = reinterpret_cast(fiber); readyFibers_.push_back(*fiber); if (observer_) { observer_->runnable(reinterpret_cast(fiber)); diff --git a/folly/fibers/FiberManagerInternal.h b/folly/fibers/FiberManagerInternal.h index 12669c7c..ea379c67 100644 --- a/folly/fibers/FiberManagerInternal.h +++ b/folly/fibers/FiberManagerInternal.h @@ -341,8 +341,8 @@ class FiberManager : public ::folly::Executor { AtomicIntrusiveLinkedListHook nextRemoteTask; }; - intptr_t activateFiber(Fiber* fiber); - intptr_t deactivateFiber(Fiber* fiber); + FContext::FiberData activateFiber(Fiber* fiber); + FContext::FiberData deactivateFiber(Fiber* fiber); typedef folly::IntrusiveList FiberTailQueue; typedef folly::IntrusiveList diff --git a/folly/m4/ax_boost_context.m4 b/folly/m4/ax_boost_context.m4 index 46517c97..0622a95c 100644 --- a/folly/m4/ax_boost_context.m4 +++ b/folly/m4/ax_boost_context.m4 @@ -69,10 +69,17 @@ AC_DEFUN([AX_BOOST_CONTEXT], CXXFLAGS_SAVE=$CXXFLAGS AC_COMPILE_IFELSE([AC_LANG_PROGRAM( - [[@%:@include -#include + [[@%:@include +#if BOOST_VERSION >= 106100 +# include +#else +# include +#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); -- 2.34.1