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