• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "aemu/base/AlignedBuf.h"
16 #include "aemu/base/ArraySize.h"
17 
18 #include <gtest/gtest.h>
19 
20 #include <vector>
21 #include <array>
22 
23 using android::AlignedBuf;
24 using android::base::arraySize;
25 using android::aligned_buf_alloc;
26 using android::aligned_buf_free;
27 
checkAligned(size_t align,void * ptr)28 static void checkAligned(size_t align, void* ptr) {
29     uintptr_t ptrVal = reinterpret_cast<uintptr_t>(ptr);
30     EXPECT_EQ(0, ptrVal & (align - 1));
31 }
32 
TEST(AlignedBuf,Basic)33 TEST(AlignedBuf, Basic) {
34     const int numItems = 10;
35 
36     // Check that the buffers are aligned
37     {
38         AlignedBuf<uint32_t, 64> buf(numItems);
39         checkAligned(64, buf.data());
40         EXPECT_EQ(numItems, buf.size());
41     }
42 
43     {
44         AlignedBuf<uint32_t, 256> buf(numItems);
45         checkAligned(256, buf.data());
46         EXPECT_EQ(numItems, buf.size());
47     }
48 
49     {
50         AlignedBuf<uint32_t, 4096> buf(numItems);
51         checkAligned(4096, buf.data());
52         EXPECT_EQ(numItems, buf.size());
53     }
54 
55     const int numManyItems = 100;
56     const int numFewItems = 4;
57 
58     // Test read/write
59     AlignedBuf<uint32_t, 64> buf(numManyItems);
60     uint32_t* bufData = buf.data();
61     for (int i = 0; i < numManyItems; i++) {
62         bufData[i] = 0;
63         EXPECT_EQ(0, bufData[i]);
64     }
65 
66     AlignedBuf<uint32_t, 64> buf2(numFewItems);
67     bufData = buf2.data();
68     for (int i = 0; i < numFewItems; i++) {
69         bufData[i] = 0;
70         EXPECT_EQ(0, bufData[i]);
71     }
72 }
73 
74 // Tests that copy constructor copies underlying buffer.
TEST(AlignedBuf,Copy)75 TEST(AlignedBuf, Copy) {
76     constexpr int align = 64;
77     constexpr int size = 128;
78 
79     AlignedBuf<uint32_t, align> buf(size);
80     AlignedBuf<uint32_t, align> buf2 = buf;
81 
82     EXPECT_EQ(buf2.size(), buf.size());
83     EXPECT_NE(buf2.data(), buf.data());
84 
85     for (int i = 0; i < buf.size(); i++) {
86         buf[i] = 0;
87     }
88 
89     for (int i = 0; i < buf2.size(); i++) {
90         buf2[i] = 1;
91     }
92 
93     for (int i = 0; i < buf.size(); i++) {
94         EXPECT_EQ(0, buf[i]);
95     }
96 }
97 
98 // Tests that move constructor preserves underlying buffer.
TEST(AlignedBuf,Move)99 TEST(AlignedBuf, Move) {
100     constexpr int align = 64;
101     constexpr int size = 128;
102 
103     AlignedBuf<uint32_t, align> buf(size);
104 
105     for (int i = 0; i < buf.size(); i++) {
106         buf[i] = 0;
107         EXPECT_EQ(0, buf[i]);
108     }
109 
110     AlignedBuf<uint32_t, align> buf2 = std::move(buf);
111 
112     EXPECT_EQ(0, buf.size());
113     EXPECT_EQ(size, buf2.size());
114 
115     for (int i = 0; i < buf2.size(); i++) {
116         EXPECT_EQ(0, buf2[i]);
117         // Check that it is stil writable.
118         buf2[i] = 0;
119     }
120 }
121 
122 // Tests that operator== is comparing raw bytes.
TEST(AlignedBuf,Compare)123 TEST(AlignedBuf, Compare) {
124     constexpr int align = 64;
125     constexpr int size = 128;
126 
127     AlignedBuf<uint32_t, align> buf(size);
128     AlignedBuf<uint32_t, align> buf2 = buf;
129 
130     EXPECT_EQ(buf, buf2);
131 }
132 
133 // Tests that resize preserves contents.
TEST(AlignedBuf,Resize)134 TEST(AlignedBuf, Resize) {
135     std::array<char, 4> contents = { 0xa, 0xb, 0xc, 0xd };
136     size_t initialSize = contents.size();
137     AlignedBuf<char, 4096> buf(initialSize);
138 
139     auto check = [&]() {
140         for (size_t i = 0; i < initialSize; i++) {
141             EXPECT_EQ(contents[i], buf[i]);
142         }
143     };
144 
145     memcpy(buf.data(), contents.data(), initialSize);
146     check();
147 
148     for (size_t i = 0; i < 10; i++) {
149         buf.resize(initialSize + i * 4096);
150         check();
151     }
152 }
153 
154 // Tests raw aligned alloc.
TEST(AlignedBuf,Raw)155 TEST(AlignedBuf, Raw) {
156     constexpr size_t alignmentsToTest[] = {
157         1, 2, 4, 8, 16, 256, 1024, 4096,
158     };
159     constexpr size_t sizesToTest[] = {
160         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
161         16, 17, 256, 400, 500, 4000, 4096,
162     };
163 
164     size_t numAlignmentCases = arraySize(alignmentsToTest);
165     size_t numSizeCases = arraySize(sizesToTest);
166 
167     for (size_t i = 0; i < numAlignmentCases; ++i) {
168         for (size_t j = 0; j < numSizeCases; ++j) {
169             void* buf = aligned_buf_alloc(alignmentsToTest[i], sizesToTest[j]);
170             EXPECT_NE(nullptr, buf);
171             checkAligned(alignmentsToTest[i], buf);
172             aligned_buf_free(buf);
173         }
174     }
175 }
176