2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <boost/version.hpp>
19 #if BOOST_VERSION >= 106100
20 #include <boost/context/detail/fcontext.hpp>
22 #include <boost/context/fcontext.hpp>
24 #include <glog/logging.h>
27 * Wrappers for different versions of boost::context library
28 * API reference for different versions
30 * http://www.boost.org/doc/libs/1_51_0/libs/context/doc/html/context/context/boost_fcontext.html
32 * http://www.boost.org/doc/libs/1_52_0/libs/context/doc/html/context/context/boost_fcontext.html
34 * http://www.boost.org/doc/libs/1_56_0/libs/context/doc/html/context/context/boost_fcontext.html
36 * https://github.com/boostorg/context/blob/boost-1.61.0/include/boost/context/detail/fcontext.hpp
43 #if BOOST_VERSION >= 106100
44 using FiberContext = boost::context::detail::fcontext_t;
45 #elif BOOST_VERSION >= 105600
46 using FiberContext = boost::context::fcontext_t;
47 #elif BOOST_VERSION >= 105200
48 using FiberContext = boost::context::fcontext_t*;
50 using FiberContext = boost::ctx::fcontext_t;
53 #if BOOST_VERSION >= 106100
54 using MainContext = boost::context::detail::fcontext_t;
55 #elif BOOST_VERSION >= 105600
56 using MainContext = boost::context::fcontext_t;
57 #elif BOOST_VERSION >= 105200
58 using MainContext = boost::context::fcontext_t;
60 using MainContext = boost::ctx::fcontext_t;
65 folly::Function<void()> func,
66 unsigned char* stackLimit,
68 : func_(std::move(func)) {
69 auto stackBase = stackLimit + stackSize;
70 #if BOOST_VERSION >= 106100
72 boost::context::detail::make_fcontext(stackBase, stackSize, &fiberFunc);
73 #elif BOOST_VERSION >= 105200
75 boost::context::make_fcontext(stackBase, stackSize, &fiberFunc);
77 fiberContext_.fc_stack.limit = stackLimit;
78 fiberContext_.fc_stack.base = stackBase;
79 make_fcontext(&fiberContext_, &fiberFunc);
84 #if BOOST_VERSION >= 106100
85 auto transfer = boost::context::detail::jump_fcontext(fiberContext_, this);
86 fiberContext_ = transfer.fctx;
87 auto context = reinterpret_cast<intptr_t>(transfer.data);
88 #elif BOOST_VERSION >= 105200
89 auto context = boost::context::jump_fcontext(
90 &mainContext_, fiberContext_, reinterpret_cast<intptr_t>(this));
92 auto context = jump_fcontext(
93 &mainContext_, &fiberContext_, reinterpret_cast<intptr_t>(this));
95 DCHECK_EQ(0, context);
99 #if BOOST_VERSION >= 106100
100 auto transfer = boost::context::detail::jump_fcontext(mainContext_, 0);
101 mainContext_ = transfer.fctx;
102 auto context = reinterpret_cast<intptr_t>(transfer.data);
103 #elif BOOST_VERSION >= 105600
105 boost::context::jump_fcontext(&fiberContext_, mainContext_, 0);
106 #elif BOOST_VERSION >= 105200
108 boost::context::jump_fcontext(fiberContext_, &mainContext_, 0);
110 auto context = jump_fcontext(&fiberContext_, &mainContext_, 0);
112 DCHECK_EQ(this, reinterpret_cast<FiberImpl*>(context));
116 #if BOOST_VERSION >= 106100
117 static void fiberFunc(boost::context::detail::transfer_t transfer) {
118 auto fiberImpl = reinterpret_cast<FiberImpl*>(transfer.data);
119 fiberImpl->mainContext_ = transfer.fctx;
123 static void fiberFunc(intptr_t arg) {
124 auto fiberImpl = reinterpret_cast<FiberImpl*>(arg);
129 folly::Function<void()> func_;
130 FiberContext fiberContext_;
131 MainContext mainContext_;