1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // -*- Mode: C++ -*- 3 // 4 // Copyright (C) 2013-2020 Red Hat, Inc. 5 // 6 // Author: Dodji Seketeli 7 8 /// @file 9 /// 10 /// This file declares an interface for the worker threads (or thread 11 /// pool) design pattern. It aims at performing a set of tasks in 12 /// parallel, using the multi-threading capabilities of the underlying 13 /// processor(s). 14 /// 15 16 #ifndef __ABG_WORKERS_H__ 17 #define __ABG_WORKERS_H__ 18 19 #include <memory> 20 #include <vector> 21 22 using std::shared_ptr; 23 24 namespace abigail 25 { 26 27 /// The namespace of the worker threads (or thread pool) 28 /// implementation of libabigail. This was modelled after the article 29 /// https://en.wikipedia.org/wiki/Thread_pool. 30 namespace workers 31 { 32 33 size_t get_number_of_threads(); 34 35 /// This represents a task to be performed. 36 /// 37 /// Each instance of this type represents a task that can be performed 38 /// concurrently to other instance of the same type. 39 /// 40 /// An instance of @ref task is meant to be performed by a worker 41 /// (thread). A set of tasks can be stored in a @ref queue. 42 class task 43 { 44 public: 45 virtual void 46 perform() = 0; 47 ~task()48 virtual ~task(){}; 49 }; // end class task. 50 51 typedef shared_ptr<task> task_sptr; 52 53 /// This represents a queue of tasks to be performed. 54 /// 55 /// Tasks are performed by a number of worker threads. 56 /// 57 /// When a task is inserted into a @ref queue, the task is said to be 58 /// "scheduled for execution". 59 /// 60 /// This is because there are worker threads waiting for tasks to be 61 /// added to the queue. When a task is added to the queue, a worker 62 /// thread picks it up, executes it, notifies interested listeners 63 /// when the @ref task's execution is completed, and waits for another 64 /// task to be added to the queue. 65 /// 66 /// Of course, several worker threads can execute tasks concurrently. 67 class queue 68 { 69 public: 70 struct priv; 71 typedef shared_ptr<priv> priv_sptr; 72 73 /// A convenience typedef for a vector of @ref task_sptr 74 typedef std::vector<task_sptr> tasks_type; 75 76 private: 77 priv_sptr p_; 78 79 public: 80 struct task_done_notify; 81 queue(); 82 queue(unsigned number_of_workers); 83 queue(unsigned number_of_workers, 84 task_done_notify& notifier); 85 size_t get_size() const; 86 bool schedule_task(const task_sptr&); 87 bool schedule_tasks(const tasks_type&); 88 void wait_for_workers_to_complete(); 89 tasks_type& get_completed_tasks() const; 90 ~queue(); 91 }; // end class queue 92 93 /// This functor is to notify listeners that a given task scheduled 94 /// for execution has been fully executed. 95 struct queue::task_done_notify 96 { 97 virtual void 98 operator()(const task_sptr& task_done); 99 }; 100 } // end namespace workers 101 } // end namespace abigail 102 #endif // __ABG_WORKERS_H__ 103