Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why my boost fiber code is deadlocking

Tags:

c++

boost

fibers

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

like image 962
newhouse Avatar asked Mar 10 '17 08:03

newhouse


2 Answers

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.

like image 63
John Estess Avatar answered Sep 29 '22 20:09

John Estess


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.

like image 24
Gert Wollny Avatar answered Sep 29 '22 19:09

Gert Wollny