aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-05-10 10:33:34 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-05-10 10:33:34 +0200
commit96f113c40d4934a98aed30a64851feec891a688a (patch)
tree3478958683cca3ce2421fbe6a4e36aa2ca7efcc3
parente8457a85edaa072d043e01b629bc0c124251a9c0 (diff)
Use our own implementation of C++14 threads on MinGW
-rw-r--r--libbuild2/scheduler.hxx22
-rw-r--r--libbuild2/scheduler.test.cxx1
-rw-r--r--libbuild2/types.hxx53
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 <list>
-#include <mutex>
#include <tuple>
#include <atomic>
#include <type_traits> // aligned_storage, etc
-#include <condition_variable>
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
@@ -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<std::mutex>;
+ using lock = build2::mlock;
lock
wait_idle ();
@@ -571,7 +569,7 @@ namespace build2
size_t monitor_init_; // Initial count.
function<size_t (size_t)> monitor_func_;
- std::mutex mutex_;
+ build2::mutex mutex_;
bool shutdown_ = true; // Shutdown flag.
optional<size_t> 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 <chrono>
-#include <thread>
#include <iostream>
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 <functional> // hash, function, reference_wrapper
#include <initializer_list>
-#include <mutex>
#include <atomic>
-#include <thread>
-#include <condition_variable>
-#include <libbutl/ft/shared_mutex.hxx>
-#if defined(__cpp_lib_shared_mutex) || defined(__cpp_lib_shared_timed_mutex)
-# include <shared_mutex>
+#ifndef LIBBUTL_MINGW_STDTHREAD
+# include <mutex>
+# include <thread>
+# include <condition_variable>
+
+# include <libbutl/ft/shared_mutex.hxx>
+# if defined(__cpp_lib_shared_mutex) || defined(__cpp_lib_shared_timed_mutex)
+# include <shared_mutex>
+# endif
+#else
+# include <libbutl/mingw-mutex.hxx>
+# include <libbutl/mingw-thread.hxx>
+# include <libbutl/mingw-condition_variable.hxx>
+# include <libbutl/mingw-shared_mutex.hxx>
#endif
#include <ios> // ios_base::failure
@@ -189,20 +197,27 @@ namespace build2
}
#endif
+#ifndef LIBBUTL_MINGW_STDTHREAD
using std::mutex;
using mlock = std::unique_lock<mutex>;
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<shared_mutex>;
using slock = std::shared_lock<shared_mutex>;
-#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<shared_mutex>;
using slock = std::shared_lock<shared_mutex>;
-#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<shared_mutex>;
using slock = ulock;
-#endif
+# endif
+#else // LIBBUTL_MINGW_STDTHREAD
+ using mingw_stdthread::mutex;
+ using mlock = mingw_stdthread::unique_lock<mutex>;
- 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<shared_mutex>;
+ using slock = mingw_stdthread::shared_lock<shared_mutex>;
+#endif
// Global, MT-safe information cache. Normally used for caching information
// (versions, target triplets, search paths, etc) extracted from other