/* * Copyright (C) 2020 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 "src/profiling/perf/unwind_queue.h" #include "test/gtest_and_gmock.h" namespace perfetto { namespace profiling { namespace { TEST(UnwindQueueTest, SinglePass) { static constexpr uint32_t kCapacity = 4; UnwindQueue queue; // write kCapacity entries for (int i = 0; i < static_cast(kCapacity); i++) { WriteView v = queue.BeginWrite(); ASSERT_TRUE(v.valid); queue.at(v.write_pos) = i; queue.CommitWrite(); } { // no more available capacity WriteView v = queue.BeginWrite(); ASSERT_FALSE(v.valid); } // reader sees all four writes ReadView v = queue.BeginRead(); ASSERT_EQ(v.read_pos, 0u); ASSERT_EQ(v.write_pos, 4u); std::vector read_back; for (auto pos = v.read_pos; pos < v.write_pos; pos++) { read_back.push_back(queue.at(pos)); } queue.CommitNewReadPosition(v.write_pos); ASSERT_THAT(read_back, ::testing::ElementsAre(0, 1, 2, 3)); // writer sees an available slot ASSERT_TRUE(queue.BeginWrite().valid); // reader caught up ASSERT_TRUE(queue.BeginRead().read_pos == queue.BeginRead().write_pos); } TEST(UnwindQueueTest, Wrapped) { static constexpr uint32_t kCapacity = 4; UnwindQueue queue; // write kCapacity entries for (int i = 0; i < static_cast(kCapacity); i++) { WriteView v = queue.BeginWrite(); ASSERT_TRUE(v.valid); queue.at(v.write_pos) = i; queue.CommitWrite(); } // no more available capacity ASSERT_FALSE(queue.BeginWrite().valid); { // consume 2 entries (partial read) ReadView v = queue.BeginRead(); ASSERT_EQ(v.read_pos, 0u); ASSERT_EQ(v.write_pos, 4u); queue.CommitNewReadPosition(v.read_pos + 2); } // write 2 more entries for (int i = 0; i < 2; i++) { WriteView v = queue.BeginWrite(); ASSERT_TRUE(v.valid); queue.at(v.write_pos) = 4 + i; queue.CommitWrite(); } // no more available capacity ASSERT_FALSE(queue.BeginWrite().valid); // read the remainder of the buffer ReadView v = queue.BeginRead(); ASSERT_EQ(v.read_pos, 2u); ASSERT_EQ(v.write_pos, 6u); std::vector read_back; for (auto pos = v.read_pos; pos < v.write_pos; pos++) { read_back.push_back(queue.at(pos)); } queue.CommitNewReadPosition(v.write_pos); ASSERT_THAT(read_back, ::testing::ElementsAre(2, 3, 4, 5)); // writer sees an available slot ASSERT_TRUE(queue.BeginWrite().valid); // reader caught up ASSERT_TRUE(queue.BeginRead().read_pos == queue.BeginRead().write_pos); } } // namespace } // namespace profiling } // namespace perfetto