1 /* Thread pool 2 3 Copyright (C) 2019-2021 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #ifndef GDBSUPPORT_THREAD_POOL_H 21 #define GDBSUPPORT_THREAD_POOL_H 22 23 #include <queue> 24 #include <thread> 25 #include <vector> 26 #include <functional> 27 #include <mutex> 28 #include <condition_variable> 29 #include <future> 30 #include "gdbsupport/gdb_optional.h" 31 32 namespace gdb 33 { 34 35 /* A thread pool. 36 37 There is a single global thread pool, see g_thread_pool. Tasks can 38 be submitted to the thread pool. They will be processed in worker 39 threads as time allows. */ 40 class thread_pool 41 { 42 public: 43 /* The sole global thread pool. */ 44 static thread_pool *g_thread_pool; 45 46 ~thread_pool (); 47 DISABLE_COPY_AND_ASSIGN (thread_pool); 48 49 /* Set the thread count of this thread pool. By default, no threads 50 are created -- the thread count must be set first. */ 51 void set_thread_count (size_t num_threads); 52 53 /* Return the number of executing threads. */ thread_count()54 size_t thread_count () const 55 { 56 return m_thread_count; 57 } 58 59 /* Post a task to the thread pool. A future is returned, which can 60 be used to wait for the result. */ 61 std::future<void> post_task (std::function<void ()> &&func); 62 63 private: 64 65 thread_pool () = default; 66 67 /* The callback for each worker thread. */ 68 void thread_function (); 69 70 /* The current thread count. */ 71 size_t m_thread_count = 0; 72 73 /* A convenience typedef for the type of a task. */ 74 typedef std::packaged_task<void ()> task; 75 76 /* The tasks that have not been processed yet. An optional is used 77 to represent a task. If the optional is empty, then this means 78 that the receiving thread should terminate. If the optional is 79 non-empty, then it is an actual task to evaluate. */ 80 std::queue<optional<task>> m_tasks; 81 82 /* A condition variable and mutex that are used for communication 83 between the main thread and the worker threads. */ 84 std::condition_variable m_tasks_cv; 85 std::mutex m_tasks_mutex; 86 }; 87 88 } 89 90 #endif /* GDBSUPPORT_THREAD_POOL_H */ 91