Search code examples
c++boostfibers

Why my boost fiber code is deadlocking


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


Solution

  • 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.