bmv2
Designing your own switch target with bmv2
periodic_task.h
1 /* Copyright 2018 Boon Thau Loo
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef BM_BM_SIM_PERIODIC_TASK_H_
17 #define BM_BM_SIM_PERIODIC_TASK_H_
18 
19 #include <string>
20 #include <vector>
21 #include <thread>
22 #include <atomic>
23 #include <queue>
24 #include <chrono>
25 #include <functional>
26 #include <condition_variable>
27 #include <mutex>
28 
29 namespace bm {
30 
55 class PeriodicTask {
56  public:
57  // Friend so that PeriodicTaskList can call execute()
58  friend class PeriodicTaskList;
59 
60  PeriodicTask(const std::string &name,
61  std::function<void()> fn,
62  std::chrono::milliseconds interval);
63  ~PeriodicTask();
64 
65  // Deleting copy-constructor and copy-assignment
66  PeriodicTask(const PeriodicTask&) = delete;
67  PeriodicTask& operator= (const PeriodicTask&) = delete;
68  // Deleting move constructor and move assignment
69  PeriodicTask(PeriodicTask&&) = delete;
70  PeriodicTask& operator= (PeriodicTask&&) = delete;
71 
72  const std::string name;
73  const std::chrono::milliseconds interval;
74 
75  private:
78  void execute();
79 
80  void reset_next();
81  void cancel();
82 
83  const std::function<void()> fn;
84  std::chrono::system_clock::time_point next;
85 };
86 
91  public:
92  static PeriodicTaskList &get_instance();
93 
94  // Returns true if task was successfully registered
95  bool register_task(PeriodicTask *task);
96  bool unregister_task(PeriodicTask *task);
97 
99  void start();
100  void join();
101 
102  private:
103  class PeriodCompare {
104  public:
105  bool
106  operator() (const PeriodicTask *lhs, const PeriodicTask *rhs) {
107  return lhs->next > rhs->next;
108  }
109  };
110  using TaskQueue = std::priority_queue<PeriodicTask*,
111  std::vector<PeriodicTask*>,
112  PeriodCompare>;
113 
114  PeriodicTaskList() = default;
115  ~PeriodicTaskList();
116 
117  void loop();
118 
119  // The queue of PeriodicTasks, ordered by next execution time
120  TaskQueue task_queue;
121 
122  std::thread periodic_thread;
123  bool running;
124  mutable std::mutex queue_mutex;
125  mutable std::condition_variable cv;
126 };
127 
128 } // namespace bm
129 
130 #endif // BM_BM_SIM_PERIODIC_TASK_H_
bm::PeriodicTask
Definition: periodic_task.h:55
bm::PeriodicTask::execute
void execute()
bm::PeriodicTaskList::start
void start()
Starts the loop which executes the tasks in a new thread.
bm::PeriodicTaskList
Definition: periodic_task.h:90