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