unioil-loyalty-rn-app/ios/Pods/Flipper-Folly/folly/fibers/BoostContextCompatibility.h

91 lines
2.7 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <boost/context/detail/fcontext.hpp>
#include <glog/logging.h>
/**
* Wrappers for different versions of boost::context library
* API reference for different versions
* Boost 1.61:
* https://github.com/boostorg/context/blob/boost-1.61.0/include/boost/context/detail/fcontext.hpp
*/
#include <folly/Function.h>
namespace folly {
namespace fibers {
class FiberImpl {
using FiberContext = boost::context::detail::fcontext_t;
using MainContext = boost::context::detail::fcontext_t;
public:
FiberImpl(
folly::Function<void()> func, unsigned char* stackLimit, size_t stackSize)
: func_(std::move(func)) {
auto stackBase = stackLimit + stackSize;
stackBase_ = stackBase;
fiberContext_ =
boost::context::detail::make_fcontext(stackBase, stackSize, &fiberFunc);
}
void activate() {
auto transfer = boost::context::detail::jump_fcontext(fiberContext_, this);
fiberContext_ = transfer.fctx;
auto context = reinterpret_cast<intptr_t>(transfer.data);
DCHECK_EQ(0, context);
}
void deactivate() {
auto transfer =
boost::context::detail::jump_fcontext(mainContext_, nullptr);
mainContext_ = transfer.fctx;
fixStackUnwinding();
auto context = reinterpret_cast<intptr_t>(transfer.data);
DCHECK_EQ(this, reinterpret_cast<FiberImpl*>(context));
}
private:
static void fiberFunc(boost::context::detail::transfer_t transfer) {
auto fiberImpl = reinterpret_cast<FiberImpl*>(transfer.data);
fiberImpl->mainContext_ = transfer.fctx;
fiberImpl->fixStackUnwinding();
fiberImpl->func_();
}
void fixStackUnwinding() {
if (kIsArchAmd64 && kIsLinux) {
// Extract RBP and RIP from main context to stitch main context stack and
// fiber stack.
auto stackBase = reinterpret_cast<void**>(stackBase_);
auto mainContext = reinterpret_cast<void**>(mainContext_);
stackBase[-2] = mainContext[6];
stackBase[-1] = mainContext[7];
}
}
unsigned char* stackBase_;
folly::Function<void()> func_;
FiberContext fiberContext_;
MainContext mainContext_;
};
} // namespace fibers
} // namespace folly