summaryrefslogtreecommitdiff
path: root/gdbsupport
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2022-05-09 11:48:40 -0600
committerTom Tromey <tromey@adacore.com>2022-05-10 08:15:40 -0600
commit20c4eb4226997c0de0a47d5d4c6c2eed21ed9af4 (patch)
treedb0fd93a83d261b61d2a107d823212a4e8c6c271 /gdbsupport
parentc7d029ea9cc566b8d3c50b08ef12d98394adf1b1 (diff)
Fix --disable-threading build
PR build/29110 points out that GDB fails to build on mingw when the "win32" thread model is in use. It turns out that the Fedora cross tools using the "posix" thread model, which somehow manages to support std::future, whereas the win32 model does not. While looking into this, I found that the configuring with --disable-threading will also cause a build failure. This patch fixes this build by introducing a compatibility wrapper for std::future. I am not able to test the win32 thread model build, but I'm going to ask the reporter to try this patch. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29110
Diffstat (limited to 'gdbsupport')
-rw-r--r--gdbsupport/parallel-for.h4
-rw-r--r--gdbsupport/thread-pool.cc6
-rw-r--r--gdbsupport/thread-pool.h76
3 files changed, 75 insertions, 11 deletions
diff --git a/gdbsupport/parallel-for.h b/gdbsupport/parallel-for.h
index 713ec66030..7b6891a0dc 100644
--- a/gdbsupport/parallel-for.h
+++ b/gdbsupport/parallel-for.h
@@ -72,7 +72,7 @@ private:
/* A vector of futures coming from the tasks run in the
background. */
- std::vector<std::future<T>> m_futures;
+ std::vector<gdb::future<T>> m_futures;
};
/* See the generic template. */
@@ -108,7 +108,7 @@ public:
private:
- std::vector<std::future<void>> m_futures;
+ std::vector<gdb::future<void>> m_futures;
};
}
diff --git a/gdbsupport/thread-pool.cc b/gdbsupport/thread-pool.cc
index 3674e910f1..ddb76b691c 100644
--- a/gdbsupport/thread-pool.cc
+++ b/gdbsupport/thread-pool.cc
@@ -192,12 +192,13 @@ thread_pool::set_thread_count (size_t num_threads)
#endif /* CXX_STD_THREAD */
}
+#if CXX_STD_THREAD
+
void
thread_pool::do_post_task (std::packaged_task<void ()> &&func)
{
std::packaged_task<void ()> t (std::move (func));
-#if CXX_STD_THREAD
if (m_thread_count != 0)
{
std::lock_guard<std::mutex> guard (m_tasks_mutex);
@@ -205,15 +206,12 @@ thread_pool::do_post_task (std::packaged_task<void ()> &&func)
m_tasks_cv.notify_one ();
}
else
-#endif
{
/* Just execute it now. */
t ();
}
}
-#if CXX_STD_THREAD
-
void
thread_pool::thread_function ()
{
diff --git a/gdbsupport/thread-pool.h b/gdbsupport/thread-pool.h
index 5e203fd896..4db35bab95 100644
--- a/gdbsupport/thread-pool.h
+++ b/gdbsupport/thread-pool.h
@@ -27,13 +27,70 @@
#include <thread>
#include <mutex>
#include <condition_variable>
-#endif
#include <future>
+#endif
#include "gdbsupport/gdb_optional.h"
namespace gdb
{
+#if CXX_STD_THREAD
+
+/* Simply use the standard future. */
+template<typename T>
+using future = std::future<T>;
+
+#else /* CXX_STD_THREAD */
+
+/* A compatibility wrapper for std::future. Once <thread> and
+ <future> are available in all GCC builds -- should that ever happen
+ -- this can be removed. GCC does not implement threading for
+ MinGW, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93687.
+
+ Meanwhile, in this mode, there are no threads. Tasks submitted to
+ the thread pool are invoked immediately and their result is stored
+ here. The base template here simply wraps a T and provides some
+ std::future compatibility methods. The provided methods are chosen
+ based on what GDB needs presently. */
+
+template<typename T>
+class future
+{
+public:
+
+ explicit future (T value)
+ : m_value (std::move (value))
+ {
+ }
+
+ future () = default;
+ future (future &&other) = default;
+ future (const future &other) = delete;
+ future &operator= (future &&other) = default;
+ future &operator= (const future &other) = delete;
+
+ void wait () const { }
+
+ T get () { return std::move (m_value); }
+
+private:
+
+ T m_value;
+};
+
+/* A specialization for void. */
+
+template<>
+class future<void>
+{
+public:
+ void wait () const { }
+ void get () { }
+};
+
+#endif /* CXX_STD_THREAD */
+
+
/* A thread pool.
There is a single global thread pool, see g_thread_pool. Tasks can
@@ -64,23 +121,32 @@ public:
/* Post a task to the thread pool. A future is returned, which can
be used to wait for the result. */
- std::future<void> post_task (std::function<void ()> &&func)
+ future<void> post_task (std::function<void ()> &&func)
{
+#if CXX_STD_THREAD
std::packaged_task<void ()> task (std::move (func));
- std::future<void> result = task.get_future ();
+ future<void> result = task.get_future ();
do_post_task (std::packaged_task<void ()> (std::move (task)));
return result;
+#else
+ func ();
+ return {};
+#endif /* CXX_STD_THREAD */
}
/* Post a task to the thread pool. A future is returned, which can
be used to wait for the result. */
template<typename T>
- std::future<T> post_task (std::function<T ()> &&func)
+ future<T> post_task (std::function<T ()> &&func)
{
+#if CXX_STD_THREAD
std::packaged_task<T ()> task (std::move (func));
- std::future<T> result = task.get_future ();
+ future<T> result = task.get_future ();
do_post_task (std::packaged_task<void ()> (std::move (task)));
return result;
+#else
+ return future<T> (func ());
+#endif /* CXX_STD_THREAD */
}
private: