msys2 / MINGW-packages

Package scripts for MinGW-w64 targets to build under MSYS2.
https://packages.msys2.org
BSD 3-Clause "New" or "Revised" License
2.3k stars 1.22k forks source link

deadlock with multiple shared_mutex on g++7.2.0 and 7.3.0 #3319

Open OmegaDoom opened 6 years ago

OmegaDoom commented 6 years ago

Hello. This code causes a deadlock.

#include <iostream>
#include <shared_mutex>
#include <thread>
#include <chrono>
#include <array>

#define DURATION 500
#define MUTEX_COUNT 128

std::array<std::shared_mutex, MUTEX_COUNT> mutexes;

void lock()
{
    auto duration = std::chrono::milliseconds(DURATION);    
    auto start = std::chrono::system_clock::now();

    unsigned long long index = 0;
    while(duration > std::chrono::system_clock::now() - start)
    {
        std::lock_guard<std::shared_mutex> lock(mutexes[++index % MUTEX_COUNT]);
    }
}

void shared_lock()
{
    auto duration = std::chrono::milliseconds(DURATION);    
    auto start = std::chrono::system_clock::now();

    unsigned long long index = 0;
    while(duration > std::chrono::system_clock::now() - start)
    {
        std::shared_lock<std::shared_mutex> lock(mutexes[++index % MUTEX_COUNT]);
    }
}

int main(int argc, char* argv[])
{
    std::thread thr3(shared_lock);
    std::thread thr1(lock);
    std::thread thr2(lock);

    thr1.join();
    thr2.join();
    thr3.join();

    std::cout << "OK" << std::endl;
}

Run this program multiple times and eventually it goes to deadlock. There is no such bug on c++ 7.2.0 of ubuntu and VS 2017.

petrutlucian94 commented 2 years ago

We're hitting the same issue on Ceph. The above sample is still hanging using mingw 8.0.0 and g++-mingw-w64 10.3.0.

Biswa96 commented 2 years ago

Can you reproduce the issue with latest GCC toolchain 12.1.0?

petrutlucian94 commented 2 years ago

Can you reproduce the issue with latest GCC toolchain 12.1.0?

I'm giving it a try, thanks for the suggestion.

petrutlucian94 commented 2 years ago

Same behavior using mingw 10.0.0 and gcc 12.1.0.

Here's a trace: https://pastebin.com/raw/wBzzpqi1

There seems to be a deadlock between the following calls:

mati865 commented 2 years ago

I suppose this is one of GCC emulatedTLS bugs. You'd probably have to use Clang from CLANG64 subsystem to workaround it. Otherwise the best way to solve it is reporting at GCC's bugzilla.

lhmouse commented 2 years ago

There have been issues in winpthreads that never get fixed. However, do you have any interest in https://gcc-mcf.lhmouse.com/? I believe it is feasible to create a new threading library to replace winpthreads.

petrutlucian94 commented 2 years ago

There have been issues in winpthreads that never get fixed. However, do you have any interest in https://gcc-mcf.lhmouse.com/? I believe it is feasible to create a new threading library to replace winpthreads.

Thanks for mentioning mcfgthread. It seems promising, however it was more convenient for us to just switch to boost::shared_mutex to avoid this specific issue, at least for the time being. Having to patch gcc and mingw would complicate the ceph build process and maintenance.