xref: /aosp_15_r20/system/chre/platform/linux/include/chre/platform/linux/task_util/task.h (revision 84e339476a462649f82315436d70fd732297a399)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_PLATFORM_LINUX_TASK_UTIL_TASK_H_
18 #define CHRE_PLATFORM_LINUX_TASK_UTIL_TASK_H_
19 
20 #include <chrono>
21 #include <cstdint>
22 #include <functional>
23 #include <mutex>
24 #include <optional>
25 
26 namespace chre {
27 namespace task_manager_internal {
28 
29 /**
30  * Represents a task to execute (a function to call) that can be executed once
31  * or repeatedly with interval: intervalOrDelay in nanoseconds until
32  * cancel() is called.
33  *
34  * Note: The Task class is not thread-safe nor synchronized properly. It is
35  * meant to be externally synchronized (see TaskManager).
36  */
37 class Task {
38  public:
39   using TaskFunction = std::function<void()>;
40 
41   /**
42    * Construct an empty Task object.
43    */
Task()44   Task()
45       : mExecutionTimestamp(std::chrono::steady_clock::now()),
46         mRepeatInterval(0),
47         mId(0),
48         mHasExecuted(false) {}
49 
50   /**
51    * Construct a new Task object.
52    *
53    * @param func              the function to execute.
54    * @param intervalOrDelay   the interval in which to repeat execution or the
55    * delay for a one-shot Task.
56    * @param id                the unique ID for use with the Task Manager.
57    * @param isOneShot         if true, the task should only be executed once
58    * after a delay of intervalOrDelay.
59    */
60   Task(const TaskFunction &func, std::chrono::nanoseconds intervalOrDelay,
61        uint32_t id, bool isOneShot = false);
62 
63   /**
64    * Construct a new Task object.
65    *
66    * @param rhs               copy constructor args.
67    */
68   Task(const Task &rhs);
69 
70   /**
71    * Assignment operator.
72    *
73    * @param rhs               rhs arg.
74    * @return                  this.
75    */
76   Task &operator=(const Task &rhs);
77 
78   /**
79    * Stops the task from repeating.
80    */
81   void cancel();
82 
83   /**
84    * Executes the function.
85    */
86   void execute();
87 
88   /**
89    * Gets the next time the task should execute.
90    */
91   inline std::chrono::time_point<std::chrono::steady_clock>
getExecutionTimestamp()92   getExecutionTimestamp() const {
93     return mExecutionTimestamp;
94   }
95 
96   /**
97    * Gets the ID of the task.
98    */
getId()99   inline uint32_t getId() const {
100     return mId;
101   }
102 
103   /**
104    * Returns true if the task has executed at least once, false if otherwise.
105    *
106    * @return true             if the task has executed at least once.
107    * @return false            if the task has not executed at least once.
108    */
hasExecuted()109   inline bool hasExecuted() const {
110     return mHasExecuted;
111   }
112 
113   /**
114    * Returns true if the task is ready to execute (time now is >= task
115    * timestamp).
116    *
117    * @return true             the task can be executed.
118    * @return false            do not yet execute the task.
119    */
isReadyToExecute()120   inline bool isReadyToExecute() const {
121     return mExecutionTimestamp <= std::chrono::steady_clock::now();
122   }
123 
124   /**
125    * Returns true if the task is a repeating task - if it has has a
126    * intervalOrDelay > 0.
127    *
128    * @return true             if the task is a repeating task.
129    * @return false            otherwise.
130    */
isRepeating()131   inline bool isRepeating() const {
132     return mRepeatInterval.count() > 0;
133   }
134 
135   /*
136    * The following relational operators are comparing execution timestamps.
137    */
138   inline bool operator<(const Task &rhs) const {
139     return mExecutionTimestamp < rhs.mExecutionTimestamp;
140   }
141 
142   inline bool operator>(const Task &rhs) const {
143     return mExecutionTimestamp > rhs.mExecutionTimestamp;
144   }
145 
146   inline bool operator<=(const Task &rhs) const {
147     return mExecutionTimestamp <= rhs.mExecutionTimestamp;
148   }
149 
150   inline bool operator>=(const Task &rhs) const {
151     return mExecutionTimestamp >= rhs.mExecutionTimestamp;
152   }
153 
154  private:
155   /**
156    * Time timestamp of when the task should be executed.
157    */
158   std::chrono::time_point<std::chrono::steady_clock> mExecutionTimestamp;
159 
160   /**
161    * The amount of time to wait in between repeating the task.
162    */
163   std::chrono::nanoseconds mRepeatInterval;
164 
165   /**
166    * The function to execute.
167    */
168   std::optional<TaskFunction> mFunc;
169 
170   /**
171    * The ID of the task.
172    */
173   uint32_t mId;
174 
175   /**
176    * If the task has executed at least once.
177    */
178   bool mHasExecuted;
179 
180   /**
181    * Mutex for execution.
182    */
183   std::mutex mExecutionMutex;
184 };
185 
186 }  // namespace task_manager_internal
187 }  // namespace chre
188 
189 #endif  // CHRE_PLATFORM_LINUX_TASK_UTIL_TASK_H_
190