folly copyright 2015 -> copyright 2016
[folly.git] / folly / experimental / fibers / BoostContextCompatibility.h
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 #pragma once
17
18 #include <boost/context/all.hpp>
19 #include <boost/version.hpp>
20
21 /**
22  * Wrappers for different versions of boost::context library
23  * API reference for different versions
24  * Boost 1.51: http://www.boost.org/doc/libs/1_51_0/libs/context/doc/html/context/context/boost_fcontext.html
25  * Boost 1.52: http://www.boost.org/doc/libs/1_52_0/libs/context/doc/html/context/context/boost_fcontext.html
26  * Boost 1.56: http://www.boost.org/doc/libs/1_56_0/libs/context/doc/html/context/context/boost_fcontext.html
27  */
28
29 namespace folly { namespace fibers {
30
31 struct FContext {
32  public:
33
34 #if BOOST_VERSION >= 105200
35   using ContextStruct = boost::context::fcontext_t;
36 #else
37   using ContextStruct = boost::ctx::fcontext_t;
38 #endif
39
40   void* stackLimit() const {
41     return stackLimit_;
42   }
43
44   void* stackBase() const {
45     return stackBase_;
46   }
47
48  private:
49   void* stackLimit_;
50   void* stackBase_;
51
52 #if BOOST_VERSION >= 105600
53   ContextStruct context_;
54 #elif BOOST_VERSION >= 105200
55   ContextStruct* context_;
56 #else
57   ContextStruct context_;
58 #endif
59
60   friend intptr_t jumpContext(FContext* oldC, FContext::ContextStruct* newC,
61                               intptr_t p);
62   friend intptr_t jumpContext(FContext::ContextStruct* oldC, FContext* newC,
63                               intptr_t p);
64   friend FContext makeContext(void* stackLimit, size_t stackSize,
65                               void(*fn)(intptr_t));
66 };
67
68 inline intptr_t jumpContext(FContext* oldC, FContext::ContextStruct* newC,
69                             intptr_t p) {
70
71 #if BOOST_VERSION >= 105600
72   return boost::context::jump_fcontext(&oldC->context_, *newC, p);
73 #elif BOOST_VERSION >= 105200
74   return boost::context::jump_fcontext(oldC->context_, newC, p);
75 #else
76   return jump_fcontext(&oldC->context_, newC, p);
77 #endif
78
79 }
80
81 inline intptr_t jumpContext(FContext::ContextStruct* oldC, FContext* newC,
82                             intptr_t p) {
83
84 #if BOOST_VERSION >= 105200
85   return boost::context::jump_fcontext(oldC, newC->context_, p);
86 #else
87   return jump_fcontext(oldC, &newC->context_, p);
88 #endif
89
90 }
91
92 inline FContext makeContext(void* stackLimit, size_t stackSize,
93                             void(*fn)(intptr_t)) {
94   FContext res;
95   res.stackLimit_ = stackLimit;
96   res.stackBase_ = static_cast<unsigned char*>(stackLimit) + stackSize;
97
98 #if BOOST_VERSION >= 105200
99   res.context_ = boost::context::make_fcontext(res.stackBase_, stackSize, fn);
100 #else
101   res.context_.fc_stack.limit = stackLimit;
102   res.context_.fc_stack.base = res.stackBase_;
103   make_fcontext(&res.context_, fn);
104 #endif
105
106   return res;
107 }
108
109 }}  // folly::fibers