blob: e906d59e22133d5dc5610dbe155cb4209ee4ddee [file] [log] [blame]
/*
* 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<int, kCapacity> queue;
// write kCapacity entries
for (int i = 0; i < static_cast<int>(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<int> 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<int, kCapacity> queue;
// write kCapacity entries
for (int i = 0; i < static_cast<int>(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<int> 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