https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102962
Bug ID: 102962 Summary: shared locks / mutexes differ between linux and windows Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Marco.Mengelkoch1 at ibm dot com Target Milestone: --- I created some minimal example to investigate the issues and I have the same application that runs 3 seconds on windows and returns properly but runs for hours (I stopped watching after 20 minutes) on my linux system and never finishes. It seems that linux now prefers shared_locks over unique_locks. As long as there are shared_locks that own the mutex, no unqiue_lock will be able to get the mutex, while new shared locks still get the mutex. Windows still prefers unique_locks instead. I know that there might be differences between compilers, but as this is basically both g++, I assumed that the application should work the same way. Here is the application: Runtime on windows 10, g++: 3s Runtime on RHEL 8.4 / Ubuntu WSL with g++: both stopped watching after > 20 minutes Code sample: // mutex.cpp // linux: // g++ -g -O2 -o stlM mutex.cpp -std=c++17 -pthread && ./stlM // windows: // g++ -g -O2 -o stlM.exe mutex.cpp -std=c++17 #include <exception> #include <iostream> #include <chrono> #include <thread> #include <memory> #include <shared_mutex> typedef std::thread Thread; typedef std::shared_mutex SharedMutex; typedef std::unique_lock<SharedMutex> UniqueLock; typedef std::shared_lock<SharedMutex> SharedLock; #define MUTEX_STRING "STL" SharedMutex myMutex; const size_t maxIterations = 20000000; int sharedLocking() { for (size_t i = 1; i < maxIterations; ++i) { SharedLock a(myMutex); if (i % 200 == 0) { std::cout << "." << std::flush; } std::this_thread::sleep_for(std::chrono::milliseconds(5)); } std::cout << "Finished local" << std::flush; return 0; } int uniqueLocking() { std::cout << "_" << std::flush; UniqueLock a(myMutex); std::cout << "|" << std::flush; std::cout << "Unique" << std::endl << std::flush; std::this_thread::sleep_for(std::chrono::seconds(2)); exit(0); return 0; } int main(int argc, char **argv) { std::cout << "Using " << MUTEX_STRING << " mutexes" << std::endl; std::cout << " starting ..." << std::endl; for (int i = 0; i < 128; ++i) { std::shared_ptr<Thread> tmpThread = std::make_shared<Thread>(&sharedLocking); tmpThread->detach(); } std::this_thread::sleep_for(std::chrono::seconds(1)); std::shared_ptr<Thread> myThread = std::make_shared<Thread>(&uniqueLocking); std::shared_ptr<Thread> myThread2 = std::make_shared<Thread>(&uniqueLocking); myThread->join(); return 0; }