diff options
author | Hansong Zhang <hsz@google.com> | 2018-08-14 14:29:23 -0700 |
---|---|---|
committer | Hansong Zhang <hsz@google.com> | 2018-09-13 13:37:42 -0700 |
commit | f05a8c49a889b5a83841e4bf55dd3cf5a1afa8d0 (patch) | |
tree | 5bc7d1343c049f61e0bafec0158a3f336dc2b137 /system/common/timer.h | |
parent | 76250727b2fa2a5a6364edcb20e4d379c82090a4 (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.h | 119 |
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 |