summaryrefslogtreecommitdiff
path: root/system/common/timer.h
diff options
context:
space:
mode:
authorHansong Zhang <hsz@google.com>2018-08-14 14:29:23 -0700
committerHansong Zhang <hsz@google.com>2018-09-13 13:37:42 -0700
commitf05a8c49a889b5a83841e4bf55dd3cf5a1afa8d0 (patch)
tree5bc7d1343c049f61e0bafec0158a3f336dc2b137 /system/common/timer.h
parent76250727b2fa2a5a6364edcb20e4d379c82090a4 (diff)
Add Timer as an alternative to osi alarm
* Add a private method MessageLoopThread.DoInThreadDelayed to post a delayed task in message loop, as an alternative approach to osi alarm clock * Add a unit test for MessageLoopThread to check ShutDown() waits until current task finishes * Add Timer using MessageLoopThread.DoInThreadDelayed * Timer provides similar API as osi alarm, and uses same OS clock (boot timer) as alarm * Add benchmark and unit tests to ensure the performance is comparable to the existing osi alarm Test: Run unit test and benchmark test ./test/run_unit_tests.sh bluetooth_test_common ./test/run_benchmarks.sh bluetooth_benchmark_timer_performance --benchmark_repetitions=10 --benchmark_report_aggregates_only=true Bug: 110303473 Change-Id: I6f2e7ae2f80f9889fc5fe3c8cd6b9b2670938b46
Diffstat (limited to 'system/common/timer.h')
-rw-r--r--system/common/timer.h119
1 files changed, 119 insertions, 0 deletions
diff --git a/system/common/timer.h b/system/common/timer.h
new file mode 100644
index 0000000000..e8532a5cd5
--- /dev/null
+++ b/system/common/timer.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <base/bind.h>
+#include <base/cancelable_callback.h>
+#include <base/tracked_objects.h>
+#include <future>
+
+namespace bluetooth {
+
+namespace common {
+
+class MessageLoopThread;
+
+/**
+ * An alarm clock that posts a delayed task to a specified MessageLoopThread
+ * once or periodically.
+ *
+ * Warning: MessageLoopThread must be running when any task is scheduled or
+ * being executed
+ */
+class Timer final {
+ public:
+ Timer()
+ : task_wrapper_(base::Bind(&Timer::RunTask, base::Unretained(this))),
+ is_periodic_(false),
+ expected_time_next_task_us_(0) {}
+ ~Timer();
+ Timer(const Timer&) = delete;
+ Timer& operator=(const Timer&) = delete;
+
+ /**
+ * Schedule a delayed task to the MessageLoopThread. Only one task can be
+ * scheduled at a time. If another task is scheduled, it will cancel the
+ * previous task synchronously and schedule the new task; this blocks until
+ * the previous task is cancelled.
+ *
+ * @param thread thread to run the task
+ * @param from_here location where this task is originated
+ * @param task task created through base::Bind()
+ * @param delay delay for the task to be executed
+ * @return true iff task is scheduled successfully
+ */
+ bool Schedule(const base::WeakPtr<MessageLoopThread>& thread,
+ const tracked_objects::Location& from_here, base::Closure task,
+ base::TimeDelta delay);
+
+ /**
+ * Schedule a delayed periodic task to the MessageLoopThread. Only one task
+ * can be scheduled at a time. If another task is scheduled, it will cancel
+ * the previous task synchronously and schedule the new periodic task; this
+ * blocks until the previous task is cancelled.
+ *
+ * @param thread thread to run the task
+ * @param from_here location where this task is originated
+ * @param task task created through base::Bind()
+ * @param period period for the task to be executed
+ * @return true iff task is scheduled successfully
+ */
+ bool SchedulePeriodic(const base::WeakPtr<MessageLoopThread>& thread,
+ const tracked_objects::Location& from_here,
+ base::Closure task, base::TimeDelta period);
+
+ /**
+ * Post an event which cancels the current task asynchronously
+ */
+ void Cancel();
+
+ /**
+ * Post an event which cancels the current task and wait for the cancellation
+ * to be completed
+ */
+ void CancelAndWait();
+
+ /**
+ * Returns true when there is a pending task scheduled on a running thread,
+ * otherwise false.
+ */
+ bool IsScheduled() const;
+
+ private:
+ base::WeakPtr<MessageLoopThread> message_loop_thread_;
+ const base::Closure task_wrapper_;
+ base::Closure task_;
+ base::TimeDelta period_;
+ bool is_periodic_;
+ uint64_t expected_time_next_task_us_; // Using clock boot time in time_util.h
+ mutable std::recursive_mutex api_mutex_;
+ bool ScheduleTaskHelper(const base::WeakPtr<MessageLoopThread>& thread,
+ const tracked_objects::Location& from_here,
+ base::Closure task, base::TimeDelta delay,
+ bool is_periodic);
+ void CancelHelper(bool is_synchronous);
+ void CancelClosure(std::promise<void> promise);
+
+ /**
+ * Wraps a task. It posts another same task if the scheduled task is periodic.
+ */
+ void RunTask();
+};
+
+} // namespace common
+
+} // namespace bluetooth