diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/fiber.cpp | 32 | ||||
| -rw-r--r-- | src/common/fiber.h | 19 |
2 files changed, 32 insertions, 19 deletions
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp index eb59f1aa9..a2c0401c4 100644 --- a/src/common/fiber.cpp +++ b/src/common/fiber.cpp | |||
| @@ -3,18 +3,21 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/fiber.h" | 5 | #include "common/fiber.h" |
| 6 | #ifdef _MSC_VER | ||
| 7 | #include <windows.h> | ||
| 8 | #else | ||
| 9 | #include <boost/context/detail/fcontext.hpp> | ||
| 10 | #endif | ||
| 6 | 11 | ||
| 7 | namespace Common { | 12 | namespace Common { |
| 8 | 13 | ||
| 9 | #ifdef _MSC_VER | 14 | #ifdef _MSC_VER |
| 10 | #include <windows.h> | ||
| 11 | 15 | ||
| 12 | struct Fiber::FiberImpl { | 16 | struct Fiber::FiberImpl { |
| 13 | LPVOID handle = nullptr; | 17 | LPVOID handle = nullptr; |
| 14 | }; | 18 | }; |
| 15 | 19 | ||
| 16 | void Fiber::_start([[maybe_unused]] void* parameter) { | 20 | void Fiber::start() { |
| 17 | guard.lock(); | ||
| 18 | if (previous_fiber) { | 21 | if (previous_fiber) { |
| 19 | previous_fiber->guard.unlock(); | 22 | previous_fiber->guard.unlock(); |
| 20 | previous_fiber = nullptr; | 23 | previous_fiber = nullptr; |
| @@ -22,10 +25,10 @@ void Fiber::_start([[maybe_unused]] void* parameter) { | |||
| 22 | entry_point(start_parameter); | 25 | entry_point(start_parameter); |
| 23 | } | 26 | } |
| 24 | 27 | ||
| 25 | static void __stdcall FiberStartFunc(LPVOID lpFiberParameter) | 28 | void __stdcall Fiber::FiberStartFunc(void* fiber_parameter) |
| 26 | { | 29 | { |
| 27 | auto fiber = static_cast<Fiber *>(lpFiberParameter); | 30 | auto fiber = static_cast<Fiber *>(fiber_parameter); |
| 28 | fiber->_start(nullptr); | 31 | fiber->start(); |
| 29 | } | 32 | } |
| 30 | 33 | ||
| 31 | Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter) | 34 | Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter) |
| @@ -74,30 +77,26 @@ std::shared_ptr<Fiber> Fiber::ThreadToFiber() { | |||
| 74 | 77 | ||
| 75 | #else | 78 | #else |
| 76 | 79 | ||
| 77 | #include <boost/context/detail/fcontext.hpp> | ||
| 78 | |||
| 79 | constexpr std::size_t default_stack_size = 1024 * 1024 * 4; // 4MB | 80 | constexpr std::size_t default_stack_size = 1024 * 1024 * 4; // 4MB |
| 80 | 81 | ||
| 81 | struct Fiber::FiberImpl { | 82 | struct alignas(64) Fiber::FiberImpl { |
| 82 | boost::context::detail::fcontext_t context; | ||
| 83 | std::array<u8, default_stack_size> stack; | 83 | std::array<u8, default_stack_size> stack; |
| 84 | boost::context::detail::fcontext_t context; | ||
| 84 | }; | 85 | }; |
| 85 | 86 | ||
| 86 | void Fiber::_start(void* parameter) { | 87 | void Fiber::start(boost::context::detail::transfer_t& transfer) { |
| 87 | guard.lock(); | ||
| 88 | boost::context::detail::transfer_t* transfer = static_cast<boost::context::detail::transfer_t*>(parameter); | ||
| 89 | if (previous_fiber) { | 88 | if (previous_fiber) { |
| 90 | previous_fiber->impl->context = transfer->fctx; | 89 | previous_fiber->impl->context = transfer.fctx; |
| 91 | previous_fiber->guard.unlock(); | 90 | previous_fiber->guard.unlock(); |
| 92 | previous_fiber = nullptr; | 91 | previous_fiber = nullptr; |
| 93 | } | 92 | } |
| 94 | entry_point(start_parameter); | 93 | entry_point(start_parameter); |
| 95 | } | 94 | } |
| 96 | 95 | ||
| 97 | static void FiberStartFunc(boost::context::detail::transfer_t transfer) | 96 | void Fiber::FiberStartFunc(boost::context::detail::transfer_t transfer) |
| 98 | { | 97 | { |
| 99 | auto fiber = static_cast<Fiber *>(transfer.data); | 98 | auto fiber = static_cast<Fiber *>(transfer.data); |
| 100 | fiber->_start(&transfer); | 99 | fiber->start(transfer); |
| 101 | } | 100 | } |
| 102 | 101 | ||
| 103 | Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter) | 102 | Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter) |
| @@ -139,6 +138,7 @@ void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) { | |||
| 139 | 138 | ||
| 140 | std::shared_ptr<Fiber> Fiber::ThreadToFiber() { | 139 | std::shared_ptr<Fiber> Fiber::ThreadToFiber() { |
| 141 | std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()}; | 140 | std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()}; |
| 141 | fiber->guard.lock(); | ||
| 142 | fiber->is_thread_fiber = true; | 142 | fiber->is_thread_fiber = true; |
| 143 | return fiber; | 143 | return fiber; |
| 144 | } | 144 | } |
diff --git a/src/common/fiber.h b/src/common/fiber.h index ab44905cf..812d6644a 100644 --- a/src/common/fiber.h +++ b/src/common/fiber.h | |||
| @@ -10,6 +10,12 @@ | |||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "common/spin_lock.h" | 11 | #include "common/spin_lock.h" |
| 12 | 12 | ||
| 13 | #ifndef _MSC_VER | ||
| 14 | namespace boost::context::detail { | ||
| 15 | struct transfer_t; | ||
| 16 | } | ||
| 17 | #endif | ||
| 18 | |||
| 13 | namespace Common { | 19 | namespace Common { |
| 14 | 20 | ||
| 15 | class Fiber { | 21 | class Fiber { |
| @@ -31,9 +37,6 @@ public: | |||
| 31 | /// Only call from main thread's fiber | 37 | /// Only call from main thread's fiber |
| 32 | void Exit(); | 38 | void Exit(); |
| 33 | 39 | ||
| 34 | /// Used internally but required to be public, Shall not be used | ||
| 35 | void _start(void* parameter); | ||
| 36 | |||
| 37 | /// Changes the start parameter of the fiber. Has no effect if the fiber already started | 40 | /// Changes the start parameter of the fiber. Has no effect if the fiber already started |
| 38 | void SetStartParameter(void* new_parameter) { | 41 | void SetStartParameter(void* new_parameter) { |
| 39 | start_parameter = new_parameter; | 42 | start_parameter = new_parameter; |
| @@ -42,6 +45,16 @@ public: | |||
| 42 | private: | 45 | private: |
| 43 | Fiber(); | 46 | Fiber(); |
| 44 | 47 | ||
| 48 | #ifdef _MSC_VER | ||
| 49 | void start(); | ||
| 50 | static void FiberStartFunc(void* fiber_parameter); | ||
| 51 | #else | ||
| 52 | void start(boost::context::detail::transfer_t& transfer); | ||
| 53 | static void FiberStartFunc(boost::context::detail::transfer_t transfer); | ||
| 54 | #endif | ||
| 55 | |||
| 56 | |||
| 57 | |||
| 45 | struct FiberImpl; | 58 | struct FiberImpl; |
| 46 | 59 | ||
| 47 | SpinLock guard; | 60 | SpinLock guard; |