• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/profiling/perf/unwind_queue.h"
18 
19 #include "test/gtest_and_gmock.h"
20 
21 namespace perfetto {
22 namespace profiling {
23 namespace {
24 
TEST(UnwindQueueTest,SinglePass)25 TEST(UnwindQueueTest, SinglePass) {
26   static constexpr uint32_t kCapacity = 4;
27   UnwindQueue<int, kCapacity> queue;
28 
29   // write kCapacity entries
30   for (int i = 0; i < static_cast<int>(kCapacity); i++) {
31     WriteView v = queue.BeginWrite();
32     ASSERT_TRUE(v.valid);
33     queue.at(v.write_pos) = i;
34     queue.CommitWrite();
35   }
36   {
37     // no more available capacity
38     WriteView v = queue.BeginWrite();
39     ASSERT_FALSE(v.valid);
40   }
41 
42   // reader sees all four writes
43   ReadView v = queue.BeginRead();
44   ASSERT_EQ(v.read_pos, 0u);
45   ASSERT_EQ(v.write_pos, 4u);
46 
47   std::vector<int> read_back;
48   for (auto pos = v.read_pos; pos < v.write_pos; pos++) {
49     read_back.push_back(queue.at(pos));
50   }
51   queue.CommitNewReadPosition(v.write_pos);
52 
53   ASSERT_THAT(read_back, ::testing::ElementsAre(0, 1, 2, 3));
54 
55   // writer sees an available slot
56   ASSERT_TRUE(queue.BeginWrite().valid);
57   // reader caught up
58   ASSERT_TRUE(queue.BeginRead().read_pos == queue.BeginRead().write_pos);
59 }
60 
TEST(UnwindQueueTest,Wrapped)61 TEST(UnwindQueueTest, Wrapped) {
62   static constexpr uint32_t kCapacity = 4;
63   UnwindQueue<int, kCapacity> queue;
64 
65   // write kCapacity entries
66   for (int i = 0; i < static_cast<int>(kCapacity); i++) {
67     WriteView v = queue.BeginWrite();
68     ASSERT_TRUE(v.valid);
69     queue.at(v.write_pos) = i;
70     queue.CommitWrite();
71   }
72 
73   // no more available capacity
74   ASSERT_FALSE(queue.BeginWrite().valid);
75 
76   {
77     // consume 2 entries (partial read)
78     ReadView v = queue.BeginRead();
79     ASSERT_EQ(v.read_pos, 0u);
80     ASSERT_EQ(v.write_pos, 4u);
81     queue.CommitNewReadPosition(v.read_pos + 2);
82   }
83 
84   // write 2 more entries
85   for (int i = 0; i < 2; i++) {
86     WriteView v = queue.BeginWrite();
87     ASSERT_TRUE(v.valid);
88     queue.at(v.write_pos) = 4 + i;
89     queue.CommitWrite();
90   }
91 
92   // no more available capacity
93   ASSERT_FALSE(queue.BeginWrite().valid);
94 
95   // read the remainder of the buffer
96   ReadView v = queue.BeginRead();
97   ASSERT_EQ(v.read_pos, 2u);
98   ASSERT_EQ(v.write_pos, 6u);
99 
100   std::vector<int> read_back;
101   for (auto pos = v.read_pos; pos < v.write_pos; pos++) {
102     read_back.push_back(queue.at(pos));
103   }
104   queue.CommitNewReadPosition(v.write_pos);
105 
106   ASSERT_THAT(read_back, ::testing::ElementsAre(2, 3, 4, 5));
107 
108   // writer sees an available slot
109   ASSERT_TRUE(queue.BeginWrite().valid);
110   // reader caught up
111   ASSERT_TRUE(queue.BeginRead().read_pos == queue.BeginRead().write_pos);
112 }
113 
114 }  // namespace
115 }  // namespace profiling
116 }  // namespace perfetto
117