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;

}

Reply via email to