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 72 /// A convenience typedef for a vector of @ref task_sptr 73 typedef std::vector<task_sptr> tasks_type; 74 75 private: 76 std::unique_ptr<priv> p_; 77 78 public: 79 struct task_done_notify; 80 queue(); 81 queue(unsigned number_of_workers); 82 queue(unsigned number_of_workers, 83 task_done_notify& notifier); 84 size_t get_size() const; 85 bool schedule_task(const task_sptr&); 86 bool schedule_tasks(const tasks_type&); 87 void wait_for_workers_to_complete(); 88 tasks_type& get_completed_tasks() const; 89 ~queue(); 90 }; // end class queue 91 92 /// This functor is to notify listeners that a given task scheduled 93 /// for execution has been fully executed. 94 struct queue::task_done_notify 95 { 96 virtual void 97 operator()(const task_sptr& task_done); 98 }; 99 } // end namespace workers 100 } // end namespace abigail 101 #endif // __ABG_WORKERS_H__ 102