aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/dwarf2/cooked-index.h2
-rw-r--r--gdbsupport/parallel-for.h4
-rw-r--r--gdbsupport/thread-pool.cc6
-rw-r--r--gdbsupport/thread-pool.h76
4 files changed, 76 insertions, 12 deletions
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index a460351..1d22958 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -330,7 +330,7 @@ private:
/* A future that tracks when the 'finalize' method is done. Note
that the 'get' method is never called on this future, only
'wait'. */
- std::future<void> m_future;
+ gdb::future<void> m_future;
};
#endif /* GDB_DWARF2_COOKED_INDEX_H */
diff --git a/gdbsupport/parallel-for.h b/gdbsupport/parallel-for.h
index 713ec66..7b6891a 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 3674e91..ddb76b69 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 5e203fd..4db35ba 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: