├── assets ├── fibermonitor1.png ├── fibermonitor2.png ├── fibermonitor3.png └── fix8mt_Master_Logo_Green_Trans.png ├── .gitignore ├── LICENSE ├── examples ├── runall ├── fibertest6.cpp ├── fibertest4.cpp ├── fibertest3.cpp ├── fibertest10.cpp ├── fibertest29.cpp ├── fibertest0.cpp ├── fibertest25.cpp ├── fibertest16.cpp ├── fibertest28.cpp ├── fibertest34.cpp ├── fibertest9.cpp ├── fibertest35.cpp ├── fibertest17.cpp ├── fibertest30.cpp ├── fibertest1.cpp ├── fibertest11.cpp ├── fibertest33.cpp ├── fibertest31.cpp ├── fibertest2.cpp ├── fibertest8.cpp ├── fibertest13.cpp ├── fibertest12.cpp ├── fibertest27.cpp ├── fibertest18.cpp ├── fibertest7.cpp ├── fibertest23.cpp ├── fibertest15.cpp ├── fibertest5.cpp ├── fibertest19.cpp ├── fibertest24.cpp ├── fibertest14.cpp ├── fibertest20.cpp ├── fibertest21.cpp ├── fibertest22.cpp ├── fibertest.cpp ├── fibertest26.cpp ├── montest1.cpp ├── fibertest32.cpp └── montest2.cpp ├── test ├── utest02.cpp └── utest01.cpp ├── CMakeLists.txt └── include └── fix8 └── fibermonitor.hpp /assets/fibermonitor1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fix8mt/fiber/HEAD/assets/fibermonitor1.png -------------------------------------------------------------------------------- /assets/fibermonitor2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fix8mt/fiber/HEAD/assets/fibermonitor2.png -------------------------------------------------------------------------------- /assets/fibermonitor3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fix8mt/fiber/HEAD/assets/fibermonitor3.png -------------------------------------------------------------------------------- /assets/fix8mt_Master_Logo_Green_Trans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fix8mt/fiber/HEAD/assets/fix8mt_Master_Logo_Green_Trans.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # misc 35 | *.swp 36 | Session.vim 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /examples/runall: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #----------------------------------------------------------------------------------------- 3 | # fiber (header only) 4 | # Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 5 | # by David L. Dight 6 | # see https:#github.com/fix8mt/fiber 7 | # 8 | # Lightweight header-only stackful per-thread fiber 9 | # with built-in roundrobin scheduler x86_64 / linux only 10 | # 11 | # Distributed under the Boost Software License, Version 1.0 August 17th, 2003 12 | # 13 | # Permission is hereby granted, free of charge, to any person or organization 14 | # obtaining a copy of the software and accompanying documentation covered by 15 | # this license (the "Software") to use, reproduce, display, distribute, 16 | # execute, and transmit the Software, and to prepare derivative works of the 17 | # Software, and to permit third-parties to whom the Software is furnished to 18 | # do so, all subject to the following: 19 | # 20 | # The copyright notices in the Software and this entire statement, including 21 | # the above license grant, this restriction and the following disclaimer, 22 | # must be included in all copies of the Software, in whole or in part, and 23 | # all derivative works of the Software, unless such copies or derivative 24 | # works are solely in the form of machine-executable object code generated by 25 | # a source language processor. 26 | # 27 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | # FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 30 | # SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 31 | # FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 32 | # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 33 | # DEALINGS IN THE SOFTWARE. 34 | #----------------------------------------------------------------------------------------- 35 | for file in `ls ./fibertest* ./utest* | sort -V` 36 | do 37 | if [ -x ${file} ]; then 38 | echo -e "\n\e[1;92mRunning:" ${file} "\e[m" 39 | ${file} 40 | fi 41 | done 42 | -------------------------------------------------------------------------------- /examples/fibertest6.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #define FIBER_NO_MULTITHREADING 37 | #include 38 | 39 | //----------------------------------------------------------------------------------------- 40 | using namespace FIX8; 41 | 42 | void print_a() 43 | { 44 | std::cout << 'a'; 45 | this_fiber::yield(); 46 | } 47 | 48 | void print_b() 49 | { 50 | std::cout << 'b'; 51 | std::thread([]() { std::cout << 'N'; }).detach(); 52 | this_fiber::yield(); 53 | } 54 | 55 | int test() 56 | { 57 | fiber([]() 58 | { 59 | int ii{}; 60 | do print_a(); while (ii++ < 1000); 61 | }).detach(); 62 | 63 | fiber([]() 64 | { 65 | int ii{}; 66 | do print_b(); while (ii++ < 1000); 67 | }).detach(); 68 | return 0; 69 | } 70 | 71 | int main() 72 | { 73 | test(); 74 | std::cout << "xxxx"; 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /examples/fibertest4.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | //----------------------------------------------------------------------------------------- 40 | using namespace FIX8; 41 | 42 | //----------------------------------------------------------------------------------------- 43 | int sub(int arg) 44 | { 45 | fibers::print(); 46 | std::cout << "\tstarting " << arg << '\n'; 47 | for (int ii{}; ii < arg; ) 48 | std::cout << '\t' << arg << ": " << ++ii << '\n'; 49 | std::cout << "\tleaving " << arg << '\n'; 50 | return arg * 100; 51 | } 52 | 53 | //----------------------------------------------------------------------------------------- 54 | int main(void) 55 | { 56 | std::future myfuture { async(&sub, 10) }; 57 | std::cout << "Future result = " << myfuture.get() << '\n'; 58 | fibers::print(); 59 | std::cout << "Exiting from main\n"; 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /examples/fibertest3.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #define FIBER_NO_INSTRUMENTATION 38 | #include 39 | 40 | //----------------------------------------------------------------------------------------- 41 | using namespace FIX8; 42 | 43 | //----------------------------------------------------------------------------------------- 44 | int main(void) 45 | { 46 | std::packaged_task task([](int arg) 47 | { 48 | std::cout << "\tstarting sub\n"; 49 | for (int ii{}; ii < arg; this_fiber::yield()) 50 | std::cout << "\tsub: " << ++ii << '\n'; 51 | std::cout << "\tleaving sub\n"; 52 | return arg * 100; 53 | }); 54 | auto myfuture { task.get_future() }; 55 | fiber myfiber(std::move(task), 10); 56 | for (int ii{}; myfiber; this_fiber::yield()) 57 | std::cout << "main: " << ++ii << '\n'; 58 | std::cout << "Future result = " << myfuture.get() << "\nExiting from main\n"; 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /examples/fibertest10.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | 38 | //----------------------------------------------------------------------------------------- 39 | using namespace FIX8; 40 | 41 | //----------------------------------------------------------------------------------------- 42 | int main() 43 | { 44 | static constexpr const std::array wordset 45 | { 46 | std::array { R"("I)", "all", "said", "It’s", "I’m", "\n –", }, 47 | std::array { "am", "of", "no", "because", "doing", "Albert", }, 48 | std::array { "thankful", "those", "to", "of", "it", "Einstein\n" }, 49 | std::array { "for", "who", "me.", "them", R"(myself.")", "" }, 50 | }; 51 | 52 | for (const auto& pp : wordset) 53 | { 54 | fiber ([](const auto& words) 55 | { 56 | for (auto qq : words) 57 | { 58 | std::cout << qq << ' '; 59 | this_fiber::yield(); 60 | } 61 | }, pp).detach(); 62 | } 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /examples/fibertest29.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | using namespace FIX8; 41 | using namespace std::literals; 42 | 43 | void func (int loops) 44 | { 45 | std::cout << this_fiber::name() << ":entry (fiber id:" << this_fiber::get_id() << ")\n"; 46 | for (int ii{}; ii < loops; ++ii) 47 | { 48 | std::cout << this_fiber::name() << ": " << ii << '\n'; 49 | this_fiber::yield(); 50 | std::this_thread::sleep_for(100ms); 51 | } 52 | this_fiber::schedule_main(); 53 | std::cout << this_fiber::name() << ": exit\n"; 54 | } 55 | 56 | int main(int argc, char *argv[]) 57 | { 58 | fiber f0({"func0"}, func, 5), f1({"func1"}, func, 10), f2({"func2"}, func, 15); 59 | argc > 1 ? fibers::wait_all() : fibers::wait_any(); 60 | std::cout << fibers::size_finished() << " fibers finished, " << fibers::size_accurate() << " remaining\n" 61 | << fibers::kill_all() << " killed\n"; 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /examples/fibertest0.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | using namespace FIX8; 41 | 42 | void doit(int ii) 43 | { 44 | std::cout << (this_fiber::is_main() ? '\0' : '\t') << this_fiber::name() << ':' << ii << '\n'; 45 | this_fiber::yield(); 46 | std::cout << (this_fiber::is_main() ? '\0' : '\t') << this_fiber::name() << ':' << ii << " (resumed)\n"; 47 | } 48 | 49 | void func (int cnt) 50 | { 51 | std::cout << '\t' << this_fiber::name() << ":entry (fiber id:" << this_fiber::get_id() << ")\n"; 52 | for (int ii{}; ii < cnt; doit(ii++)) 53 | ; 54 | fibers::print(); 55 | std::cout << '\t' << this_fiber::name() << ":exit\n"; 56 | } 57 | 58 | int main(int argc, char *argv[]) 59 | { 60 | std::cout << this_fiber::name() << ":entry (fiber id:" << this_fiber::get_id() << ")\n"; 61 | fiber f0({"func"}, &func, 5); 62 | for (int ii{}; f0; doit(ii++)) 63 | ; 64 | std::cout << this_fiber::name() << ":exit\n"; 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /examples/fibertest25.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | 38 | //----------------------------------------------------------------------------------------- 39 | using namespace FIX8; 40 | using namespace std::literals; 41 | 42 | //----------------------------------------------------------------------------------------- 43 | void doit() 44 | { 45 | std::cout << "\tstarting " << this_fiber::name() << '\n'; 46 | this_fiber::yield(); 47 | for(int ii{}; ii < 10; std::this_thread::sleep_for(100ms)) 48 | std::cout << '\t' << this_fiber::name() << ": " << ++ii << '\n'; 49 | std::cout << "\tleaving " << this_fiber::name() << '\n'; 50 | } 51 | 52 | //----------------------------------------------------------------------------------------- 53 | int main(int argc, char *argv[]) 54 | { 55 | auto fb { argc > 1 ? make_fiber({"fiber"}, &doit) : make_fiber({"jfiber"}, &doit) }; 56 | this_fiber::yield(); 57 | fibers::print(); 58 | std::cout << "Exiting from main\n"; 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /examples/fibertest16.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | //----------------------------------------------------------------------------------------- 40 | using namespace FIX8; 41 | using namespace std::literals; 42 | 43 | //----------------------------------------------------------------------------------------- 44 | int main(void) 45 | { 46 | static std::mt19937_64 rnde {std::random_device{}()}; 47 | std::cout << "Starting main\n"; 48 | 49 | for (int ii{}; ii < 1000; ++ii) 50 | { 51 | fiber([](int arg) 52 | { 53 | std::cout << "\tStarting " << this_fiber::name() << '\n'; 54 | for (int ii{}; ii < arg; this_fiber::yield()) 55 | std::cout << "\t\t" << this_fiber::name() << ": " << ++ii << ' ' 56 | << std::uniform_int_distribution{1, 1000000}(rnde) << '\n'; 57 | std::cout << "\tLeaving " << this_fiber::name() << '\n'; 58 | }, 59 | ii + 1).set_params(("sub"s + std::to_string(ii)).c_str(), ii).detach(); 60 | } 61 | fibers::print(); 62 | std::cout << "Exiting main\n"; 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /examples/fibertest28.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | using namespace FIX8; 41 | 42 | struct tell 43 | { 44 | tell() { std::cout << this_fiber::name() << ":entry (fiber id:" << this_fiber::get_id() << ")\n"; } 45 | ~tell() { std::cout << this_fiber::name() << ":exit\n"; } 46 | 47 | static void wrap_yield(int val) 48 | { 49 | std::cout << this_fiber::name() << ": " << val << '\n'; 50 | this_fiber::yield(); 51 | std::cout << this_fiber::name() << ": " << val << " (resumed)\n"; 52 | } 53 | }; 54 | 55 | int main(int argc, char *argv[]) 56 | { 57 | tell wrp; 58 | bool flag{}; 59 | 60 | std::cout << "flag=" << std::boolalpha << flag << '\n'; 61 | fiber f0({"\tfunc"}, [](bool& flag, int cnt) 62 | { 63 | tell wrp1; 64 | fibers::print(); 65 | for (int kk{}; kk < cnt; tell::wrap_yield(kk++)); 66 | flag = true; 67 | }, std::ref(flag), 5); 68 | for (int ii{}; f0; tell::wrap_yield(ii++)) 69 | ; 70 | std::cout << "flag=" << std::boolalpha << flag << '\n'; 71 | return 0; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /examples/fibertest34.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | using namespace FIX8; 41 | 42 | class doit 43 | { 44 | int ii{}; 45 | 46 | public: 47 | template 48 | void run(Fn cond) 49 | { 50 | const char spacer { this_fiber::is_main() ? '\0' : '\t' }; 51 | std::cout << spacer << this_fiber::name() << ":entry (fiber id:" << this_fiber::get_id() << ")\n"; 52 | for (; cond(); ++ii) 53 | { 54 | std::cout << spacer << this_fiber::name() << ':' << ii << '\n'; 55 | this_fiber::yield(); 56 | std::cout << spacer << this_fiber::name() << ':' << ii << " (resumed)\n"; 57 | } 58 | if (!this_fiber::is_main()) 59 | fibers::print(); 60 | std::cout << spacer << this_fiber::name() << ":exit\n"; 61 | } 62 | void run(int cnt) { run([this, cnt]() { return ii < cnt; }); } 63 | }; 64 | 65 | int main(int argc, char *argv[]) 66 | { 67 | doit a, b; 68 | fiber f0({"func"}, static_cast(&doit::run), &a, 5); 69 | b.run([&f0]() { return f0.joinable(); }); 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /examples/fibertest9.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | //----------------------------------------------------------------------------------------- 43 | using namespace FIX8; 44 | 45 | //----------------------------------------------------------------------------------------- 46 | struct foo : fiber 47 | { 48 | constexpr foo(fiber_params&& fp) : fiber(std::move(fp), [this]() 49 | { 50 | std::cout << "\tstarting " << name() << '\n'; 51 | for (int ii{}; ii < 5; this_fiber::yield()) 52 | std::cout << '\t' << name() << ": " << std::dec << ++ii << '\n'; 53 | fibers::print(); 54 | std::cout << "\tleaving " << name() << '\n'; 55 | }) {} 56 | }; 57 | 58 | //----------------------------------------------------------------------------------------- 59 | int main(void) 60 | { 61 | foo sub_co({"sub_co"}), sub_co1({"sub_co1"}), sub_co2({"sub_co2"}); 62 | for (int ii{}; fibers::has_fibers(); this_fiber::yield()) 63 | std::cout << "main: " << ++ii << '\n'; 64 | std::cout << "exiting main\n"; 65 | fibers::print(); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /examples/fibertest35.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | //----------------------------------------------------------------------------------------- 44 | using namespace FIX8; 45 | 46 | //----------------------------------------------------------------------------------------- 47 | int main(int argc, char *argv[]) 48 | { 49 | int num{18}; 50 | if (argc > 1) 51 | { 52 | try 53 | { 54 | if ((num = std::stoi(argv[1])) <= 0) 55 | throw std::invalid_argument("count must be +ve integer"); 56 | } 57 | catch (const std::exception& e) 58 | { 59 | std::cerr << "exception: " << e.what() << " (" << argv[1] << ')' << std::endl; 60 | exit(1); 61 | } 62 | } 63 | uint64_t val{}; 64 | auto func ([&val](int cnt) // lambda works with any numeric type 65 | { 66 | for(decltype(val) next{1}; --cnt; this_fiber::yield()) 67 | val = std::exchange(next, val + next); 68 | }); 69 | for (fiber f0(func, num); f0; f0.resume()) 70 | std::cout << val << ' '; 71 | std::cout << std::endl; 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /examples/fibertest17.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | //----------------------------------------------------------------------------------------- 45 | using namespace FIX8; 46 | using namespace std::literals; 47 | 48 | //----------------------------------------------------------------------------------------- 49 | int main(void) 50 | { 51 | std::cout << "Starting main\n"; 52 | std::mt19937_64 rnde {std::random_device{}()}; 53 | std::uniform_int_distribution agen {1, 1000}, pgen {1, 1000000}; 54 | 55 | for (int ii{}; ii < 10; ++ii) 56 | { 57 | fiber([&rnde,&pgen](int arg) 58 | { 59 | std::cout << "\tStarting " << this_fiber::name() << ' ' << arg << '\n'; 60 | for (int ii{}; ii < arg; this_fiber::yield()) 61 | std::cout << "\t\t" << this_fiber::name() << ": " << ++ii << ' ' << pgen(rnde) << '\n'; 62 | std::cout << "\tLeaving " << this_fiber::name() << '\n'; 63 | }, 64 | agen(rnde)).set_params(("sub"s + std::to_string(ii)).c_str(), ii).detach(); 65 | } 66 | fibers::print(); 67 | std::cout << "Exiting main\n"; 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /examples/fibertest30.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | //----------------------------------------------------------------------------------------- 42 | using namespace FIX8; 43 | 44 | //----------------------------------------------------------------------------------------- 45 | template 46 | void fibonacci (T& val) 47 | { 48 | int cnt{}; 49 | val = 0; 50 | for(T next{1}; !fibers::terminating(); val = std::exchange(next, val + next)) 51 | { 52 | ++cnt; 53 | this_fiber::yield(); 54 | } 55 | std::cout << "fiber: generated " << cnt << " values\n"; 56 | fibers::print(); 57 | } 58 | 59 | int main(int argc, char *argv[]) 60 | { 61 | int num{18}; 62 | if (argc > 1) try 63 | { 64 | num = std::stoi(argv[1]); 65 | } 66 | catch (const std::exception& e) 67 | { 68 | std::cerr << "exception (" << e.what() << "): " << argv[1] << std::endl; 69 | exit(1); 70 | } 71 | uint64_t val; 72 | fiber(fibonacci, std::ref(val)).detach(); 73 | 74 | while (num--) 75 | { 76 | this_fiber::yield(); 77 | std::cout << val << ' '; 78 | } 79 | std::cout << "\nmain: done\n"; 80 | return 0; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /examples/fibertest1.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | //----------------------------------------------------------------------------------------- 41 | using namespace FIX8; 42 | 43 | //----------------------------------------------------------------------------------------- 44 | class foo : public fiber 45 | { 46 | int _arg; 47 | 48 | public: 49 | foo(int arg) : fiber (&foo::sub, this), _arg(arg) {} 50 | 51 | void sub() 52 | { 53 | std::cout << "\tstarting sub " << _arg << '\n'; 54 | for (int ii{}; ii < _arg; this_fiber::yield()) 55 | std::cout << '\t' << _arg << ": " << ++ii << '\n'; 56 | std::cout << "\tleaving sub " << _arg << '\n'; 57 | } 58 | }; 59 | 60 | //----------------------------------------------------------------------------------------- 61 | int main(void) 62 | { 63 | try 64 | { 65 | foo bar(10); 66 | fibers::print(); 67 | while (fibers::has_fibers()) 68 | { 69 | std::cout << "main\n"; 70 | this_fiber::yield(); 71 | } 72 | fibers::print(); 73 | std::cout << "Exiting from main\n"; 74 | } 75 | catch (const std::exception& e) 76 | { 77 | std::cerr << "\nException: " << e.what() << '\n'; 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /examples/fibertest11.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | 38 | //----------------------------------------------------------------------------------------- 39 | using namespace FIX8; 40 | 41 | //----------------------------------------------------------------------------------------- 42 | int main() 43 | { 44 | static constexpr const std::array wordset 45 | { 46 | std::array { R"("I)", "all", "said", "It’s", "I’m", "\n –", }, 47 | std::array { "thankful", "those", "to", "of", "it", "Einstein\n" }, 48 | std::array { "for", "who", "me.", "them", R"(myself.")", "" }, 49 | std::array { "am", "of", "no", "because", "doing", "Albert", }, 50 | }; 51 | auto func([](const auto& words) 52 | { 53 | for (auto pp : words) 54 | { 55 | std::cout << pp << ' '; 56 | this_fiber::yield(); 57 | } 58 | }); 59 | 60 | std::array work 61 | { 62 | fiber{ {.launch_order=0}, func, wordset[0] }, 63 | fiber{ {.launch_order=2}, func, wordset[1] }, 64 | fiber{ {.launch_order=3}, func, wordset[2] }, 65 | fiber{ {.launch_order=1}, func, wordset[3] } 66 | }; 67 | 68 | fibers::set_flag(global_fiber_flags::skipmain); 69 | this_fiber::yield(); 70 | std::cout << std::endl; 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /examples/fibertest33.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | //----------------------------------------------------------------------------------------- 44 | using namespace FIX8; 45 | 46 | //----------------------------------------------------------------------------------------- 47 | template 48 | void fibonacci (T& val, int cnt) 49 | { 50 | for(T next{1}; --cnt; this_fiber::yield()) 51 | val = std::exchange(next, val + next); 52 | } 53 | 54 | int main(int argc, char *argv[]) 55 | { 56 | int num{18}; 57 | if (argc > 1) 58 | { 59 | if (std::string_view(argv[1]) == "-h") 60 | { 61 | std::cout << "usage: " << argv[0] << " [count]\n"; 62 | return 0; 63 | } 64 | try 65 | { 66 | if ((num = std::stoi(argv[1])) <= 0) 67 | throw std::invalid_argument("count must be +ve integer"); 68 | } 69 | catch (const std::exception& e) 70 | { 71 | std::cerr << "exception: " << e.what() << " (" << argv[1] << ')' << std::endl; 72 | return 1; 73 | } 74 | } 75 | uint64_t val{}; 76 | for (fiber f0(fibonacci, std::ref(val), num); f0; f0.resume()) 77 | std::cout << val << ' '; 78 | std::cout << std::endl; 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /examples/fibertest31.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | //----------------------------------------------------------------------------------------- 43 | using namespace FIX8; 44 | using namespace std::literals; 45 | 46 | //----------------------------------------------------------------------------------------- 47 | struct foo : fiber 48 | { 49 | int _num; 50 | constexpr foo(fiber_params&& fp, int num=5) : fiber(std::move(fp), &foo::sub, this), _num(num) {} 51 | 52 | void sub() 53 | { 54 | std::cout << "\tstarting " << this_fiber::name() << '\n'; 55 | for (int ii{}; ii < _num; this_fiber::yield()) 56 | std::cout << '\t' << this_fiber::name() << ": " << std::dec << ++ii << '\n'; 57 | std::cout << "\tleaving " << this_fiber::name() << '\n'; 58 | } 59 | }; 60 | 61 | //----------------------------------------------------------------------------------------- 62 | int main(void) 63 | { 64 | foo sub_co({"sub_co"}), sub_co1({"sub_co1"}), sub_co2({"sub_co2s"}, 6), sub_co3({"sub_co3s"}, 10); 65 | sub_co2.detach(); 66 | sub_co3.detach(); 67 | for (int ii{}; fibers::has_fibers(); this_fiber::yield()) 68 | std::cout << "main: " << std::dec << ++ii << '\n'; 69 | std::cout << "Exiting from main\n"; 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /examples/fibertest2.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | //----------------------------------------------------------------------------------------- 42 | using namespace FIX8; 43 | 44 | //----------------------------------------------------------------------------------------- 45 | int main(void) 46 | { 47 | try 48 | { 49 | std::promise mypromise; 50 | auto myfuture { mypromise.get_future() }; 51 | fiber sub_co([](int arg, std::promise& pr) 52 | { 53 | std::cout << "\tstarting " << arg << '\n'; 54 | for (int ii{}; ii < arg; ) 55 | { 56 | std::cout << '\t' << arg << ": " << ++ii << '\n'; 57 | this_fiber::yield(); 58 | } 59 | pr.set_value(arg * 100); 60 | std::cout << "\tleaving " << arg << '\n'; 61 | }, 10, std::ref(mypromise)); 62 | 63 | for (int ii{}; sub_co; ) 64 | { 65 | std::cout << "main: " << ++ii << '\n'; 66 | this_fiber::yield(); 67 | } 68 | std::cout << "Exiting from main\n"; 69 | std::cout << "Future result = " << myfuture.get() << '\n'; 70 | //if (myfuture.valid()) 71 | std::cout << "Repeated result (should throw exception) = " << myfuture.get() << '\n'; 72 | } 73 | catch (const std::future_error& e) 74 | { 75 | std::cerr << "Exception: " << e.what() << '(' << e.code() << ")\n"; 76 | } 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /test/utest02.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | //----------------------------------------------------------------------------------------- 49 | using namespace FIX8; 50 | using namespace std::literals; 51 | 52 | //----------------------------------------------------------------------------------------- 53 | void doit() 54 | { 55 | for(int ii{}; ii < 10; ++ii) 56 | std::this_thread::sleep_for(10ms); 57 | } 58 | 59 | TEST_CASE("jfiber - auto joining fiber", "[fiber]") 60 | { 61 | jfiber{doit}; 62 | } 63 | 64 | TEST_CASE("fiber - non auto joining fiber", "[fiber]") 65 | { 66 | fibers::set_flag(global_fiber_flags::excepthandling); 67 | fibers::set_flag(global_fiber_flags::termthrow); 68 | fiber{doit}; 69 | } 70 | 71 | //----------------------------------------------------------------------------------------- 72 | int main(int argc, char *argv[]) 73 | { 74 | int result{}; 75 | try 76 | { 77 | result = Catch::Session().run(argc, argv); 78 | if (fibers::get_exception_ptr()) 79 | std::rethrow_exception(fibers::get_exception_ptr()); 80 | } 81 | catch(const std::exception& e) 82 | { 83 | std::cerr << "exception: " << e.what() << '\n'; 84 | } 85 | 86 | return result; 87 | } 88 | -------------------------------------------------------------------------------- /examples/fibertest8.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | 38 | //----------------------------------------------------------------------------------------- 39 | using namespace FIX8; 40 | 41 | //----------------------------------------------------------------------------------------- 42 | struct foo 43 | { 44 | int _a; 45 | foo(int a) : _a(a) { std::cout << "foo(" << _a << ",this=" << this << ")\n"; } 46 | ~foo() { std::cout << "~foo(" << _a << ")\n"; } 47 | }; 48 | 49 | //----------------------------------------------------------------------------------------- 50 | void sub(int arg, int spacer) 51 | { 52 | foo a(arg); 53 | const auto tabs { std::string(spacer, '\t') }; 54 | std::cout << tabs << "starting " << this_fiber::name() << '\n'; 55 | for (int ii{}; ii < arg; ) 56 | { 57 | std::cout << tabs << this_fiber::name() << ": " << ++ii << '\n'; 58 | this_fiber::yield(); 59 | } 60 | std::cout << tabs << "leaving " << this_fiber::name() << '\n'; 61 | } 62 | 63 | //----------------------------------------------------------------------------------------- 64 | int main() 65 | { 66 | int ii{}; 67 | for (fiber myfiber({"sub"}, &sub, 10, 1); myfiber; this_fiber::yield()) 68 | { 69 | std::cout << "main: " << ++ii << '\n'; 70 | if (ii == 9) 71 | { 72 | myfiber.set_params("sub1").resume_with(&sub, 5, 2); 73 | for (int jj{}; myfiber; this_fiber::yield()) 74 | std::cout << "main1: " << ++jj << '\n'; 75 | } 76 | } 77 | std::cout << "Exiting from main\n"; 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /examples/fibertest13.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | //----------------------------------------------------------------------------------------- 41 | using namespace FIX8; 42 | using namespace std::literals; 43 | 44 | //----------------------------------------------------------------------------------------- 45 | struct blah 46 | { 47 | ~blah() { std::cout << "~blah() - " << this_fiber::name() << '\n'; } 48 | }; 49 | void doit(int arg) 50 | { 51 | blah b; 52 | std::cout << "\tstarting " << this_fiber::name() << ' ' << arg << '\n'; 53 | for (int ii{}; ii < arg; ) 54 | { 55 | std::cout << '\t' << this_fiber::name() << ' ' << arg << ": " << ++ii << '\n'; 56 | this_fiber::yield(); 57 | } 58 | std::cout << "\tleaving " << this_fiber::name() << ' ' << arg << '\n'; 59 | } 60 | 61 | //----------------------------------------------------------------------------------------- 62 | int main(void) 63 | { 64 | fiber sub_co({"sub0"}, &doit, 9), sub_co1({"sub1"}, &doit, 10); 65 | fibers::print(); 66 | for (int ii{}; fibers::has_fibers(); ++ii) 67 | { 68 | if (ii == 2) 69 | { 70 | fibers::print(); 71 | sub_co1.suspend(); 72 | fibers::print(); 73 | } 74 | if (ii == 6) 75 | { 76 | fibers::print(); 77 | sub_co1.unsuspend(); 78 | fibers::print(); 79 | } 80 | this_fiber::yield(); 81 | std::cout << "main: " << std::dec << ii << '\n'; 82 | } 83 | std::cout << "Exiting from main\n"; 84 | fibers::print(); 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /examples/fibertest12.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | //----------------------------------------------------------------------------------------- 40 | using namespace FIX8; 41 | 42 | //----------------------------------------------------------------------------------------- 43 | int main() 44 | { 45 | static constexpr const std::array wordsets 46 | { 47 | std::array { R"("I )", "all ", "said ", "It’s ", "I’m ", "" }, 48 | std::array { "for ", "who ", "me. ", "them ", "myself.\"\n", "" }, 49 | std::array { "am ", "of ", "no ", "because ", "doing ", " - Albert ", }, 50 | std::array { "thankful ", "those ", "to ", "of ", "it ", "Einstein\n" }, 51 | }; 52 | 53 | static const auto func([](const auto& words) 54 | { 55 | for (auto pp : words) 56 | { 57 | std::cout << pp; 58 | this_fiber::yield(); 59 | } 60 | }); 61 | 62 | std::thread([]() 63 | { 64 | launch_all // will print in fiber work order 65 | ( 66 | std::bind(func, wordsets[0]), 67 | std::bind(func, wordsets[1]), 68 | std::bind(func, wordsets[2]), 69 | std::bind(func, wordsets[3]) 70 | ); 71 | }).join(); 72 | 73 | launch_all_with_params // will print in specified order 74 | ( 75 | fiber_params{.launch_order=0}, std::bind(func, wordsets[0]), 76 | fiber_params{.launch_order=3}, std::bind(func, wordsets[1]), 77 | fiber_params{.launch_order=1}, std::bind(func, wordsets[2]), 78 | fiber_params{.launch_order=2}, std::bind(func, wordsets[3]) 79 | ); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /examples/fibertest27.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | //----------------------------------------------------------------------------------------- 41 | using namespace FIX8; 42 | 43 | //----------------------------------------------------------------------------------------- 44 | int main() 45 | { 46 | static constexpr const std::array wordsets 47 | { 48 | std::array { R"("I )", "all ", "said ", "It’s ", "I’m ", "" }, 49 | std::array { "for ", "who ", "me. ", "them ", "myself.\"\n", "" }, 50 | std::array { "am ", "of ", "no ", "because ", "doing ", " - Albert ", }, 51 | std::array { "thankful ", "those ", "to ", "of ", "it ", "Einstein\n" }, 52 | }; 53 | 54 | const auto func([](const auto& words) 55 | { 56 | for (auto pp : words) 57 | { 58 | std::cout << pp; 59 | this_fiber::yield(); 60 | } 61 | }); 62 | 63 | std::list sts; 64 | 65 | launch_all_n 66 | ( 67 | sts, 68 | std::bind(func, wordsets[0]), 69 | std::bind(func, wordsets[1]), 70 | std::bind(func, wordsets[2]), 71 | std::bind(func, wordsets[3]) 72 | ); 73 | fibers::wait_all(); 74 | 75 | sts.clear(); 76 | fibers::set_flag(global_fiber_flags::skipmain); 77 | 78 | launch_all_with_params_n 79 | ( 80 | sts, 81 | fiber_params{.launch_order=0}, std::bind(func, wordsets[0]), 82 | fiber_params{.launch_order=3}, std::bind(func, wordsets[1]), 83 | fiber_params{.launch_order=1}, std::bind(func, wordsets[2]), 84 | fiber_params{.launch_order=2}, std::bind(func, wordsets[3]) 85 | ); 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /examples/fibertest18.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | //----------------------------------------------------------------------------------------- 42 | using namespace FIX8; 43 | using namespace std::literals; 44 | 45 | //----------------------------------------------------------------------------------------- 46 | int main(void) 47 | { 48 | static std::mt19937_64 rnde {std::random_device{}()}; // this one needs to be static 49 | std::cout << "Starting main\n"; 50 | std::list> flist; 51 | 52 | std::thread ([&flist]() 53 | { 54 | for (int ii{1}; ii <= 5; ++ii) 55 | { 56 | std::packaged_task task([](int arg) 57 | { 58 | std::cout << "\tStarting " << this_fiber::name(std::string(this_fiber::name()) + std::to_string(arg)) << '\n'; 59 | int result{}; 60 | for (int ii{}; ii < arg; this_fiber::yield()) 61 | { 62 | result += std::uniform_int_distribution{1, 1000000}(rnde); 63 | std::cout << "\t\t" << this_fiber::name() << ": " << ++ii << ' ' << result << '\n'; 64 | } 65 | std::cout << "\tLeaving " << this_fiber::name() << '\n'; 66 | return result; 67 | }); 68 | flist.emplace_back(task.get_future()); 69 | fiber({.name="sub",.launch_order=ii}, std::move(task), ii).detach(); 70 | } 71 | }).join(); 72 | 73 | int result{}, kk{}; 74 | for (auto& pp : flist) 75 | { 76 | auto val { pp.get() }; 77 | result += val; 78 | std::cout << "got " << ++kk << " (" << val << ")\n"; 79 | } 80 | std::cout << "result = " << result << '\n'; 81 | std::cout << "Exiting main\n"; 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /examples/fibertest7.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | using namespace FIX8; 40 | 41 | //----------------------------------------------------------------------------------------- 42 | // from Dilawar's Blog 43 | // https://dilawar.github.io/posts/2021/2021-11-14-example-boost-fiber/ 44 | //----------------------------------------------------------------------------------------- 45 | int main() 46 | { 47 | static int ii{}; 48 | 49 | fiber([]() 50 | { 51 | do 52 | { 53 | std::printf("%c", 'a'); 54 | this_fiber::yield(); 55 | } 56 | while (++ii < 20); 57 | }).detach(); 58 | 59 | fiber([]() 60 | { 61 | do 62 | { 63 | std::printf("%c", 'b'); 64 | std::thread([]() { std::printf("%c", 'B'); }).detach(); 65 | this_fiber::yield(); 66 | } 67 | while (++ii < 20); 68 | }).detach(); 69 | 70 | std::printf("%c", 'X'); 71 | std::atexit([]() 72 | { 73 | using namespace std::chrono_literals; 74 | std::this_thread::sleep_for(100ms); 75 | std::printf("%c", '\n'); 76 | }); 77 | return 0; 78 | } 79 | 80 | // XabababBabBBabBababBabBabBBabBaB 81 | // XabababBabBBabBabBabBababBabBaBB 82 | // XabababBabBBabBabBababBababBBBaB 83 | // XabababBabBababBBBababBBabBabBaB 84 | // XabababBabBBabBababBabBabBabBBaB 85 | // XabababBabBBabBababBabBabBabBaBB 86 | // XabababBabBBababBabBabBBababBaBB 87 | // XabababBabBabBBabababBBBabBabaBB 88 | // XabababBBabBabababBBabBBababBaBB 89 | // XabababBabBabBabBBababBabBabBBaB 90 | // XabababBBababBabBabBabBBabBabaBB 91 | // XabababBabBabBBababababBBBabBBaB 92 | // XabababBabBBabBababBabBabBBabaBB 93 | // XabababBabBBabBababBabBabBBabBaB 94 | // XabababBabBBababBBababBBababBaBB 95 | // XababBabBababBababBBBabBababBaBB 96 | // XabababBabBBabBababBabBabBBabBaB 97 | // XabababBabBBababBabBabBBababBaBB 98 | -------------------------------------------------------------------------------- /examples/fibertest23.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | //----------------------------------------------------------------------------------------- 44 | using namespace FIX8; 45 | 46 | //----------------------------------------------------------------------------------------- 47 | class foo 48 | { 49 | std::queue _queue; 50 | fiber _produce, _consume; 51 | 52 | public: 53 | foo(int num) : _produce([this](int numtogen) 54 | { 55 | std::cout << "\tproducer:fiber entry (id:" << this_fiber::get_id() << ")\n"; 56 | std::mt19937_64 rnde {std::random_device{}()}; 57 | for (int cnt{}; cnt < numtogen; ++cnt) 58 | { 59 | while(_queue.size() < 5) 60 | _queue.push(std::uniform_int_distribution(1, std::numeric_limits().max())(rnde)); 61 | std::cout << "\tproduced: " << _queue.size() << '\n'; 62 | _consume.resume(); // switch to consumer 63 | } 64 | _consume.schedule(); // consumer is next fiber to run 65 | std::cout << "\tproducer:fiber exit\n"; 66 | }, num), _consume([this]() 67 | { 68 | std::cout << "\tconsumer:fiber entry (id:" << this_fiber::get_id() << ")\n"; 69 | while (_produce) 70 | { 71 | std::cout << "\tconsuming: " << _queue.size() << '\n'; 72 | while(!_queue.empty()) 73 | { 74 | std::cout << "\t\t" << _queue.front() << '\n'; 75 | _queue.pop(); 76 | } 77 | _produce.resume(); // switch to producer 78 | } 79 | std::cout << "\tconsumer:fiber exit\n"; 80 | }) 81 | { 82 | _produce.resume(); // switch to producer 83 | } 84 | }; 85 | 86 | //----------------------------------------------------------------------------------------- 87 | int main(int argc, char *argv[]) 88 | { 89 | std::cout << "main:entry\n"; 90 | foo bar(argc > 1 ? std::stoi(argv[1]) : 10); 91 | std::cout << "main:exit\n"; 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /examples/fibertest15.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | //----------------------------------------------------------------------------------------- 41 | using namespace FIX8; 42 | using namespace std::literals; 43 | 44 | //----------------------------------------------------------------------------------------- 45 | class blah 46 | { 47 | std::string_view tabs; 48 | public: 49 | blah() = default; 50 | blah(std::string_view tb) : tabs(std::move(tb)) {} 51 | ~blah() { std::cout << tabs << "~blah(): " << this_fiber::name() << '\n'; } 52 | }; 53 | 54 | void doit_with_stoprequest(bool& stop_requested) 55 | { 56 | blah b("\t"); 57 | bool waitagain{}; 58 | std::cout << '\t' << "Starting " << this_fiber::name() << '\n'; 59 | for(int ii{};; this_fiber::yield()) 60 | { 61 | std::cout << '\t' << this_fiber::name() << ": " << ++ii << '\n'; 62 | if (stop_requested) 63 | { 64 | if (waitagain) 65 | { 66 | std::cout << '\t' << this_fiber::name() << ": stop actioned\n"; 67 | break; 68 | } 69 | else 70 | { 71 | std::cout << '\t' << this_fiber::name() << ": stop requested\n"; 72 | waitagain = true; 73 | } 74 | } 75 | } 76 | std::cout << '\t' << "Leaving " << this_fiber::name() << '\n'; 77 | } 78 | 79 | //----------------------------------------------------------------------------------------- 80 | int main(void) 81 | { 82 | std::cout << "Starting " << this_fiber::name() << '\n'; 83 | blah b; 84 | bool stop_requested{}; 85 | fiber sub_co({.name="sub",.join=true}, &doit_with_stoprequest, std::ref(stop_requested)); 86 | for (int ii{}; ii < 5; this_fiber::yield()) 87 | { 88 | std::cout << this_fiber::name() << ": " << ++ii << '\n'; 89 | std::this_thread::sleep_for(100ms); 90 | } 91 | stop_requested = true; 92 | this_fiber::yield(); 93 | fibers::print(); 94 | std::cout << "Exiting " << this_fiber::name() << '\n'; 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /examples/fibertest5.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | //----------------------------------------------------------------------------------------- 42 | using namespace FIX8; 43 | 44 | //----------------------------------------------------------------------------------------- 45 | struct blah 46 | { 47 | ~blah() { std::cout << "~blah()\n"; } 48 | }; 49 | 50 | struct foo 51 | { 52 | void sub(int arg, std::promise& pr) 53 | { 54 | blah b; 55 | try 56 | { 57 | std::cout << "\tstarting " << arg << '\n'; 58 | for (int ii{}; ii < arg; ) 59 | { 60 | std::cout << '\t' << arg << ": " << ++ii << '\n'; 61 | this_fiber::yield(); 62 | } 63 | //pr.set_value(arg * 100); 64 | std::cout << "\tleaving " << arg << '\n'; 65 | throw std::runtime_error("test exception"); 66 | } 67 | catch (...) 68 | { 69 | try 70 | { 71 | pr.set_exception(std::current_exception()); 72 | } 73 | catch(...) 74 | { 75 | std::cerr << "pr.set_exception(std::current_exception()) threw\n"; 76 | } 77 | } 78 | } 79 | ~foo() { std::cout << "~foo()\n"; } 80 | }; 81 | 82 | //----------------------------------------------------------------------------------------- 83 | int main(void) 84 | { 85 | foo bar; 86 | std::promise mypromise; 87 | auto myfuture { mypromise.get_future() }; 88 | fiber sub_co(&foo::sub, &bar, 10, std::ref(mypromise)); 89 | for (int ii{}; sub_co; ) 90 | { 91 | std::cout << "main: " << ++ii << '\n'; 92 | this_fiber::yield(); 93 | } 94 | try 95 | { 96 | std::cout << "Future result = " << myfuture.get() << '\n'; 97 | sub_co.join_if(); 98 | } 99 | catch (const std::exception& e) 100 | { 101 | std::cerr << "\nException: " << e.what() << '\n'; 102 | } 103 | std::cout << "Exiting from main\n"; 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /examples/fibertest19.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | //----------------------------------------------------------------------------------------- 41 | using namespace FIX8; 42 | 43 | //----------------------------------------------------------------------------------------- 44 | void func(int arg) 45 | { 46 | const std::string tag { std::string(this_fiber::name()) + ' ' + std::to_string(arg) }; 47 | std::cout << "\tstarting " << tag << '\n'; 48 | for (int ii{}; ii < arg; this_fiber::yield()) 49 | std::cout << "\t\t" << tag << ": " << ++ii << '\n'; 50 | std::cout << "\tleaving " << tag << '\n'; 51 | fibers::print(); 52 | } 53 | 54 | //----------------------------------------------------------------------------------------- 55 | int main(void) 56 | { 57 | auto stack_memory { std::make_unique(32768) }; 58 | std::array fbs 59 | {{ 60 | { {.name="sub01",.stacksz=8192}, &func, 3 }, 61 | { {"sub02",99,false,8192}, &func, 6 }, 62 | { {.name="sub03",.stacksz=8192}, &func, 9 }, 63 | { {.name="sub04",.stacksz=8192}, &func, 12 }, 64 | { {.name="sub05",.stacksz=8192,.stack=make_stack(stack_memory.get())}, &func, 3 }, 65 | { {.name="sub06",.stacksz=8192,.stack=make_stack(stack_memory.get(), 8192)}, &func, 6 }, 66 | { {.name="sub07",.stacksz=8192,.stack=make_stack(stack_memory.get(), 2 * 8192)}, &func, 9 }, 67 | { {.name="sub08",.stacksz=8192,.stack=make_stack(stack_memory.get(), 3 * 8192)}, &func, 12 }, 68 | { {.name="sub09",.stacksz=8192,.stack=make_stack()}, &func, 3 }, 69 | { {.name="sub10",.stacksz=8192,.stack=make_stack()}, &func, 6 }, 70 | { {.name="sub11",.stacksz=8192,.stack=make_stack()}, &func, 9 }, 71 | { {.name="sub12",.stacksz=8192,.stack=make_stack()}, &func, 12 } 72 | }}; 73 | fibers::print(); 74 | for (int ii{}; fibers::has_fibers(); ++ii) 75 | { 76 | std::cout << "main: " << std::dec << ii << '\n'; 77 | this_fiber::yield(); 78 | } 79 | std::cout << "Exiting from main\n"; 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /examples/fibertest24.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | 38 | //----------------------------------------------------------------------------------------- 39 | using namespace FIX8; 40 | using namespace std::chrono_literals; 41 | 42 | //----------------------------------------------------------------------------------------- 43 | void sub(int arg) 44 | { 45 | std::cout << "\tstarting " << this_fiber::name() << '\n'; 46 | for (int ii{}; ii < arg; this_fiber::yield()) 47 | { 48 | std::cout << '\t' << std::this_thread::get_id() << ' ' << this_fiber::name() << ' ' << ++ii << '\n'; 49 | std::this_thread::sleep_for(250ms); 50 | } 51 | std::cout << "\tleaving " << this_fiber::name() << '\n'; 52 | } 53 | 54 | //----------------------------------------------------------------------------------------- 55 | int main(void) 56 | { 57 | fiber f0({"first"}, &sub, 10), f2({"second"}, &sub, 10); 58 | std::thread t1([]() 59 | { 60 | jfiber ft1({"thread:first"}, &sub, 10); 61 | for (int ii{}; fibers::has_fibers(); ++ii) 62 | { 63 | std::cout << "main1 " << ii << '\n'; 64 | switch(ii) 65 | { 66 | case 1: 67 | case 9: 68 | fibers::print(); 69 | [[fallthrough]]; 70 | default: 71 | std::this_thread::sleep_for(250ms); 72 | this_fiber::yield(); 73 | break; 74 | } 75 | } 76 | std::cout << std::this_thread::get_id() << " Exiting from main1\n"; 77 | }); 78 | 79 | std::this_thread::sleep_for(100ms); 80 | 81 | for (int ii{}; fibers::has_fibers(); ++ii) 82 | { 83 | std::cout << "main " << ii << '\n'; 84 | switch(ii) 85 | { 86 | case 5: 87 | std::cout << "transferring " << f0.get_id() << " from " 88 | << std::this_thread::get_id() << " to " << t1.get_id() << '\n'; 89 | f0.move(t1.get_id()); 90 | break; 91 | case 4: 92 | case 9: 93 | fibers::print(); 94 | [[fallthrough]]; 95 | default: 96 | this_fiber::yield(); 97 | break; 98 | } 99 | } 100 | std::cout << "waiting at join...\n"; 101 | fibers::print(); 102 | t1.join(); 103 | std::cout << std::this_thread::get_id() << " Exiting from main\n"; 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /examples/fibertest14.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | //----------------------------------------------------------------------------------------- 42 | using namespace FIX8; 43 | using namespace std::literals; 44 | 45 | //----------------------------------------------------------------------------------------- 46 | struct blah { ~blah() { std::cout << "~blah(): " << this_fiber::name() << '\n'; } }; 47 | 48 | void doit(int arg, std::string_view spacer) 49 | { 50 | blah b; 51 | std::cout << spacer << "starting " << this_fiber::name() << ' ' << arg << '\n'; 52 | for (int ii{}; ii < arg; this_fiber::yield()) 53 | std::cout << spacer << this_fiber::name() << ' ' << arg << ": " << ++ii << '\n'; 54 | std::cout << spacer << "leaving " << this_fiber::name() << ' ' << arg << '\n'; 55 | } 56 | 57 | void doit_with_stoprequest(std::string_view spacer, bool& stop_requested) 58 | { 59 | blah b; 60 | std::cout << spacer << "starting " << this_fiber::name() << '\n'; 61 | for(int ii{};; this_fiber::yield()) 62 | { 63 | std::cout << spacer << this_fiber::name() << ": " << ++ii << '\n'; 64 | if (stop_requested) 65 | { 66 | std::cout << spacer << this_fiber::name() << ": stop requested\n"; 67 | break; 68 | } 69 | } 70 | std::cout << spacer << "leaving " << this_fiber::name() << '\n'; 71 | } 72 | 73 | //----------------------------------------------------------------------------------------- 74 | int main(void) 75 | { 76 | fiber sub_co({"sub0"}, &doit, 9, "\t"), sub_co1({"sub1"}, [](int arg, std::string_view spacer) 77 | { 78 | blah b; 79 | bool stop_requested{}; 80 | std::cout << spacer << "starting " << this_fiber::name() << ' ' << arg << '\n'; 81 | fiber sub_co2({.name="sub1/sub",.join=true}, &doit_with_stoprequest, "\t\t", std::ref(stop_requested)); 82 | for (int ii{}; ii < arg; this_fiber::yield()) 83 | std::cout << spacer << this_fiber::name() << ' ' << arg << ": " << ++ii << '\n'; 84 | stop_requested = true; 85 | std::cout << spacer << "leaving " << this_fiber::name() << ' ' << arg << '\n'; 86 | }, 10, "\t"); 87 | fibers::print(); 88 | for (int ii{}; fibers::has_fibers(); ++ii) 89 | { 90 | std::cout << "main: " << std::dec << ii << '\n'; 91 | this_fiber::yield(); 92 | if (ii == 1) 93 | fibers::print(); 94 | } 95 | std::cout << "Exiting from main\n"; 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /examples/fibertest20.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | //----------------------------------------------------------------------------------------- 42 | using namespace FIX8; 43 | using namespace std::chrono_literals; 44 | 45 | //----------------------------------------------------------------------------------------- 46 | std::thread::id id0; 47 | 48 | //----------------------------------------------------------------------------------------- 49 | void sub(int arg) 50 | { 51 | id0 = std::this_thread::get_id(); 52 | 53 | std::cout << "\tstarting sub " << arg << '\n'; 54 | for (int ii{}; ii < arg; this_fiber::yield()) 55 | { 56 | std::cout << "\tsub " << std::this_thread::get_id() << ' ' << arg << ": " << ++ii << '\n'; 57 | std::this_thread::sleep_for(500ms); 58 | } 59 | std::cout << "\tleaving sub " << arg << '\n'; 60 | } 61 | 62 | void sub1(int arg) 63 | { 64 | std::cout << "\tstarting sub1 " << arg << '\n'; 65 | for (int ii{}; ii < arg; this_fiber::yield()) 66 | { 67 | std::cout << "\tsub1 " << std::this_thread::get_id() << ' ' << arg << ": " << ++ii << '\n'; 68 | if (ii == 5) 69 | { 70 | std::cout << "\ntransferring from " << std::this_thread::get_id() << " to " << id0 << '\n'; 71 | this_fiber::move(id0); 72 | } 73 | std::this_thread::sleep_for(500ms); 74 | } 75 | std::cout << "\tleaving sub1 " << arg << '\n'; 76 | } 77 | 78 | void sub2(int arg) 79 | { 80 | std::cout << "\tstarting sub2 " << arg << '\n'; 81 | for (int ii{}; ii < arg; this_fiber::yield()) 82 | { 83 | std::cout << "\tsub2 " << std::this_thread::get_id() << ' ' << arg << ": " << ++ii << '\n'; 84 | std::this_thread::sleep_for(500ms); 85 | } 86 | std::cout << "\tleaving sub2 " << arg << '\n'; 87 | } 88 | 89 | //----------------------------------------------------------------------------------------- 90 | int main(void) 91 | { 92 | fiber f0({"first"},&sub, 15); 93 | std::thread t1([]() 94 | { 95 | fiber f1({"second"},&sub1, 12), f2({"third"},&sub2, 13); 96 | while (fibers::has_fibers()) 97 | { 98 | std::cout << "main1\n"; 99 | this_fiber::yield(); 100 | } 101 | std::cout << "Exiting from main1\n"; 102 | }); 103 | std::this_thread::sleep_for(100ms); 104 | while (fibers::has_fibers()) 105 | { 106 | #if defined FIX8_FIBER_MULTITHREADING_ 107 | std::cout << "main: total fibers/threads:" << fibers::const_get_all_cvars().count() << '/' << fibers::const_get_all_cvars().size() << '\n'; 108 | #else 109 | std::cout << "main\n"; 110 | #endif 111 | this_fiber::yield(); 112 | } 113 | std::cout << "Exiting from main\n"; 114 | t1.join(); 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /examples/fibertest21.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | //----------------------------------------------------------------------------------------- 43 | using namespace FIX8; 44 | using namespace std::chrono_literals; 45 | 46 | //----------------------------------------------------------------------------------------- 47 | void sub(int arg) 48 | { 49 | std::cout << "\tstarting " << this_fiber::name() << ' ' << arg << '\n'; 50 | for (int ii{}; ii < arg; this_fiber::yield()) 51 | { 52 | std::cout << '\t' << std::this_thread::get_id() << ' ' << this_fiber::name() << ' ' << arg << ": " << ++ii << '\n'; 53 | std::this_thread::sleep_for(1s); 54 | } 55 | std::cout << "\tleaving " << this_fiber::name() << ' ' << arg << '\n'; 56 | } 57 | 58 | //----------------------------------------------------------------------------------------- 59 | int main(int argc, char *argv[]) 60 | { 61 | int stcnt{20}; 62 | try 63 | { 64 | if (argc > 1) 65 | stcnt = std::stoi(argv[1]); 66 | } 67 | catch (const std::exception& e) 68 | { 69 | std::cerr << "exception: " << e.what() << std::endl; 70 | exit(1); 71 | } 72 | 73 | fiber f0({"first"}, &sub, 15), f1({"second"}, &sub, 12), f2({"third"}, &sub, 13); 74 | std::thread t1([stcnt]() 75 | { 76 | fiber ft1({"tfirst"}, &sub, stcnt); 77 | for (int ii{}; fibers::has_fibers(); ++ii) 78 | { 79 | std::cout << "main1 " << ii << '\n'; 80 | switch(ii) 81 | { 82 | case 4: 83 | case 9: 84 | case 11: 85 | case 21: 86 | fibers::print(); 87 | break; 88 | default: 89 | break; 90 | } 91 | std::cout << "main1\n"; 92 | this_fiber::yield(); 93 | } 94 | std::cout << "Exiting from main1\n"; 95 | }); 96 | std::this_thread::sleep_for(250ms); 97 | try 98 | { 99 | for (int ii{}; fibers::has_fibers(); ++ii) 100 | { 101 | std::cout << "main " << ii << '\n'; 102 | switch(ii) 103 | { 104 | case 5: 105 | std::cout << "transferring " << f0.get_id() << " from " << std::this_thread::get_id() << " to " << t1.get_id() << '\n'; 106 | f0.move(t1.get_id()); 107 | break; 108 | case 10: 109 | std::cout << "transferring " << f1.get_id() << " from " << std::this_thread::get_id() << " to " << t1.get_id() << '\n'; 110 | f1.move(t1.get_id()); 111 | break; 112 | case 4: 113 | case 9: 114 | case 11: 115 | fibers::print(); 116 | [[fallthrough]]; 117 | default: 118 | this_fiber::yield(); 119 | break; 120 | } 121 | } 122 | } 123 | catch (std::exception& e) 124 | { 125 | std::cerr << "exception " << e.what() << '\n'; 126 | std::cerr << "killed " << fibers::kill_all() << " fibers\n"; 127 | } 128 | std::cout << "Exiting from main\n"; 129 | t1.join(); 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /examples/fibertest22.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | 38 | //----------------------------------------------------------------------------------------- 39 | using namespace FIX8; 40 | 41 | //----------------------------------------------------------------------------------------- 42 | using uint128_t = __uint128_t; 43 | 44 | std::ostream& operator<<(std::ostream& os, const uint128_t val) noexcept 45 | { 46 | if (std::ostream::sentry sent(os); sent) 47 | { 48 | uint128_t tmp { val < 0 ? -val : val }; 49 | std::array buffer; 50 | auto blen { std::end(buffer) }; 51 | do 52 | { 53 | static constexpr const std::string_view vnum {"0123456789"}; 54 | *--blen = vnum[tmp % 10]; 55 | tmp /= 10; 56 | } 57 | while (tmp); 58 | if (val < 0) 59 | *--blen = '-'; 60 | if (auto len { std::end(buffer) - blen }; os.rdbuf()->sputn(blen, len) != len) 61 | os.setstate(std::ios_base::badbit); 62 | } 63 | return os; 64 | } 65 | 66 | //----------------------------------------------------------------------------------------- 67 | template 68 | class foo 69 | { 70 | std::queue _queue; 71 | fiber _produce, _consume; 72 | 73 | void producer(int numtogen) 74 | { 75 | std::cout << "\tproducer:entry (id:" << this_fiber::get_id() << ")\n"; 76 | std::mt19937_64 rnde {std::random_device{}()}; 77 | auto dist{std::uniform_int_distribution(1, std::numeric_limits().max())}; 78 | while (numtogen--) 79 | { 80 | int cnt{}; 81 | while(_queue.size() < 5) 82 | { 83 | _queue.push(dist(rnde)); 84 | ++cnt; 85 | } 86 | std::cout << "\tproduced: " << cnt << '\n'; 87 | _consume.resume(); // switch to consumer 88 | } 89 | _consume.schedule(); // consumer is next fiber to run 90 | std::cout << "\tproducer:exit\n"; 91 | } 92 | void consumer() 93 | { 94 | std::cout << "\tconsumer:entry (id:" << this_fiber::get_id() << ")\n"; 95 | while (_produce) 96 | { 97 | int cnt{}; 98 | while(!_queue.empty()) 99 | { 100 | std::cout << "\t\t" << ++cnt << ": " << _queue.front() << '\n'; 101 | _queue.pop(); 102 | } 103 | std::cout << "\tconsumed: " << cnt << '\n'; 104 | _produce.resume(); // switch to producer 105 | } 106 | std::cout << "\tconsumer:exit\n"; 107 | } 108 | 109 | public: 110 | foo(int num) : _produce(&foo::producer, this, num), _consume(&foo::consumer, this) 111 | { 112 | _produce.resume(); // switch to producer 113 | } 114 | }; 115 | 116 | //----------------------------------------------------------------------------------------- 117 | int main(int argc, char *argv[]) 118 | { 119 | std::cout << "main:entry\n"; 120 | try 121 | { 122 | foo(argc > 1 ? std::stoi(argv[1]) : 10); 123 | } 124 | catch (const std::exception& e) 125 | { 126 | std::cerr << "exception: " << e.what() << std::endl; 127 | } 128 | std::cout << "main:exit\n"; 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /examples/fibertest.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | //----------------------------------------------------------------------------------------- 41 | using namespace FIX8; 42 | using namespace std::literals; 43 | 44 | //----------------------------------------------------------------------------------------- 45 | void doit(int arg) 46 | { 47 | std::cout << this_fiber::name(("sub"s + std::to_string(arg)).c_str()); 48 | std::cout << "\tstarting " << arg << '\n'; 49 | for (int ii{}; ii < arg; ) 50 | { 51 | std::cout << '\t' << this_fiber::name() << ' ' << arg << ": " << ++ii << '\n'; 52 | this_fiber::yield(); 53 | } 54 | std::cout << "\tleaving " << arg << '\n'; 55 | fibers::print(); 56 | } 57 | 58 | struct foo 59 | { 60 | void sub(int arg) 61 | { 62 | doit(arg); 63 | } 64 | void sub1(int arg, const char *str) 65 | { 66 | std::cout << str << '\n'; 67 | doit(arg); 68 | } 69 | void sub3(int arg, const char *str) 70 | { 71 | auto st { "sub"s + std::to_string(arg) }; 72 | this_fiber::name(st.c_str()); 73 | std::cout << "\tsub2 starting " << arg << '\n'; 74 | for (int ii{}; ii < arg; ) 75 | { 76 | std::cout << '\t' << this_fiber::name() << ' ' << arg << ": " << ++ii << '\n'; 77 | //this_fiber::sleep_until(std::chrono::steady_clock::now() + 500ms); 78 | this_fiber::sleep_for(100ms); 79 | } 80 | std::cout << "\tsub2 leaving " << arg << '\n'; 81 | } 82 | void sub2() 83 | { 84 | doit(4); 85 | } 86 | }; 87 | 88 | //----------------------------------------------------------------------------------------- 89 | int main(void) 90 | { 91 | foo bar; 92 | fiber sub_co({.stacksz=2048}, &doit, 3), 93 | sub_co1({.stacksz=16384}, &foo::sub2, &bar), 94 | sub_co2({.stacksz=32768}, &foo::sub, &bar, 5), 95 | sub_co3({.stacksz=8192}, &foo::sub1, &bar, 8., "hello"), 96 | sub_co4(std::bind(&foo::sub3, &bar, 12, "there")); 97 | fiber sub_lam({.name="sub lambda",.stack=std::make_unique()}, [](int arg) 98 | //char stack[4096]; 99 | //fiber sub_lam({.name="sub lambda",.stacksz=sizeof(stack),.stack=std::make_unique(stack)}, [](int arg) 100 | { 101 | std::cout << "\tlambda starting " << arg << '\n'; 102 | for (int ii{}; ii < arg; ) 103 | { 104 | std::cout << '\t' << this_fiber::name() << ' ' << arg << ": " << ++ii << '\n'; 105 | this_fiber::yield(); 106 | } 107 | std::cout << "\tlambda leaving " << arg << '\n'; 108 | }, 15); 109 | for (int ii{}; fibers::has_fibers(); ++ii) 110 | { 111 | if (ii == 0) 112 | { 113 | fibers::print(std::cout); 114 | sub_co3.resume(); 115 | fibers::print(std::cout); 116 | } 117 | this_fiber::yield(); 118 | std::cout << "main: " << std::dec << ii << '\n'; 119 | //fibers::print(std::cout); 120 | } 121 | std::cout << "Exiting from main\n" 122 | << fibers::size_finished() << " fibers finished\n" 123 | << "fiber: " << sizeof(fiber) << '\n' 124 | << "fiber::cvars: " << sizeof(fiber::cvars) << '\n' 125 | << "fiber::all_cvars: " << sizeof(fiber::all_cvars) << '\n' 126 | << "fiber_id: " << sizeof(fiber_id) << '\n' 127 | << "fiber_base: " << sizeof(fiber_base) << '\n' 128 | << "fiber_params: " << sizeof(fiber_params) << std::endl; 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /examples/fibertest26.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | 44 | //----------------------------------------------------------------------------------------- 45 | using namespace FIX8; 46 | 47 | //----------------------------------------------------------------------------------------- 48 | class Reader : public fiber 49 | { 50 | static constexpr std::string_view b64set{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; 51 | static const int _max_msg_len{256}, _trl_len{10}; 52 | std::exception_ptr _eptr; 53 | std::mt19937 _rnd_engine{ std::random_device{}() }; // uses /dev/urandom 54 | std::uniform_int_distribution _chardist{0, b64set.size() - 1}, _hdrdist{12, 16}, _mlendist{80, 102}; 55 | 56 | // simulate a read that doesn't guarentee to read all that was requested 57 | int read_some(char *where, int cnt) 58 | { 59 | // 50% will not read all requested (will resume and try again) 60 | if (std::bernoulli_distribution()(_rnd_engine)) 61 | cnt = std::uniform_int_distribution{0, cnt - 1}(_rnd_engine); 62 | if (cnt && std::bernoulli_distribution(.002)(_rnd_engine)) // 0.2% chance of a read exception 63 | throw std::runtime_error("exception reading " + std::to_string(cnt) + " bytes"); 64 | for (const auto ptr{ where + cnt }; where < ptr; ++where) 65 | *where = b64set[_chardist(_rnd_engine)]; 66 | return cnt; 67 | } 68 | 69 | // override to process message 70 | virtual void process (std::string_view msg) const 71 | { 72 | std::cout << std::setw(3) << msg.size() << ' ' << msg << '\n'; 73 | } 74 | 75 | // non-blocking resumable reader 76 | // message: [header:12-16][' '][body:80-102][' '][trailer:10] 77 | void read_nb(int rdcnt) 78 | { 79 | int mread{}; 80 | try 81 | { 82 | for (std::array buff; mread < rdcnt; ++mread) 83 | { 84 | auto hlen{ _hdrdist(_rnd_engine) }, mlen{ _mlendist(_rnd_engine) }; // variable header and body length 85 | 86 | // read header(var length), yield if nothing or insufficent to read 87 | for (int sofar{}; (sofar += read_some(buff.data() + sofar, hlen - sofar)) < hlen;) 88 | this_fiber::yield(); 89 | buff[hlen++] = ' '; // separator 90 | 91 | // read body(var length), yield if nothing or insufficent to read 92 | for (int sofar{}; (sofar += read_some(buff.data() + hlen + sofar, mlen - sofar)) < mlen;) 93 | this_fiber::yield(); 94 | buff[hlen + mlen++] = ' '; // separator 95 | 96 | // read trailer(fixed length), yield if nothing or insufficent to read 97 | for (int sofar{}; (sofar += read_some(buff.data() + hlen + sofar + mlen, _trl_len - sofar)) < _trl_len;) 98 | this_fiber::yield(); 99 | 100 | process(std::string_view(buff.data(), hlen + mlen + _trl_len)); 101 | } 102 | } 103 | catch (...) 104 | { 105 | _eptr = std::current_exception(); 106 | } 107 | std::cout << "read_nb: " << mread << " messages read\n"; 108 | } 109 | 110 | public: 111 | Reader(int rdcnt) : fiber(&Reader::read_nb, this, rdcnt) {} 112 | std::exception_ptr get_exception() const { return _eptr; } 113 | }; 114 | 115 | //----------------------------------------------------------------------------------------- 116 | int main(int argc, char *argv[]) 117 | { 118 | try 119 | { 120 | Reader reader(argc > 1 ? std::stoi(argv[1]) : 100); 121 | while (reader) 122 | { 123 | reader.resume(); 124 | try 125 | { 126 | if (reader.get_exception()) 127 | std::rethrow_exception(reader.get_exception()); 128 | } 129 | catch (const std::exception& e) 130 | { 131 | std::cerr << "Reader: " << e.what() << '\n'; 132 | } 133 | catch (...) 134 | { 135 | std::cerr << "Reader: unknown exception\n"; 136 | } 137 | } 138 | std::cout << reader.get_ctxswtchs() << " yields\n"; 139 | } 140 | catch (const std::exception& e) 141 | { 142 | std::cerr << "main: " << e.what() << '\n'; 143 | } 144 | return 0; 145 | } 146 | 147 | -------------------------------------------------------------------------------- /examples/montest1.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | // 34 | // Monitor test using: 35 | // 36 | // Termbox2 37 | // MIT License 38 | // Copyright (c) 2010-2020 nsf 39 | // 2015-2022 Adam Saponara 40 | //----------------------------------------------------------------------------------------- 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | //----------------------------------------------------------------------------------------- 51 | using namespace FIX8; 52 | using namespace std::literals; 53 | 54 | //----------------------------------------------------------------------------------------- 55 | class foo : public fiber_monitor 56 | { 57 | std::mt19937_64 _rnde {std::random_device{}()}; 58 | std::uniform_int_distribution _dist{1, 224}; 59 | int _sleepval, _val; 60 | window_frame _xyxy; 61 | 62 | public: 63 | foo(int sleepval, std::chrono::milliseconds timeout, sort_mode mode) 64 | : fiber_monitor(timeout, mode), _sleepval(sleepval), _xyxy({{}, {get_dimensions().first, get_dimensions().second}}) {} 65 | 66 | void func(int arg) 67 | { 68 | this_fiber::name("sub"s + std::to_string(arg)); 69 | auto num { 2 * ++arg }; 70 | while (num--) 71 | { 72 | double varr[arg * _dist(_rnde)]; // consume variable amt of stack 73 | _val = varr[_dist(_rnde)]; // force optimizer hands off 74 | 75 | update(_xyxy); 76 | if (!*this) 77 | this_fiber::resume_main(); 78 | std::this_thread::sleep_for(std::chrono::milliseconds(_sleepval)); 79 | this_fiber::yield(); 80 | } 81 | } 82 | }; 83 | 84 | //----------------------------------------------------------------------------------------- 85 | int main(int argc, char *argv[]) 86 | { 87 | constexpr int sleep_default{50}, interval_default{100}; 88 | int interval{interval_default}, fcnt{-1}, sleepval{sleep_default}; 89 | bool lorder{true}, skip{true}; 90 | fiber_monitor::sort_mode sm{ fiber_monitor::sort_mode::by_ms }; 91 | 92 | static constexpr auto optstr { "f:i:s:om:rkh" }; 93 | static constexpr const std::array long_options 94 | { 95 | option{ "help", no_argument, 0, 'h' }, option{ "retain", no_argument, 0, 'r' }, 96 | option{ "order", no_argument, 0, 'o' }, option{ "noskip", no_argument, 0, 'k' }, 97 | option{ "sleep", required_argument, 0, 's' }, option{ "interval", required_argument, 0, 'i' }, 98 | option{ "fibers", required_argument, 0, 'f' }, option{ "mode", required_argument, 0, 'm' }, 99 | option{} 100 | }; 101 | 102 | for (int val; (val = getopt_long (argc, argv, optstr, long_options.data(), 0)) != -1; ) 103 | { 104 | try 105 | { 106 | switch (val) 107 | { 108 | case 'm': 109 | if (auto ism{ std::stoul(optarg) - 1UL }; ism < static_cast(fiber_monitor::sort_mode::count)) 110 | sm = fiber_monitor::sort_mode(ism); 111 | break; 112 | case 'f': fcnt = std::stoi(optarg); break; 113 | case 's': sleepval = std::stoi(optarg); break; 114 | case 'r': fibers::set_flag(global_fiber_flags::retain); break; 115 | case 'k': skip ^= true; break; 116 | case 'o': lorder ^= true; break; 117 | case 'i': interval = std::stoi(optarg); break; 118 | case '?': 119 | case ':': 120 | case 'h': 121 | std::cout << "Usage: " << argv[0] << " -[" << optstr << R"(] 122 | -i,--interval interval msecs (default )" << interval << R"() 123 | -f,--fibers fiber count (default )" << (fiber_monitor::get_terminal_dimensions().second - 4) << R"() 124 | -s,--sleep sleep msecs (default )" << sleepval << R"() 125 | -m,--mode sort mode )" << fiber_monitor::sort_help() << "(default " << (static_cast(sm) + 1) << R"() 126 | -o,--order no launch order 127 | -k,--noskip no skip main 128 | -r,--retain retain finished fibers (default false) 129 | -h,--help) 130 | e.g. 131 | ./montest1 --mode 8 --retain --interval 0 --sleep 25)" << std::endl; 132 | exit(1); 133 | default: 134 | break; 135 | } 136 | } 137 | catch (const std::exception& e) 138 | { 139 | std::cerr << "exception: " << e.what(); 140 | if (optarg) 141 | std::cerr << " (" << static_cast(val) << ':' << optarg << ')'; 142 | std::cerr << std::endl; 143 | exit(1); 144 | } 145 | } 146 | 147 | if (skip) 148 | fibers::set_flag(global_fiber_flags::skipmain); 149 | foo bar(sleepval, std::chrono::milliseconds(interval), sm); 150 | if (fcnt == -1) 151 | fcnt = bar.get_dimensions().second - 4; 152 | std::vector fbs; 153 | for (int ii{}; ii < fcnt; ++ii) 154 | fbs.emplace_back(make_fiber({.launch_order=lorder ? ii : 99,.stacksz=(fcnt * 4096lu) & ~0xff}, &foo::func, &bar, ii)); 155 | 156 | fibers::wait_all([&bar]() 157 | { 158 | if (!bar) 159 | fibers::kill_all(); 160 | return !bar; 161 | }); 162 | bar.update(); 163 | std::this_thread::sleep_for(2s); 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------------------- 2 | # fiber (header only) 3 | # Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | # by David L. Dight 5 | # see https://github.com/fix8mt/fiber 6 | # 7 | # Lightweight header-only stackful per-thread fiber 8 | # with built-in roundrobin scheduler x86_64 / linux only 9 | # 10 | # Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | # 12 | # Permission is hereby granted, free of charge, to any person or organization 13 | # obtaining a copy of the software and accompanying documentation covered by 14 | # this license (the "Software") to use, reproduce, display, distribute, 15 | # execute, and transmit the Software, and to prepare derivative works of the 16 | # Software, and to permit third-parties to whom the Software is furnished to 17 | # do so, all subject to the following: 18 | # 19 | # The copyright notices in the Software and this entire statement, including 20 | # the above license grant, this restriction and the following disclaimer, 21 | # must be included in all copies of the Software, in whole or in part, and 22 | # all derivative works of the Software, unless such copies or derivative 23 | # works are solely in the form of machine-executable object code generated by 24 | # a source language processor. 25 | # 26 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | # FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | # SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | # FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | # DEALINGS IN THE SOFTWARE. 33 | # 34 | # ---------------------------------------------------------------------------------------- 35 | # cmake config 36 | # clang 37 | # CXX="clang++" CC="clang" cmake .. 38 | # gcc 39 | # CXX="g++" CC="gcc" cmake .. 40 | # 41 | # min cmake version 3.20 (Mar 24, 2021) 42 | # ---------------------------------------------------------------------------------------- 43 | cmake_minimum_required (VERSION 3.20) 44 | project (fiber 45 | LANGUAGES CXX 46 | HOMEPAGE_URL https://github.com/fix8mt/fiber 47 | DESCRIPTION "Lightweight header-only stackful per-thread C++20 fiber" 48 | VERSION 2.3 49 | ) 50 | 51 | set(THREADS_PREFER_PTHREAD_FLAG ON) 52 | find_package(Threads REQUIRED) 53 | link_libraries(Threads::Threads) 54 | include_directories(${CMAKE_SOURCE_DIR}/include) 55 | 56 | if(CMAKE_BUILD_TYPE STREQUAL "") 57 | set(CMAKE_BUILD_TYPE "RELEASE") 58 | endif() 59 | if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") 60 | set(CMAKE_CXX_FLAGS_DEBUG "-O0 -D_DEBUG -ggdb") 61 | set(CMAKE_C_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) 62 | else(CMAKE_BUILD_TYPE STREQUAL "RELEASE") 63 | set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -ggdb") 64 | set(CMAKE_C_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) 65 | endif() 66 | message("-- cxx flags ${CMAKE_BUILD_TYPE}: \"${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}\"") 67 | 68 | set(exdir ${CMAKE_SOURCE_DIR}/examples) 69 | file(GLOB esrc CONFIGURE_DEPENDS "${exdir}/fiber*.cpp") 70 | foreach(x ${esrc}) 71 | cmake_path(GET x STEM LAST_ONLY target) 72 | add_executable(${target} ${x}) 73 | set_target_properties(${target} PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED true) 74 | get_target_property(v1 ${target} CXX_STANDARD) 75 | cmake_path(GET x FILENAME fname) 76 | message("-- adding ${fname} cxx std: c++${v1}") 77 | endforeach() 78 | 79 | # to disable building monitor tests: 80 | # cmake -DBUILD_MONITOR=false .. 81 | option(BUILD_MONITOR "enable building monitor tests" true) 82 | message("-- Build monitor tests: ${BUILD_MONITOR}") 83 | if(BUILD_MONITOR) 84 | message(STATUS "Populating termbox2...") 85 | include(ExternalProject) 86 | ExternalProject_Add(termbox2 87 | GIT_REPOSITORY https://github.com/termbox/termbox2.git 88 | GIT_PROGRESS true 89 | GIT_SHALLOW ON 90 | GIT_TAG master 91 | UPDATE_DISCONNECTED true 92 | CONFIGURE_COMMAND "" 93 | BUILD_IN_SOURCE true 94 | BUILD_COMMAND sh -c "make -j4" 95 | INSTALL_COMMAND "" 96 | ) 97 | set(termbox2 ${CMAKE_CURRENT_BINARY_DIR}/termbox2-prefix/src/termbox2) 98 | 99 | message(STATUS "Populating GMP...") 100 | ExternalProject_Add(gmp 101 | GIT_REPOSITORY https://github.com/alisw/GMP.git 102 | GIT_PROGRESS true 103 | GIT_SHALLOW ON 104 | GIT_TAG master 105 | UPDATE_DISCONNECTED true 106 | CONFIGURE_COMMAND sh -c "./configure --enable-cxx -enable-alloca=alloca" 107 | BUILD_IN_SOURCE true 108 | BUILD_COMMAND sh -c "make -j4" 109 | INSTALL_COMMAND "" 110 | TEST_COMMAND sh -c "make -j4 check" 111 | ) 112 | set(gmp ${CMAKE_CURRENT_BINARY_DIR}/gmp-prefix/src/gmp) 113 | 114 | file(GLOB msrc CONFIGURE_DEPENDS "${exdir}/montest*.cpp") 115 | foreach(x ${msrc}) 116 | cmake_path(GET x STEM LAST_ONLY target) 117 | add_executable(${target} ${x}) 118 | set_target_properties(${target} PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED true CXX_EXTENSIONS off) 119 | add_dependencies(${target} termbox2 gmp) 120 | target_include_directories(${target} PRIVATE ${termbox2} ${gmp}) 121 | target_link_directories(${target} PRIVATE ${termbox2} ${gmp}/.libs) 122 | target_link_libraries(${target} PRIVATE termbox2.a gmpxx.a gmp.a) 123 | get_target_property(v1 ${target} CXX_STANDARD) 124 | cmake_path(GET x FILENAME fname) 125 | message("-- adding ${fname} cxx std: c++${v1}") 126 | endforeach() 127 | endif() 128 | 129 | # to disable building unit tests: 130 | # cmake -DBUILD_TESTS=false .. 131 | option(BUILD_TESTS "enable building unit tests" true) 132 | message("-- Build unit tests: ${BUILD_TESTS}") 133 | if(BUILD_TESTS) 134 | message(STATUS "Populating Catch2...") 135 | include(FetchContent) 136 | enable_testing() 137 | FetchContent_Declare(Catch2 138 | GIT_REPOSITORY https://github.com/catchorg/Catch2.git 139 | GIT_SHALLOW ON 140 | GIT_TAG devel 141 | ) 142 | FetchContent_MakeAvailable(Catch2) 143 | list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) 144 | include(Catch) 145 | 146 | set(testdir ${CMAKE_SOURCE_DIR}/test) 147 | add_executable(utest01 ${testdir}/utest01.cpp) 148 | target_link_libraries(utest01 PRIVATE Catch2::Catch2WithMain) 149 | catch_discover_tests(utest01) 150 | add_executable(utest02 ${testdir}/utest02.cpp) 151 | set_target_properties(utest01 utest02 PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED true) 152 | target_link_libraries(utest02 PRIVATE Catch2::Catch2) 153 | catch_discover_tests(utest02) 154 | endif() 155 | 156 | # to dump all non-empty cmake variables 157 | # cmake -DCMAKE_DUMP_VARS=true .. 158 | option(CMAKE_DUMP_VARS "dump all cmake vars" false) 159 | if(CMAKE_DUMP_VARS) 160 | get_cmake_property(varname VARIABLES) 161 | foreach (var ${varname}) 162 | if(NOT ${var} STREQUAL "") 163 | message(STATUS "${var}=${${var}}") 164 | endif() 165 | endforeach() 166 | endif() 167 | -------------------------------------------------------------------------------- /examples/fibertest32.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #ifdef _GNU_SOURCE 38 | #include 39 | #endif 40 | #include 41 | 42 | //----------------------------------------------------------------------------------------- 43 | using namespace FIX8; 44 | using namespace std::literals; 45 | 46 | //----------------------------------------------------------------------------------------- 47 | class foo 48 | { 49 | bool tests[9]{}; 50 | void set(int n) { tests[n - 1] = true; } 51 | 52 | static constexpr const std::array long_options 53 | { 54 | option{ "scenarioA", no_argument, 0, 'A' }, 55 | option{ "scenarioB", no_argument, 0, 'B' }, 56 | option{ "scenarioC", no_argument, 0, 'C' }, 57 | option{ "scenarioD", no_argument, 0, 'D' }, 58 | option{ "scenarioE", no_argument, 0, 'E' }, 59 | option{ "test1", no_argument, 0, '1' }, 60 | option{ "test2", no_argument, 0, '2' }, 61 | option{ "test3", no_argument, 0, '3' }, 62 | option{ "test4", no_argument, 0, '4' }, 63 | option{ "test5", no_argument, 0, '5' }, 64 | option{ "test6", no_argument, 0, '6' }, 65 | option{ "test7", no_argument, 0, '7' }, 66 | option{ "test8", no_argument, 0, '8' }, 67 | option{ "test9", no_argument, 0, '9' }, 68 | option{ "help", no_argument, 0, 'h' }, 69 | option{} 70 | }; 71 | 72 | static const char *get_optstr() 73 | { 74 | static const std::string _optstr([]() 75 | { 76 | std::ostringstream ostr; 77 | for (const auto& pp : long_options) 78 | ostr << static_cast(pp.val); 79 | return ostr.str(); 80 | }()); 81 | return _optstr.c_str(); 82 | } 83 | static std::string_view get_helpstr() 84 | { 85 | static const std::string _helpstr([]() 86 | { 87 | std::ostringstream ostr; 88 | for (const auto& pp : long_options) 89 | ostr << " -" << static_cast(pp.val) << ",--" << pp.name << '\n'; 90 | return ostr.str(); 91 | }()); 92 | return _helpstr; 93 | } 94 | 95 | public: 96 | foo(int argc, char *argv[]) 97 | { 98 | for (int val; (val = getopt_long (argc, argv, get_optstr(), long_options.data(), 0)) != -1; ) 99 | { 100 | if (std::isdigit(val)) 101 | set(val - '0'); 102 | else switch(val) 103 | { 104 | case 'A': 105 | set(1); set(2); set(5); 106 | break; 107 | case 'B': 108 | set(1); set(2); set(6); 109 | break; 110 | case 'C': 111 | set(1); set(2); set(7); 112 | break; 113 | case 'E': 114 | set(3); 115 | [[fallthrough]]; 116 | case 'D': 117 | set(1); set(2); set(4); set(5); 118 | break; 119 | case 'h': 120 | std::cout << "Usage: " << argv[0] << " -[" << get_optstr() << "]\n" << get_helpstr(); 121 | [[fallthrough]]; 122 | case '?': 123 | case ':': 124 | exit(1); 125 | default: 126 | break; 127 | } 128 | } 129 | } 130 | 131 | bool test(int n) const { return tests[n - 1]; } 132 | 133 | void doit() 134 | { 135 | std::cout << "\tstarting " << this_fiber::name() << '\n'; 136 | this_fiber::yield(); 137 | for(int ii{}; ii < 10; std::this_thread::sleep_for(100ms)) 138 | { 139 | if (test(9) && ii > 4) 140 | throw 64; 141 | std::cout << '\t' << this_fiber::name() << ": " << ++ii << '\n'; 142 | } 143 | std::cout << "\tleaving " << this_fiber::name() << '\n'; 144 | if (test(3)) 145 | throw 42; 146 | } 147 | 148 | friend std::ostream& operator<<(std::ostream& os, const foo& what) 149 | { 150 | for (int ii{}; auto pp : what.tests) 151 | std::cout << ++ii << ':' << std::boolalpha << pp << ' '; 152 | return os; 153 | } 154 | }; 155 | 156 | //----------------------------------------------------------------------------------------- 157 | int main(int argc, char *argv[]) 158 | { 159 | foo bar(argc, argv); 160 | std::cout << bar << std::endl; 161 | 162 | if (bar.test(1)) 163 | fibers::set_flag(global_fiber_flags::excepthandling); 164 | if (bar.test(2)) 165 | fibers::set_flag(global_fiber_flags::termthrow); 166 | if (bar.test(5)) 167 | fiber{{"f1"}, &foo::doit, &bar}; 168 | if (bar.test(6)) 169 | fiber({"f1"}, &foo::doit, &bar).detach(); 170 | fiber_ptr fb; 171 | if (bar.test(7)) 172 | fb = make_fiber({"f1"}, &foo::doit, &bar); 173 | if (bar.test(4)) 174 | fibers::wait_all(); 175 | try 176 | { 177 | if (fibers::get_exception_ptr()) 178 | std::rethrow_exception(fibers::get_exception_ptr()); 179 | } 180 | catch(const std::exception& e) 181 | { 182 | std::cerr << "rethrown: " << e.what() << '\n'; 183 | } 184 | catch(const int& e) 185 | { 186 | std::cerr << "rethrown: " << e << '\n'; 187 | } 188 | catch(...) 189 | { 190 | std::cerr << "unknown exception\n"; 191 | } 192 | 193 | if (bar.test(8)) try 194 | { 195 | fiber fb({"f2"}, &foo::doit, &bar); 196 | this_fiber::yield(); 197 | fb.join(); 198 | this_fiber::yield(); 199 | fb.join(); 200 | } 201 | catch(const std::exception& e) 202 | { 203 | std::cerr << "exception: " << e.what() << '\n'; 204 | } 205 | catch(...) 206 | { 207 | std::cerr << "unknown exception\n"; 208 | } 209 | std::cout << "exiting main\n"; 210 | return 0; 211 | } 212 | -------------------------------------------------------------------------------- /examples/montest2.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | // 34 | // Monitor test using: 35 | // 36 | // GNU multiple precision arithmetic library, version 6.2.1. 37 | // Copyright 1991, 1993-2016, 2018-2020 Free Software Foundation, Inc. 38 | // Termbox2 39 | // MIT License 40 | // Copyright (c) 2010-2020 nsf 41 | // 2015-2022 Adam Saponara 42 | //---------------------------------------------------------------------------------------- 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | 54 | //----------------------------------------------------------------------------------------- 55 | using namespace FIX8; 56 | using namespace std::literals; 57 | 58 | //----------------------------------------------------------------------------------------- 59 | class foo : public fiber_monitor 60 | { 61 | std::mt19937_64 _rnde {std::random_device{}()}; 62 | std::uniform_int_distribution _exp; 63 | bool _todisk, _percent; 64 | 65 | public: 66 | foo(int interval, long maxexp, bool todisk, bool percent) : 67 | fiber_monitor(std::chrono::milliseconds(interval), fiber_monitor::sort_mode::by_ms), 68 | _exp{1, maxexp}, _todisk(todisk), _percent(percent) {} 69 | 70 | void func(int arg) 71 | { 72 | std::unique_ptr dskfile { _todisk ? std::make_unique( 73 | std::string { "worker"s + std::to_string(arg - 10) + ".out" }.c_str(), std::ios::trunc) : nullptr }; 74 | mpz_class result; 75 | for (int ii{}; ii < arg; ++ii) 76 | { 77 | auto expv { _exp(_rnde) }; // obtain our exponent 78 | std::ostringstream expstr; 79 | if (_percent) 80 | expstr << ii << '/' << arg << " (" << (ii * 100 / arg) << "%)"; 81 | else 82 | expstr << "2^" << expv; 83 | this_fiber::name(expstr.str().c_str()); 84 | update(); 85 | mpz_class pr; 86 | mpz_ui_pow_ui(pr.get_mpz_t(), 2, expv); // raise 2^expv 87 | is_quit() ? this_fiber::resume_main() : this_fiber::yield(); // user pressed 'x'?, yield mid processing 88 | result += pr; // add to total 89 | if (dskfile) 90 | *dskfile << expstr.str() << " = " << pr << '\n'; 91 | update(); 92 | is_quit() ? this_fiber::resume_main() : this_fiber::yield(); // user pressed 'x'?. or yield 93 | } 94 | if (dskfile) 95 | *dskfile << "result = " << result << '\n'; 96 | this_fiber::name("finished"); 97 | } 98 | bool user_key_process(char ch) noexcept override 99 | { 100 | return ch == 'q'; 101 | } 102 | }; 103 | 104 | //----------------------------------------------------------------------------------------- 105 | int main(int argc, char *argv[]) 106 | { 107 | constexpr long maxexp_default{3999999999L}; 108 | constexpr int fcnt_default{20}; 109 | long maxexp{maxexp_default}; 110 | int interval{}, fcnt{fcnt_default}; 111 | bool todisk{}, threaded{}, retain{true}, percent{}; 112 | 113 | static constexpr const char *optstr{"f:i:hm:wrp"}; 114 | static constexpr const std::array long_options 115 | { 116 | option{ "help", no_argument, nullptr, 'h' }, 117 | option{ "write", no_argument, nullptr, 'w' }, 118 | option{ "percent", no_argument, nullptr, 'p' }, 119 | option{ "retain", no_argument, nullptr, 'r' }, 120 | option{ "fibers", required_argument, nullptr, 'f' }, 121 | option{ "maxexp", required_argument, nullptr, 'm' }, 122 | option{ "interval", required_argument, nullptr, 'i' }, 123 | option{} 124 | }; 125 | 126 | for (int val; (val = getopt_long (argc, argv, optstr, long_options.data(), 0)) != -1; ) 127 | { 128 | try 129 | { 130 | switch (val) 131 | { 132 | case ':': case '?': 133 | std::cout << '\n'; 134 | [[fallthrough]]; 135 | case 'h': 136 | std::cout << "Usage: " << argv[0] << " [-" << optstr << "]" << R"( 137 | -w write results to disk files (default )" << std::boolalpha << todisk << R"() 138 | -i interval msecs (default )" << interval << R"() 139 | -r retain finished fibers (default )" << std::boolalpha << retain << R"() 140 | -p show percent remaining work (default )" << std::boolalpha << percent << R"() 141 | -f fiber count (default )" << fcnt_default << R"() 142 | -m max exponent (default )" << maxexp_default << R"() 143 | -h help 144 | e.g. 145 | ./montest1 --mode 8 --retain --interval 0 --sleep 25)" << std::endl; 146 | return 0; 147 | case 'w': todisk ^= true; break; 148 | case 'p': percent ^= true; break; 149 | case 'r': retain ^= true; break; 150 | case 'm': maxexp = std::stol(optarg); break; 151 | case 'f': fcnt = std::stoi(optarg); break; 152 | case 'i': interval = std::stoi(optarg); break; 153 | default: break; 154 | } 155 | } 156 | catch (const std::exception& e) 157 | { 158 | std::cerr << "exception: " << e.what(); 159 | if (optarg) 160 | std::cerr << " (" << static_cast(val) << ':' << optarg << ')'; 161 | std::cerr << std::endl; 162 | return 1; 163 | } 164 | } 165 | 166 | if (todisk && maxexp == maxexp_default) 167 | maxexp = 10000000L; 168 | if (retain) 169 | fibers::set_flag(global_fiber_flags::retain); 170 | 171 | foo bar(interval, maxexp, todisk, percent); 172 | std::vector fbs; 173 | for (int ii{}; ii < fcnt; ++ii) 174 | fbs.emplace_back(make_fiber({.launch_order=ii}, &foo::func, &bar, ii + 10)); 175 | 176 | fibers::wait_all([&bar]() 177 | { 178 | if (!bar) 179 | fibers::kill_all(); 180 | return !bar; 181 | }); 182 | bar.update(); 183 | std::this_thread::sleep_for(2s); 184 | return 0; 185 | } 186 | -------------------------------------------------------------------------------- /test/utest01.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //----------------------------------------------------------------------------------------- 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | //----------------------------------------------------------------------------------------- 48 | using namespace FIX8; 49 | using namespace std::literals; 50 | 51 | //----------------------------------------------------------------------------------------- 52 | int future_sub(int arg) 53 | { 54 | return arg * 100; 55 | } 56 | 57 | TEST_CASE("Future - fiber async wth std::future", "[fiber][async][future]") 58 | { 59 | std::future myfuture { async(&future_sub, 10) }; 60 | REQUIRE(myfuture.get() == 1000); 61 | } 62 | 63 | //----------------------------------------------------------------------------------------- 64 | template 65 | void fibonacci (T& val) 66 | { 67 | val = 0; 68 | for(T next{1}; !fibers::terminating(); val = std::exchange(next, val + next)) 69 | this_fiber::yield(); 70 | } 71 | 72 | TEST_CASE("Fibonacci - calculating first 18 fibonacci numbers", "[fiber]") 73 | { 74 | uint64_t val; 75 | fiber(fibonacci, std::ref(val)).detach(); 76 | for (int num{18}; num--; this_fiber::yield()) 77 | ; 78 | REQUIRE(val == 1597); 79 | } 80 | 81 | //----------------------------------------------------------------------------------------- 82 | TEST_CASE("Promise - fiber with std::promise", "[fiber][promise][future]") 83 | { 84 | std::promise mypromise; 85 | auto myfuture { mypromise.get_future() }; 86 | fiber sub_co([](int arg, std::promise& pr) 87 | { 88 | for (int ii{}; ii++ < arg; this_fiber::yield()) 89 | ; 90 | pr.set_value(arg * 100); 91 | }, 10, std::ref(mypromise)); 92 | 93 | while(sub_co) 94 | this_fiber::yield(); 95 | REQUIRE(myfuture.get() == 1000); 96 | } 97 | 98 | //----------------------------------------------------------------------------------------- 99 | TEST_CASE("Task - with std::future and std::packaged_task", "[fiber][task]") 100 | { 101 | std::packaged_task task([](int arg) 102 | { 103 | for (int ii{}; ii++ < arg; this_fiber::yield()) 104 | ; 105 | return arg * 100; 106 | }); 107 | auto myfuture { task.get_future() }; 108 | fiber myfiber(std::move(task), 10); 109 | while(myfiber) 110 | this_fiber::yield(); 111 | REQUIRE(myfuture.get() == 1000); 112 | } 113 | 114 | //----------------------------------------------------------------------------------------- 115 | TEST_CASE("Wordset - fiber reconstructing sentence", "[fiber][launch_all_with_params_n]") 116 | { 117 | static constexpr const std::array wordsets 118 | { 119 | std::array { R"("I )", "all ", "said ", "It’s ", "I’m ", "" }, 120 | std::array { "for ", "who ", "me. ", "them ", "myself.\"\n", "" }, 121 | std::array { "am ", "of ", "no ", "because ", "doing ", " - Albert ", }, 122 | std::array { "thankful ", "those ", "to ", "of ", "it ", "Einstein\n" }, 123 | }; 124 | static const std::string_view cmpstr { R"("I am thankful for all of those who said no to me. It’s because of them I’m doing it myself." 125 | - Albert Einstein 126 | )"}; 127 | 128 | std::ostringstream ostr; 129 | const auto func([&ostr](const auto& words) 130 | { 131 | for (auto pp : words) 132 | { 133 | ostr << pp; 134 | this_fiber::yield(); 135 | } 136 | }); 137 | 138 | std::list sts; 139 | fibers::set_flag(global_fiber_flags::skipmain); 140 | 141 | launch_all_with_params_n 142 | ( 143 | sts, 144 | fiber_params{.launch_order=0}, std::bind(func, wordsets[0]), 145 | fiber_params{.launch_order=3}, std::bind(func, wordsets[1]), 146 | fiber_params{.launch_order=1}, std::bind(func, wordsets[2]), 147 | fiber_params{.launch_order=2}, std::bind(func, wordsets[3]) 148 | ); 149 | 150 | REQUIRE(ostr.str() == cmpstr); 151 | } 152 | 153 | //----------------------------------------------------------------------------------------- 154 | void resume_sub(int arg, int& res) 155 | { 156 | for (int ii{}; ii++ < arg; this_fiber::resume_main()) 157 | ; 158 | res = arg; 159 | } 160 | 161 | TEST_CASE("Resume - fiber resume with another function", "[fiber][resume]") 162 | { 163 | int ii{}, result; 164 | for (fiber myfiber(&resume_sub, 10, std::ref(result)); myfiber; ++ii) 165 | { 166 | if (ii == 9) 167 | { 168 | myfiber.resume_with(&resume_sub, 5, std::ref(result)); 169 | while (myfiber) 170 | this_fiber::yield(); 171 | } 172 | this_fiber::yield(); 173 | } 174 | REQUIRE(result == 5); 175 | } 176 | 177 | //----------------------------------------------------------------------------------------- 178 | TEST_CASE("Manyfibers - test with 1000 fibers", "[fiber]") 179 | { 180 | static int cnt{}; 181 | std::thread([] 182 | { 183 | for (int ii{}; ii < 1000; ++ii) 184 | { 185 | fiber([](int arg) 186 | { 187 | for (int ii{}; ii < arg; ++ii) 188 | this_fiber::yield(); 189 | ++cnt; 190 | }, 191 | ii + 1).detach(); 192 | } 193 | }).join(); 194 | 195 | REQUIRE(cnt == 1000); 196 | } 197 | 198 | //----------------------------------------------------------------------------------------- 199 | class generator_foo 200 | { 201 | std::queue _queue; 202 | fiber _produce, _consume; 203 | 204 | void producer() 205 | { 206 | for (int ii{1}; ii <= 10; ++ii) 207 | { 208 | _queue.push(ii); 209 | if (ii % 2 == 0) 210 | _consume.resume(); // switch to consumer 211 | } 212 | _consume.schedule(); // consumer is next fiber to run 213 | } 214 | void consumer(long& res) 215 | { 216 | res = 1; 217 | while (_produce) 218 | { 219 | while(!_queue.empty()) 220 | { 221 | res *= _queue.front(); 222 | _queue.pop(); 223 | } 224 | _produce.resume(); // switch to producer 225 | } 226 | } 227 | 228 | public: 229 | generator_foo(long& res) : _produce(&generator_foo::producer, this), _consume(&generator_foo::consumer, this, std::ref(res)) 230 | { 231 | _produce.resume(); // switch to producer 232 | } 233 | }; 234 | 235 | TEST_CASE("Generator - generate 10!", "[fiber][generator]") 236 | { 237 | long result{}; 238 | generator_foo(std::ref(result)); 239 | REQUIRE(result == 3628800); 240 | } 241 | 242 | //----------------------------------------------------------------------------------------- 243 | TEST_CASE("jfiber - auto joining fiber", "[fiber]") 244 | { 245 | REQUIRE_NOTHROW(std::thread([]() 246 | { 247 | jfiber {[]() 248 | { 249 | for(int ii{}; ii < 10; ++ii) 250 | std::this_thread::sleep_for(100ms); 251 | }}; 252 | }).join()); 253 | } 254 | 255 | -------------------------------------------------------------------------------- /include/fix8/fibermonitor.hpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------------------- 2 | // fiber (header only) 3 | // Copyright (C) 2022-23 Fix8 Market Technologies Pty Ltd 4 | // by David L. Dight 5 | // see https://github.com/fix8mt/fiber 6 | // 7 | // Lightweight header-only stackful per-thread fiber 8 | // with built-in roundrobin scheduler x86_64 / linux only 9 | // 10 | // Distributed under the Boost Software License, Version 1.0 August 17th, 2003 11 | // 12 | // Permission is hereby granted, free of charge, to any person or organization 13 | // obtaining a copy of the software and accompanying documentation covered by 14 | // this license (the "Software") to use, reproduce, display, distribute, 15 | // execute, and transmit the Software, and to prepare derivative works of the 16 | // Software, and to permit third-parties to whom the Software is furnished to 17 | // do so, all subject to the following: 18 | // 19 | // The copyright notices in the Software and this entire statement, including 20 | // the above license grant, this restriction and the following disclaimer, 21 | // must be included in all copies of the Software, in whole or in part, and 22 | // all derivative works of the Software, unless such copies or derivative 23 | // works are solely in the form of machine-executable object code generated by 24 | // a source language processor. 25 | // 26 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 29 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 30 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 31 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | // DEALINGS IN THE SOFTWARE. 33 | //---------------------------------------------------------------------------------------- 34 | #ifndef FIX8_FIBERMONITOR_HPP_ 35 | #define FIX8_FIBERMONITOR_HPP_ 36 | 37 | //---------------------------------------------------------------------------------------- 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | //----------------------------------------------------------------------------------------- 44 | #if defined FIBER_NO_INSTRUMENTATION || !defined FIX8_FIBER_INSTRUMENTATION_ 45 | #error "fiber_monitor can't be built with FIBER_NO_INSTRUMENTATION defined" 46 | #endif 47 | 48 | //----------------------------------------------------------------------------------------- 49 | namespace FIX8 { 50 | 51 | //----------------------------------------------------------------------------------------- 52 | using xy_coord = std::pair; // x,y 53 | using window_coord = std::pair; 54 | 55 | struct window_frame : window_coord 56 | { 57 | using window_coord::window_coord; 58 | constexpr window_frame(xy_coord dim) : window_coord({{},{dim.first, dim.second}}) {} 59 | xy_coord& upper() { return first; } 60 | xy_coord& lower() { return second; } 61 | constexpr xy_coord upper() const { return first; } 62 | constexpr xy_coord lower() const { return second; } 63 | constexpr bool empty() const { return *this == window_coord(); } 64 | }; 65 | 66 | class fiber_monitor 67 | { 68 | public: 69 | enum class sort_mode { by_sched, by_id, by_ms, by_tms, by_name, by_flag, by_ctxsw, by_depth, by_launchorder, count }; 70 | using enum sort_mode; 71 | 72 | static xy_coord get_terminal_dimensions() 73 | { 74 | struct winsize w; 75 | return ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0 ? xy_coord{ w.ws_col, w.ws_row } : xy_coord{-1, -1}; 76 | } 77 | 78 | private: 79 | sort_mode _mode; 80 | const std::chrono::milliseconds _timeout; 81 | std::chrono::steady_clock::time_point _tp; 82 | bool _quit{}, _pause{}; 83 | xy_coord _dimensions; 84 | #if defined FIX8_FIBER_MULTITHREADING_ 85 | f8_spin_lock _pre_spl; 86 | #endif 87 | static constexpr const std::array(count)> 88 | _snames { "sched", "id", "time", "delta time", "name", "flags", "ctxswtch", "depth", "launch order" }; 89 | 90 | public: 91 | fiber_monitor(std::chrono::milliseconds timeout=std::chrono::milliseconds(1), sort_mode mode=by_id) 92 | : _mode(mode), _timeout(timeout), _tp{std::chrono::steady_clock::now()} 93 | { 94 | tb_init(); 95 | _dimensions = { tb_width(), tb_height() }; 96 | } 97 | fiber_monitor(const fiber_monitor&) = delete; 98 | fiber_monitor& operator=(const fiber_monitor&) = delete; 99 | 100 | ~fiber_monitor() 101 | { 102 | tb_shutdown(); 103 | } 104 | 105 | bool is_quit() const noexcept { return _quit; } 106 | bool operator! () const noexcept { return is_quit(); } 107 | xy_coord get_dimensions() const noexcept { return _dimensions; } 108 | virtual bool user_key_process(char key) noexcept { return false; } 109 | 110 | static std::string sort_help() noexcept 111 | { 112 | std::ostringstream result; 113 | for (int ii{}; const auto pp : _snames) 114 | result << ++ii << ':' << pp << ' '; 115 | return std::move(result.str()); 116 | } 117 | 118 | void update_row(int row, int pos, bool iscurrent, const fiber_base& what) const 119 | { 120 | tb_printf(0, row, 0, iscurrent ? TB_BOLD|TB_RED : 0, 121 | "%-4u %c %-4s %-4s %-4s %6u %6u %4u %#14lx %#14lx %8u %8u %7s %3u %15s", 122 | pos, iscurrent ? '*' : ' ', what.get_id().to_string().c_str(), what.get_pid().to_string().c_str(), 123 | what.get_prev_id().to_string().c_str(), what._ctxswtchs, 124 | std::chrono::duration_cast(what._extime).count(), 125 | std::chrono::duration_cast(what._exdelta).count(), 126 | what._stk, what._stk_alloc, what._stk_alloc ? (reinterpret_cast(what._stk_alloc + what._stacksz 127 | / sizeof(uintptr_t) - 1) - reinterpret_cast(what._stk)) : 0, what._stacksz, 128 | what.get_flags_as_string().c_str(), what._params.launch_order, what._params.name); 129 | } 130 | 131 | void update(window_frame winpos=window_frame(), const fiber::cvars *vs=nullptr) 132 | { 133 | if (static thread_local bool notfirst{}; std::exchange(notfirst, true)) 134 | { 135 | if (auto tp { std::chrono::steady_clock::now() }; (tp - _tp) < _timeout) 136 | return; 137 | else 138 | _tp = tp; 139 | } 140 | 141 | static constexpr const char *banner { 142 | "# fid pfid prev ctxsw t(ms) ^t stack ptr stack alloc depth stacksz flags ord name"}; 143 | 144 | if (!_pause) 145 | { 146 | if (!vs) 147 | vs = &fibers::const_get_vars(); 148 | if (winpos.empty()) 149 | winpos = window_frame(_dimensions); 150 | int y{winpos.upper().second}, pos{}; 151 | tb_printf(0, y++, TB_BOLD|TB_WHITE, TB_GREEN, banner); 152 | if (_mode == by_sched) 153 | { 154 | update_row(y++, pos++, true, *vs->_curr); 155 | for (const auto& pp : vs->_sched) // scheduled 156 | if (pp->is_detached() ? !vs->_gflags[static_cast(global_fiber_flags::hidedetached)] : true) 157 | update_row(y++, pos++, false, *pp); 158 | } 159 | else if (_mode == by_id) 160 | for (const auto& pp : vs->_uniq) // all fibers 161 | update_row(y++, pos++, pp == vs->_curr, *pp); 162 | else 163 | { 164 | struct tcmp 165 | { 166 | const sort_mode _smode; 167 | tcmp(sort_mode smode) : _smode(smode) {} 168 | bool operator()(const fiber_base_ptr& lhs, const fiber_base_ptr& rhs) const 169 | { 170 | switch(_smode) 171 | { 172 | case by_ms: 173 | return lhs->_extime < rhs->_extime; 174 | case by_tms: 175 | return lhs->_exdelta < rhs->_exdelta; 176 | case by_name: 177 | return std::strcmp(lhs->_params.name, rhs->_params.name) < 0; 178 | case by_flag: 179 | return lhs->_flags.to_ulong() < rhs->_flags.to_ulong(); 180 | case by_ctxsw: 181 | return lhs->_ctxswtchs < rhs->_ctxswtchs; 182 | case by_launchorder: 183 | return lhs->_params.launch_order < rhs->_params.launch_order; 184 | case by_depth: 185 | return lhs->_stk_alloc ? 186 | (reinterpret_cast(lhs->_stk_alloc + lhs->_stacksz 187 | / sizeof(uintptr_t) - 1) - reinterpret_cast(lhs->_stk)) < 188 | (reinterpret_cast(rhs->_stk_alloc + rhs->_stacksz 189 | / sizeof(uintptr_t) - 1) - reinterpret_cast(rhs->_stk)) : true; 190 | default: 191 | break; 192 | } 193 | return false; 194 | } 195 | }; 196 | std::multiset tset(_mode); 197 | for (const auto pp : vs->_uniq) // all fibers 198 | tset.emplace(pp); 199 | for (const auto& pp : tset) 200 | update_row(y++, pos++, pp == vs->_curr, *pp); 201 | } 202 | // clear remaining window 203 | for (int jj{y}; jj < winpos.lower().second; ++jj) 204 | for (int kk{}; kk < winpos.lower().first; ++kk) 205 | tb_set_cell(kk, jj, ' ', TB_DEFAULT, TB_DEFAULT); 206 | } 207 | 208 | if (tb_event event; tb_peek_event(&event, 0) != TB_ERR_NO_EVENT && event.type == TB_EVENT_KEY) 209 | { 210 | switch (event.ch) 211 | { 212 | case TB_KEY_SPACE: 213 | _mode = static_cast((static_cast(_mode) + 1) % static_cast(count)); 214 | break; 215 | case 'p': 216 | _pause ^= true; 217 | break; 218 | default: 219 | if (std::isdigit(event.ch)) //1 - 9 220 | _mode = sort_mode(static_cast(event.ch) - 0x31); 221 | else if (user_key_process(event.ch)) 222 | case 'x': 223 | _quit = true; 224 | [[fallthrough]]; 225 | case '0': 226 | break; 227 | } 228 | } 229 | const auto smi { static_cast(_mode) }; 230 | tb_printf(0, tb_height() - 1, 0, TB_GREEN, ",<1-9> sort mode(%d:%s),

pause, exit", smi + 1, _snames[smi]); 231 | #if defined FIX8_FIBER_MULTITHREADING_ 232 | f8_scoped_spin_lock guard(_pre_spl); 233 | #endif 234 | tb_present(); 235 | } 236 | }; 237 | 238 | //----------------------------------------------------------------------------------------- 239 | } // namespace FIX8 240 | 241 | #endif // FIX8_FIBERMONITOR_HPP_ 242 | --------------------------------------------------------------------------------