From 96f113c40d4934a98aed30a64851feec891a688a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 10 May 2022 10:33:34 +0200 Subject: Use our own implementation of C++14 threads on MinGW --- libbuild2/scheduler.hxx | 22 +++++++++--------- libbuild2/scheduler.test.cxx | 1 - libbuild2/types.hxx | 53 ++++++++++++++++++++++++++++++++------------ 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/libbuild2/scheduler.hxx b/libbuild2/scheduler.hxx index 76b3263..dc18859 100644 --- a/libbuild2/scheduler.hxx +++ b/libbuild2/scheduler.hxx @@ -5,11 +5,9 @@ #define LIBBUILD2_SCHEDULER_HXX #include -#include #include #include #include // aligned_storage, etc -#include #include #include @@ -492,7 +490,7 @@ namespace build2 static size_t hardware_concurrency () { - return std::thread::hardware_concurrency (); + return build2::thread::hardware_concurrency (); } // Return a prime number that can be used as a lock shard size that's @@ -509,7 +507,7 @@ namespace build2 // to become idle. Return the lock over the scheduler mutex. Normally you // don't need to call this function directly. // - using lock = std::unique_lock; + using lock = build2::mlock; lock wait_idle (); @@ -571,7 +569,7 @@ namespace build2 size_t monitor_init_; // Initial count. function monitor_func_; - std::mutex mutex_; + build2::mutex mutex_; bool shutdown_ = true; // Shutdown flag. optional max_stack_; @@ -611,8 +609,8 @@ namespace build2 // size_t orig_max_active_ = 0; - std::condition_variable idle_condv_; // Idle helpers queue. - std::condition_variable ready_condv_; // Ready masters queue. + build2::condition_variable idle_condv_; // Idle helpers queue. + build2::condition_variable ready_condv_; // Ready masters queue. // Statistics counters. // @@ -631,8 +629,8 @@ namespace build2 // Deadlock detection. // - std::thread dead_thread_; - std::condition_variable dead_condv_; + build2::thread dead_thread_; + build2::condition_variable dead_condv_; static void* deadlock_monitor (void*); @@ -653,8 +651,8 @@ namespace build2 // struct wait_slot { - std::mutex mutex; - std::condition_variable condv; + build2::mutex mutex; + build2::condition_variable condv; size_t waiters = 0; const atomic_count* task_count; bool shutdown = true; @@ -726,7 +724,7 @@ namespace build2 struct task_queue: task_queue_data { - std::mutex mutex; + build2::mutex mutex; bool shutdown = false; size_t stat_full = 0; // Number of times push() returned NULL. diff --git a/libbuild2/scheduler.test.cxx b/libbuild2/scheduler.test.cxx index b29c932..2ef8d5c 100644 --- a/libbuild2/scheduler.test.cxx +++ b/libbuild2/scheduler.test.cxx @@ -2,7 +2,6 @@ // license : MIT; see accompanying LICENSE file #include -#include #include diff --git a/libbuild2/types.hxx b/libbuild2/types.hxx index cd6fdd8..c260aeb 100644 --- a/libbuild2/types.hxx +++ b/libbuild2/types.hxx @@ -29,14 +29,22 @@ #include // hash, function, reference_wrapper #include -#include #include -#include -#include -#include -#if defined(__cpp_lib_shared_mutex) || defined(__cpp_lib_shared_timed_mutex) -# include +#ifndef LIBBUTL_MINGW_STDTHREAD +# include +# include +# include + +# include +# if defined(__cpp_lib_shared_mutex) || defined(__cpp_lib_shared_timed_mutex) +# include +# endif +#else +# include +# include +# include +# include #endif #include // ios_base::failure @@ -189,20 +197,27 @@ namespace build2 } #endif +#ifndef LIBBUTL_MINGW_STDTHREAD using std::mutex; using mlock = std::unique_lock; using std::condition_variable; -#if defined(__cpp_lib_shared_mutex) + using std::defer_lock; + using std::adopt_lock; + + using std::thread; + namespace this_thread = std::this_thread; + +# if defined(__cpp_lib_shared_mutex) using shared_mutex = std::shared_mutex; using ulock = std::unique_lock; using slock = std::shared_lock; -#elif defined(__cpp_lib_shared_timed_mutex) +# elif defined(__cpp_lib_shared_timed_mutex) using shared_mutex = std::shared_timed_mutex; using ulock = std::unique_lock; using slock = std::shared_lock; -#else +# else // Because we have this fallback, we need to be careful not to create // multiple shared locks in the same thread. // @@ -217,13 +232,23 @@ namespace build2 using ulock = std::unique_lock; using slock = ulock; -#endif +# endif +#else // LIBBUTL_MINGW_STDTHREAD + using mingw_stdthread::mutex; + using mlock = mingw_stdthread::unique_lock; - using std::defer_lock; - using std::adopt_lock; + using mingw_stdthread::condition_variable; - using std::thread; - namespace this_thread = std::this_thread; + using mingw_stdthread::defer_lock; + using mingw_stdthread::adopt_lock; + + using mingw_stdthread::thread; + namespace this_thread = mingw_stdthread::this_thread; + + using shared_mutex = mingw_stdthread::shared_mutex; + using ulock = mingw_stdthread::unique_lock; + using slock = mingw_stdthread::shared_lock; +#endif // Global, MT-safe information cache. Normally used for caching information // (versions, target triplets, search paths, etc) extracted from other -- cgit v1.1