diff options
| author | 2022-09-13 09:29:14 +0000 | |
|---|---|---|
| committer | 2022-09-15 06:54:17 +0000 | |
| commit | 9bca81c8b9ede39e721dbf2cab4f58b0176f38ab (patch) | |
| tree | 8dfe6de5f19b471e65867c033b18bd582f08bd4b | |
| parent | de31b5a2b4dae9973e9946470f02fec9d6a64545 (diff) | |
Floss: use CLOCK_MONOTONIC_RAW in A2DP encoding for TARGET_FLOSS
Floss uses CLOCK_MONOTONIC and CLOCK_BOOTTIME for various timestamp and
timediff calculation.
This causes glitches when the audio stack calculates timestamp and
schedules with CLOCK_MONOTONIC_RAW.
In this CL, we swap out the clock used in scheduling A2DP packet
encoding to use CLOCK_MONOTONIC_RAW when the build is targeted to Floss.
Note that we intentionally leave the timestamps in metrics/stats
untouched since they have different purposes (e.g., allowing to match
with other timestamps across applications).
Bug: 241816575
Tag: #floss
Test: Build and verify A2DP doesn't glitch
Change-Id: I275208e33285282911c49caa599cbb14a810bfa9
| -rw-r--r-- | system/btif/src/btif_a2dp_source.cc | 11 | ||||
| -rw-r--r-- | system/common/time_util.cc | 9 | ||||
| -rw-r--r-- | system/common/time_util.h | 2 | ||||
| -rw-r--r-- | system/common/time_util_unittest.cc | 46 | ||||
| -rw-r--r-- | system/test/mock/mock_common_time_util.cc | 4 |
5 files changed, 67 insertions, 5 deletions
diff --git a/system/btif/src/btif_a2dp_source.cc b/system/btif/src/btif_a2dp_source.cc index f13abac71a..55f46dd31c 100644 --- a/system/btif/src/btif_a2dp_source.cc +++ b/system/btif/src/btif_a2dp_source.cc @@ -895,8 +895,15 @@ static void btif_a2dp_source_audio_tx_stop_event(void) { static void btif_a2dp_source_audio_handle_timer(void) { if (btif_av_is_a2dp_offload_running()) return; +#ifndef TARGET_FLOSS uint64_t timestamp_us = bluetooth::common::time_get_os_boottime_us(); - log_tstamps_us("A2DP Source tx timer", timestamp_us); + uint64_t stats_timestamp_us = timestamp_us; +#else + uint64_t timestamp_us = bluetooth::common::time_get_os_monotonic_raw_us(); + uint64_t stats_timestamp_us = bluetooth::common::time_get_os_boottime_us(); +#endif + + log_tstamps_us("A2DP Source tx scheduling timer", timestamp_us); if (!btif_a2dp_source_cb.media_alarm.IsScheduled()) { LOG_ERROR("%s: ERROR Media task Scheduled after Suspend", __func__); @@ -916,7 +923,7 @@ static void btif_a2dp_source_audio_handle_timer(void) { btif_a2dp_source_cb.encoder_interface->send_frames(timestamp_us); bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO); update_scheduling_stats(&btif_a2dp_source_cb.stats.tx_queue_enqueue_stats, - timestamp_us, + stats_timestamp_us, btif_a2dp_source_cb.encoder_interval_ms * 1000); } diff --git a/system/common/time_util.cc b/system/common/time_util.cc index 273be181d0..d77c17c0c8 100644 --- a/system/common/time_util.cc +++ b/system/common/time_util.cc @@ -42,6 +42,13 @@ uint64_t time_gettimeofday_us() { static_cast<uint64_t>(tv.tv_usec); } +uint64_t time_get_os_monotonic_raw_us() { + struct timespec ts_now = {}; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts_now); + + return ((uint64_t)ts_now.tv_sec * 1000000L) + + ((uint64_t)ts_now.tv_nsec / 1000); +} } // namespace common -} // namespace bluetooth
\ No newline at end of file +} // namespace bluetooth diff --git a/system/common/time_util.h b/system/common/time_util.h index 70a64d2cba..16808135c3 100644 --- a/system/common/time_util.h +++ b/system/common/time_util.h @@ -33,6 +33,8 @@ uint64_t time_get_os_boottime_us(); // Get the current wall clock time in microseconds. uint64_t time_gettimeofday_us(); +// Get the OS monotonic raw time in microseconds. +uint64_t time_get_os_monotonic_raw_us(); } // namespace common } // namespace bluetooth diff --git a/system/common/time_util_unittest.cc b/system/common/time_util_unittest.cc index 77e205d3a6..eb21aee5ad 100644 --- a/system/common/time_util_unittest.cc +++ b/system/common/time_util_unittest.cc @@ -42,8 +42,17 @@ TEST(TimeTest, test_time_get_os_boottime_us_not_zero) { } // +// Test that the return value of +// bluetooth::common::time_get_os_monotonic_raw_us() is not zero. +// +TEST(TimeTest, test_time_get_os_monotonic_raw_us_not_zero) { + uint64_t t1 = bluetooth::common::time_get_os_monotonic_raw_us(); + ASSERT_GT(t1, uint64_t(0)); +} + +// // Test that the return value of bluetooth::common::time_get_os_boottime_ms() -// is monotonically increasing within reasonable boundries. +// is monotonically increasing within reasonable boundaries. // TEST(TimeTest, test_time_get_os_boottime_ms_increases_upper_bound) { uint64_t t1 = bluetooth::common::time_get_os_boottime_ms(); @@ -53,7 +62,7 @@ TEST(TimeTest, test_time_get_os_boottime_ms_increases_upper_bound) { // // Test that the return value of bluetooth::common::time_get_os_boottime_us() -// is monotonically increasing within reasonable boundries. +// is monotonically increasing within reasonable boundaries. // TEST(TimeTest, test_time_get_os_boottime_us_increases_upper_bound) { uint64_t t1 = bluetooth::common::time_get_os_boottime_us(); @@ -62,6 +71,17 @@ TEST(TimeTest, test_time_get_os_boottime_us_increases_upper_bound) { } // +// Test that the return value of +// bluetooth::common::time_get_os_monotonic_raw_us() is monotonically increasing +// within reasonable boundaries. +// +TEST(TimeTest, test_time_get_os_monotonic_raw_time_us_increases_upper_bound) { + uint64_t t1 = bluetooth::common::time_get_os_monotonic_raw_us(); + uint64_t t2 = bluetooth::common::time_get_os_monotonic_raw_us(); + ASSERT_TRUE((t2 - t1) < TEST_TIME_DELTA_UPPER_BOUND_MS * 1000); +} + +// // Test that the return value of bluetooth::common::time_get_os_boottime_ms() // is increasing. // @@ -105,6 +125,28 @@ TEST(TimeTest, test_time_get_os_boottime_us_increases_lower_bound) { } // +// Test that the return value of +// bluetooth::common::time_get_os_monotonic_raw_us() is increasing. +// +TEST(TimeTest, test_time_get_os_monotonic_raw_us_increases_lower_bound) { + static const uint64_t TEST_TIME_SLEEP_US = 100 * 1000; + struct timespec delay = {}; + + delay.tv_sec = TEST_TIME_SLEEP_US / (1000 * 1000); + delay.tv_nsec = 1000 * (TEST_TIME_SLEEP_US % (1000 * 1000)); + + // Take two timestamps with sleep in-between + uint64_t t1 = bluetooth::common::time_get_os_monotonic_raw_us(); + int err = nanosleep(&delay, &delay); + uint64_t t2 = bluetooth::common::time_get_os_monotonic_raw_us(); + + ASSERT_EQ(err, 0); + ASSERT_GT(t2, t1); + ASSERT_TRUE((t2 - t1) >= TEST_TIME_SLEEP_US); + ASSERT_TRUE((t2 - t1) < TEST_TIME_DELTA_UPPER_BOUND_MS * 1000); +} + +// // Test that the return value of bluetooth::common::time_gettimeofday_us() is // not zero. // diff --git a/system/test/mock/mock_common_time_util.cc b/system/test/mock/mock_common_time_util.cc index e29368e8bb..7a9c4d6a13 100644 --- a/system/test/mock/mock_common_time_util.cc +++ b/system/test/mock/mock_common_time_util.cc @@ -47,6 +47,10 @@ uint64_t time_gettimeofday_us() { mock_function_count_map[__func__]++; return 0; } +uint64_t time_get_os_monotonic_raw_us() { + mock_function_count_map[__func__]++; + return 0; +} } // namespace common } // namespace bluetooth |