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