diff options
-rw-r--r-- | gdb/dwarf2/cooked-index.h | 2 | ||||
-rw-r--r-- | gdbsupport/parallel-for.h | 4 | ||||
-rw-r--r-- | gdbsupport/thread-pool.cc | 6 | ||||
-rw-r--r-- | gdbsupport/thread-pool.h | 76 |
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: |