Loading media/libaaudio/src/legacy/AudioStreamRecord.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -557,7 +557,7 @@ int64_t AudioStreamRecord::getFramesWritten() { case AAUDIO_STREAM_STATE_STARTED: case AAUDIO_STREAM_STATE_STARTED: result = mAudioRecord->getPosition(&position); result = mAudioRecord->getPosition(&position); if (result == OK) { if (result == OK) { mFramesWritten.update32(position); mFramesWritten.update32((int32_t)position); } } break; break; case AAUDIO_STREAM_STATE_STOPPING: case AAUDIO_STREAM_STATE_STOPPING: Loading media/libaaudio/src/legacy/AudioStreamTrack.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -508,7 +508,7 @@ int64_t AudioStreamTrack::getFramesRead() { case AAUDIO_STREAM_STATE_PAUSED: case AAUDIO_STREAM_STATE_PAUSED: result = mAudioTrack->getPosition(&position); result = mAudioTrack->getPosition(&position); if (result == OK) { if (result == OK) { mFramesRead.update32(position); mFramesRead.update32((int32_t)position); } } break; break; default: default: Loading media/libaaudio/src/utility/MonotonicCounter.h +8 −3 Original line number Original line Diff line number Diff line Loading @@ -41,7 +41,12 @@ public: } } /** /** * advance the current value to match the counter * Advance the current value to match the counter. * * Note that it will take several million years for the 64-bit * counters to wrap around. * So we do not use __builtin_sub_overflow. * We want to know if overflow happens because of a bug. */ */ void catchUpTo(int64_t counter) { void catchUpTo(int64_t counter) { if ((counter - mCounter64) > 0) { if ((counter - mCounter64) > 0) { Loading Loading @@ -74,7 +79,8 @@ public: * @return current value of the 64-bit counter * @return current value of the 64-bit counter */ */ int64_t update32(int32_t counter32) { int64_t update32(int32_t counter32) { int32_t delta = counter32 - mCounter32; int32_t delta; __builtin_sub_overflow(counter32, mCounter32, &delta); // protect against the mCounter64 going backwards // protect against the mCounter64 going backwards if (delta > 0) { if (delta > 0) { mCounter64 += delta; mCounter64 += delta; Loading Loading @@ -108,5 +114,4 @@ private: int32_t mCounter32 = 0; int32_t mCounter32 = 0; }; }; #endif //UTILITY_MONOTONIC_COUNTER_H #endif //UTILITY_MONOTONIC_COUNTER_H media/libaaudio/tests/Android.bp +17 −0 Original line number Original line Diff line number Diff line Loading @@ -13,6 +13,11 @@ cc_defaults { "-Wall", "-Wall", "-Werror", "-Werror", ], ], sanitize: { integer_overflow: true, misc_undefined: ["bounds"], }, } } cc_test { cc_test { Loading Loading @@ -146,6 +151,18 @@ cc_test { ], ], } } cc_test { name: "test_monotonic_counter", defaults: ["libaaudio_tests_defaults"], srcs: ["test_monotonic_counter.cpp"], shared_libs: [ "libaaudio_internal", "libbinder", "libcutils", "libutils", ], } cc_binary { cc_binary { name: "test_return_stop", name: "test_return_stop", defaults: ["libaaudio_tests_defaults"], defaults: ["libaaudio_tests_defaults"], Loading media/libaaudio/tests/test_monotonic_counter.cpp 0 → 100644 +91 −0 Original line number Original line Diff line number Diff line /* * Copyright 2022 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. */ /* * Test MonotonicCounter */ #include <iostream> #include <gtest/gtest.h> #include "utility/MonotonicCounter.h" TEST(test_monotonic_counter, builtin_wrap) { int32_t x = 0x7FFFFFF0; int32_t y = 0x80000010; int32_t delta; // delta = y - x; // This would cause a numeric overflow! __builtin_sub_overflow(y, x, &delta); ASSERT_EQ(0x20, delta); } // test updating past some overflow points TEST(test_monotonic_counter, mono_counter_update32_wrap) { MonotonicCounter counter; ASSERT_EQ(0, counter.get()); static constexpr uint32_t x = (uint32_t) 0x7FFFFFF0; counter.update32(x); ASSERT_EQ((int64_t)0x7FFFFFF0, counter.get()); static constexpr uint32_t y = (uint32_t) 0x80000010; counter.update32(y); ASSERT_EQ((int64_t)0x80000010, counter.get()); counter.update32(0); ASSERT_EQ((int64_t)0x100000000, counter.get()); } TEST(test_monotonic_counter, mono_counter_roundup) { MonotonicCounter counter; static constexpr uint32_t x = 2345; counter.update32(x); ASSERT_EQ((int64_t)x, counter.get()); counter.roundUp64(100); ASSERT_EQ((int64_t)2400, counter.get()); } TEST(test_monotonic_counter, mono_counter_catchup) { MonotonicCounter counter; counter.update32(7654); counter.catchUpTo(5000); // already past 5000 so no change ASSERT_EQ((int64_t)7654, counter.get()); counter.catchUpTo(9876); // jumps ASSERT_EQ((int64_t)9876, counter.get()); } TEST(test_monotonic_counter, mono_counter_increment) { MonotonicCounter counter; counter.update32(1000); counter.increment(-234); // will not go backwards ASSERT_EQ((int64_t)1000, counter.get()); counter.increment(96); // advances ASSERT_EQ((int64_t)1096, counter.get()); } TEST(test_monotonic_counter, mono_counter_reset) { MonotonicCounter counter; counter.update32(1000); // Counter is monotonic and should not go backwards. counter.update32(500); // No change because 32-bit counter is already past 1000. ASSERT_EQ((int64_t)1000, counter.get()); counter.reset32(); counter.update32(500); ASSERT_EQ((int64_t)1500, counter.get()); } Loading
media/libaaudio/src/legacy/AudioStreamRecord.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -557,7 +557,7 @@ int64_t AudioStreamRecord::getFramesWritten() { case AAUDIO_STREAM_STATE_STARTED: case AAUDIO_STREAM_STATE_STARTED: result = mAudioRecord->getPosition(&position); result = mAudioRecord->getPosition(&position); if (result == OK) { if (result == OK) { mFramesWritten.update32(position); mFramesWritten.update32((int32_t)position); } } break; break; case AAUDIO_STREAM_STATE_STOPPING: case AAUDIO_STREAM_STATE_STOPPING: Loading
media/libaaudio/src/legacy/AudioStreamTrack.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -508,7 +508,7 @@ int64_t AudioStreamTrack::getFramesRead() { case AAUDIO_STREAM_STATE_PAUSED: case AAUDIO_STREAM_STATE_PAUSED: result = mAudioTrack->getPosition(&position); result = mAudioTrack->getPosition(&position); if (result == OK) { if (result == OK) { mFramesRead.update32(position); mFramesRead.update32((int32_t)position); } } break; break; default: default: Loading
media/libaaudio/src/utility/MonotonicCounter.h +8 −3 Original line number Original line Diff line number Diff line Loading @@ -41,7 +41,12 @@ public: } } /** /** * advance the current value to match the counter * Advance the current value to match the counter. * * Note that it will take several million years for the 64-bit * counters to wrap around. * So we do not use __builtin_sub_overflow. * We want to know if overflow happens because of a bug. */ */ void catchUpTo(int64_t counter) { void catchUpTo(int64_t counter) { if ((counter - mCounter64) > 0) { if ((counter - mCounter64) > 0) { Loading Loading @@ -74,7 +79,8 @@ public: * @return current value of the 64-bit counter * @return current value of the 64-bit counter */ */ int64_t update32(int32_t counter32) { int64_t update32(int32_t counter32) { int32_t delta = counter32 - mCounter32; int32_t delta; __builtin_sub_overflow(counter32, mCounter32, &delta); // protect against the mCounter64 going backwards // protect against the mCounter64 going backwards if (delta > 0) { if (delta > 0) { mCounter64 += delta; mCounter64 += delta; Loading Loading @@ -108,5 +114,4 @@ private: int32_t mCounter32 = 0; int32_t mCounter32 = 0; }; }; #endif //UTILITY_MONOTONIC_COUNTER_H #endif //UTILITY_MONOTONIC_COUNTER_H
media/libaaudio/tests/Android.bp +17 −0 Original line number Original line Diff line number Diff line Loading @@ -13,6 +13,11 @@ cc_defaults { "-Wall", "-Wall", "-Werror", "-Werror", ], ], sanitize: { integer_overflow: true, misc_undefined: ["bounds"], }, } } cc_test { cc_test { Loading Loading @@ -146,6 +151,18 @@ cc_test { ], ], } } cc_test { name: "test_monotonic_counter", defaults: ["libaaudio_tests_defaults"], srcs: ["test_monotonic_counter.cpp"], shared_libs: [ "libaaudio_internal", "libbinder", "libcutils", "libutils", ], } cc_binary { cc_binary { name: "test_return_stop", name: "test_return_stop", defaults: ["libaaudio_tests_defaults"], defaults: ["libaaudio_tests_defaults"], Loading
media/libaaudio/tests/test_monotonic_counter.cpp 0 → 100644 +91 −0 Original line number Original line Diff line number Diff line /* * Copyright 2022 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. */ /* * Test MonotonicCounter */ #include <iostream> #include <gtest/gtest.h> #include "utility/MonotonicCounter.h" TEST(test_monotonic_counter, builtin_wrap) { int32_t x = 0x7FFFFFF0; int32_t y = 0x80000010; int32_t delta; // delta = y - x; // This would cause a numeric overflow! __builtin_sub_overflow(y, x, &delta); ASSERT_EQ(0x20, delta); } // test updating past some overflow points TEST(test_monotonic_counter, mono_counter_update32_wrap) { MonotonicCounter counter; ASSERT_EQ(0, counter.get()); static constexpr uint32_t x = (uint32_t) 0x7FFFFFF0; counter.update32(x); ASSERT_EQ((int64_t)0x7FFFFFF0, counter.get()); static constexpr uint32_t y = (uint32_t) 0x80000010; counter.update32(y); ASSERT_EQ((int64_t)0x80000010, counter.get()); counter.update32(0); ASSERT_EQ((int64_t)0x100000000, counter.get()); } TEST(test_monotonic_counter, mono_counter_roundup) { MonotonicCounter counter; static constexpr uint32_t x = 2345; counter.update32(x); ASSERT_EQ((int64_t)x, counter.get()); counter.roundUp64(100); ASSERT_EQ((int64_t)2400, counter.get()); } TEST(test_monotonic_counter, mono_counter_catchup) { MonotonicCounter counter; counter.update32(7654); counter.catchUpTo(5000); // already past 5000 so no change ASSERT_EQ((int64_t)7654, counter.get()); counter.catchUpTo(9876); // jumps ASSERT_EQ((int64_t)9876, counter.get()); } TEST(test_monotonic_counter, mono_counter_increment) { MonotonicCounter counter; counter.update32(1000); counter.increment(-234); // will not go backwards ASSERT_EQ((int64_t)1000, counter.get()); counter.increment(96); // advances ASSERT_EQ((int64_t)1096, counter.get()); } TEST(test_monotonic_counter, mono_counter_reset) { MonotonicCounter counter; counter.update32(1000); // Counter is monotonic and should not go backwards. counter.update32(500); // No change because 32-bit counter is already past 1000. ASSERT_EQ((int64_t)1000, counter.get()); counter.reset32(); counter.update32(500); ASSERT_EQ((int64_t)1500, counter.get()); }