Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fdcaf26d authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

Split Timer into OnceTimer and RepeatingTimer am: cd985f72

am: d873136e

Change-Id: I90fa25a2d9bae98429a8486e5b74799d6b2537d5
parents 9b9ff589 d873136e
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -41,8 +41,8 @@
#include "btif_util.h"
#include "common/message_loop_thread.h"
#include "common/metrics.h"
#include "common/repeating_timer.h"
#include "common/time_util.h"
#include "common/timer.h"
#include "osi/include/fixed_queue.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
@@ -51,7 +51,7 @@

using bluetooth::common::A2dpSessionMetrics;
using bluetooth::common::BluetoothMetricsLogger;
using bluetooth::common::Timer;
using bluetooth::common::RepeatingTimer;

extern std::unique_ptr<tUIPC_STATE> a2dp_uipc;

@@ -212,7 +212,7 @@ class BtifA2dpSource {

  fixed_queue_t* tx_audio_queue;
  bool tx_flush; /* Discards any outgoing data when true */
  Timer media_alarm;
  RepeatingTimer media_alarm;
  const tA2DP_ENCODER_INTERFACE* encoder_interface;
  uint64_t encoder_interval_ms; /* Local copy of the encoder interval */
  BtifMediaStats stats;
+4 −2
Original line number Diff line number Diff line
@@ -8,9 +8,10 @@ cc_library_static {
    ],
    srcs: [
        "address_obfuscator.cc",
        "timer.cc",
        "message_loop_thread.cc",
        "metrics.cc",
        "once_timer.cc",
        "repeating_timer.cc",
        "time_util.cc",
    ],
    shared_libs: [
@@ -32,10 +33,11 @@ cc_test {
    ],
    srcs : [
        "address_obfuscator_unittest.cc",
        "timer_unittest.cc",
        "leaky_bonded_queue_unittest.cc",
        "message_loop_thread_unittest.cc",
        "metrics_unittest.cc",
        "once_timer_unittest.cc",
        "repeating_timer_unittest.cc",
        "state_machine_unittest.cc",
        "time_util_unittest.cc",
    ],
+27 −17
Original line number Diff line number Diff line
@@ -21,14 +21,16 @@
#include <future>

#include "common/message_loop_thread.h"
#include "common/once_timer.h"
#include "common/repeating_timer.h"
#include "common/time_util.h"
#include "common/timer.h"
#include "osi/include/alarm.h"

using ::benchmark::State;
using bluetooth::common::MessageLoopThread;
using bluetooth::common::OnceTimer;
using bluetooth::common::RepeatingTimer;
using bluetooth::common::time_get_os_boottime_us;
using bluetooth::common::Timer;

// fake get_main_message_loop implementation for alarm
base::MessageLoop* get_main_message_loop() { return nullptr; }
@@ -104,14 +106,17 @@ class BM_AlarmTaskTimer : public ::benchmark::Fixture {
    message_loop_thread_ = new MessageLoopThread("timer_benchmark");
    message_loop_thread_->StartUp();
    message_loop_thread_->EnableRealTimeScheduling();
    timer_ = new Timer();
    once_timer_ = new OnceTimer();
    repeating_timer_ = new RepeatingTimer();
    g_promise = std::make_shared<std::promise<void>>();
  }

  void TearDown(State& st) override {
    g_promise = nullptr;
    delete timer_;
    timer_ = nullptr;
    delete once_timer_;
    once_timer_ = nullptr;
    delete repeating_timer_;
    repeating_timer_ = nullptr;
    message_loop_thread_->ShutDown();
    delete message_loop_thread_;
    message_loop_thread_ = nullptr;
@@ -119,18 +124,19 @@ class BM_AlarmTaskTimer : public ::benchmark::Fixture {
  }

  MessageLoopThread* message_loop_thread_;
  Timer* timer_;
  OnceTimer* once_timer_;
  RepeatingTimer* repeating_timer_;
};

BENCHMARK_DEFINE_F(BM_AlarmTaskTimer, timer_performance_ms)(State& state) {
  auto milliseconds = static_cast<int>(state.range(0));
  for (auto _ : state) {
    auto start_time_point = time_get_os_boottime_us();
    timer_->Schedule(message_loop_thread_->GetWeakPtr(), FROM_HERE,
                     base::Bind(&TimerFire, nullptr),
    once_timer_->Schedule(message_loop_thread_->GetWeakPtr(), FROM_HERE,
                          base::BindOnce(&TimerFire, nullptr),
                          base::TimeDelta::FromMilliseconds(milliseconds));
    g_promise->get_future().get();
    timer_->Cancel();
    once_timer_->Cancel();
    auto end_time_point = time_get_os_boottime_us();
    auto duration = end_time_point - start_time_point;
    state.SetIterationTime(duration * 1e-6);
@@ -204,7 +210,8 @@ class BM_AlarmTaskPeriodicTimer : public ::benchmark::Fixture {
    message_loop_thread_ = new MessageLoopThread("timer_benchmark");
    message_loop_thread_->StartUp();
    message_loop_thread_->EnableRealTimeScheduling();
    timer_ = new Timer();
    once_timer_ = new OnceTimer();
    repeating_timer_ = new RepeatingTimer();
    g_map.clear();
    g_promise = std::make_shared<std::promise<void>>();
    g_scheduled_tasks = 0;
@@ -215,8 +222,10 @@ class BM_AlarmTaskPeriodicTimer : public ::benchmark::Fixture {

  void TearDown(State& st) override {
    g_promise = nullptr;
    delete timer_;
    timer_ = nullptr;
    delete once_timer_;
    once_timer_ = nullptr;
    delete repeating_timer_;
    repeating_timer_ = nullptr;
    message_loop_thread_->ShutDown();
    delete message_loop_thread_;
    message_loop_thread_ = nullptr;
@@ -224,7 +233,8 @@ class BM_AlarmTaskPeriodicTimer : public ::benchmark::Fixture {
  }

  MessageLoopThread* message_loop_thread_;
  Timer* timer_;
  OnceTimer* once_timer_;
  RepeatingTimer* repeating_timer_;
};

BENCHMARK_DEFINE_F(BM_AlarmTaskPeriodicTimer, periodic_accuracy)
@@ -234,12 +244,12 @@ BENCHMARK_DEFINE_F(BM_AlarmTaskPeriodicTimer, periodic_accuracy)
    g_task_length = state.range(1);
    g_task_interval = state.range(2);
    g_start_time = time_get_os_boottime_us();
    timer_->SchedulePeriodic(
    repeating_timer_->SchedulePeriodic(
        message_loop_thread_->GetWeakPtr(), FROM_HERE,
        base::Bind(&AlarmSleepAndCountDelayedTime, nullptr),
        base::BindRepeating(&AlarmSleepAndCountDelayedTime, nullptr),
        base::TimeDelta::FromMilliseconds(g_task_interval));
    g_promise->get_future().get();
    timer_->Cancel();
    repeating_timer_->Cancel();
  }
  for (const auto& delay : g_map) {
    state.counters[std::to_string(delay.first)] = delay.second;
+2 −1
Original line number Diff line number Diff line
@@ -176,7 +176,8 @@ class MessageLoopThread final {
  bool DoInThreadDelayed(const base::Location& from_here,
                         base::OnceClosure task, const base::TimeDelta& delay);

  friend class Timer;  // allow Timer to use DoInThreadDelayed()
  friend class RepeatingTimer;  // allow Timer to use DoInThreadDelayed()
  friend class OnceTimer;       // allow OnceTimer to use DoInThreadDelayed()

  /**
   * Actual method to run the thread, blocking until ShutDown() is called
+130 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#include "once_timer.h"

#include "message_loop_thread.h"
#include "time_util.h"

namespace bluetooth {

namespace common {

// This runs on user thread
OnceTimer::~OnceTimer() {
  std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
  if (message_loop_thread_ != nullptr && message_loop_thread_->IsRunning()) {
    CancelAndWait();
  }
}

// This runs on user thread
bool OnceTimer::Schedule(const base::WeakPtr<MessageLoopThread>& thread,
                         const base::Location& from_here,
                         base::OnceClosure task, base::TimeDelta delay) {
  uint64_t time_now_us = time_get_os_boottime_us();
  uint64_t time_next_task_us = time_now_us + delay.InMicroseconds();
  std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
  if (thread == nullptr) {
    LOG(ERROR) << __func__ << ": thread must be non-null";
    return false;
  }
  CancelAndWait();
  task_ = std::move(task);
  task_wrapper_.Reset(
      base::BindOnce(&OnceTimer::RunTask, base::Unretained(this)));
  message_loop_thread_ = thread;
  delay_ = delay;
  uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us();
  if (!thread->DoInThreadDelayed(
          from_here, task_wrapper_.callback(),
          base::TimeDelta::FromMicroseconds(time_until_next_us))) {
    LOG(ERROR) << __func__
               << ": failed to post task to message loop for thread " << *thread
               << ", from " << from_here.ToString();
    task_wrapper_.Cancel();
    message_loop_thread_ = nullptr;
    delay_ = {};
    return false;
  }
  return true;
}

// This runs on user thread
void OnceTimer::Cancel() {
  std::promise<void> promise;
  CancelHelper(std::move(promise));
}

// This runs on user thread
void OnceTimer::CancelAndWait() {
  std::promise<void> promise;
  auto future = promise.get_future();
  CancelHelper(std::move(promise));
  future.wait();
}

// This runs on user thread
void OnceTimer::CancelHelper(std::promise<void> promise) {
  std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
  MessageLoopThread* scheduled_thread = message_loop_thread_.get();
  if (scheduled_thread == nullptr) {
    promise.set_value();
    return;
  }
  if (scheduled_thread->GetThreadId() == base::PlatformThread::CurrentId()) {
    CancelClosure(std::move(promise));
    return;
  }
  scheduled_thread->DoInThread(
      FROM_HERE, base::BindOnce(&OnceTimer::CancelClosure,
                                base::Unretained(this), std::move(promise)));
}

// This runs on message loop thread
void OnceTimer::CancelClosure(std::promise<void> promise) {
  message_loop_thread_ = nullptr;
  task_wrapper_.Cancel();
  std::move(task_);
  delay_ = base::TimeDelta();
  promise.set_value();
}

// This runs on user thread
bool OnceTimer::IsScheduled() const {
  std::lock_guard<std::recursive_mutex> api_lock(api_mutex_);
  return message_loop_thread_ != nullptr && message_loop_thread_->IsRunning();
}

// This runs on message loop thread
void OnceTimer::RunTask() {
  if (message_loop_thread_ == nullptr || !message_loop_thread_->IsRunning()) {
    LOG(ERROR) << __func__
               << ": message_loop_thread_ is null or is not running";
    return;
  }
  CHECK_EQ(message_loop_thread_->GetThreadId(),
           base::PlatformThread::CurrentId())
      << ": task must run on message loop thread";

  task_wrapper_.Cancel();
  std::move(task_).Run();
  message_loop_thread_ = nullptr;
}

}  // namespace common

}  // namespace bluetooth
Loading