I've tried out boost::fibers::barrier and I cannot find out why the following code deadlocks:
#include <boost/fiber/all.hpp>
#include <iostream>
#include <boost/range/algorithm/generate.hpp>
#include <boost/range/algorithm/for_each.hpp>
void barrier_test()
{
boost::fibers::barrier barrier(2);
std::vector<boost::fibers::fiber> myfibers(4);
boost::generate(myfibers, [&barrier]() {
return boost::fibers::fiber([](boost::fibers::barrier& barrier) {
static unsigned id_inc = 0;
const auto id = ++id_inc;
std::cout << "fiber id: " << boost::this_fiber::get_id() << " - local id: " << id << std::endl;
barrier.wait();
std::cout << "barrier passed, fiber id: " << boost::this_fiber::get_id() << " - local id: " << id << std::endl;
}, std::ref(barrier) );
});
std::cout << "main fiber: " << boost::this_fiber::get_id() << std::endl;
boost::for_each(myfibers, [](boost::fibers::fiber& aFiber) {
aFiber.join();
});
std::cout << "end of program" << std::endl;
}
If I set the launch as "dispatch" it can go through. So it has something with the order of running, but I don't know what is wrong. So I've tried to imagine how locking goes behind the scene, what gets running, etc, but I just cannot find out, why the original code is not able to finish.
If somebody does not want to try it out, let me put here the output I see:
main fiber: 000000000042C960
fiber id: 000000000042C6E0 - local id: 1
fiber id: 000000000044CF60 - local id: 2
barrier passed, fiber id: 000000000044CF60 - local id: 2
fiber id: 000000000045D020 - local id: 3
fiber id: 000000000046D0E0 - local id: 4
barrier passed, fiber id: 000000000046D0E0 - local id: 4
barrier passed, fiber id: 000000000045D020 - local id: 3
I've copied a custom test scheduler algorithm of mine into the test code and I see, that after a while, no fiber is availabe for running, the local id 1 fiber is simply not continuing.
Boost version is 1.63 with visual studio 2015 precompiled package and the compilation is in 64bit
The code never deadlocks for me, but there are some variables to consider: I'm on a mac, I'm using boost 1.64, and I might have compiled boost differently.
boost? ./fibers
main fiber: 0x7f877cc02bc0
fiber id: 0x100cbce00 - local id: 1
fiber id: 0x100ebce00 - local id: 2
barrier passed, fiber id: 0x100ebce00 - local id: 2
fiber id: 0x100fbce00 - local id: 3
fiber id: 0x1010bce00 - local id: 4
barrier passed, fiber id: 0x1010bce00 - local id: 4
barrier passed, fiber id: 0x100cbce00 - local id: 1
barrier passed, fiber id: 0x100fbce00 - local id: 3
end of program
FYI - I compiled and ran like this:
./bootstrap.sh --prefix=/Users/john/boost/boost_installation --without-libraries=python
./b2 install cxxflags='-std=c++14' -j 6 threading=multi variant=release link=shared stage --reconfigure
g++ -std=c++14 -I/Users/john/boost/boost_installation/include/ -L/Users/john/boost/boost_installation/lib -lboost_context -lboost_system -lboost_thread -lpthread -lboost_fiber -o fibers fibers.cpp
DYLD_LIBRARY_PATH=/Users/john/boost/boost_installation/lib
./fibers
This may not be what you need, but since it works for me I can't help you.
I tried the program on Debian/unstable with boost-1.63.0 and I can confirm the problem. When I run the program using valgrind access to uninitialized memory is reported and later on also invalid reads, so I guess the problem is with that specific boost version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With