gem5  v22.1.0.0
chunk_generator.test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 The Regents of the University of California
3  * All rights reserved
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <gtest/gtest.h>
30 
31 #include "chunk_generator.hh"
32 
33 using namespace gem5;
34 
35 /*
36  * A test to ensure the object is in a sane state after initialization.
37  */
38 TEST(ChunkGeneratorTest, StartingConditions)
39 {
40  ChunkGenerator chunk_generator(0, 1024, 8);
41  EXPECT_EQ(0, chunk_generator.addr());
42  EXPECT_EQ(8, chunk_generator.size());
43  EXPECT_EQ(0, chunk_generator.complete());
44  EXPECT_FALSE(chunk_generator.done());
45  EXPECT_FALSE(chunk_generator.last());
46 }
47 
48 /*
49  * A simple test to check the move to the next chunk under normal conditions.
50  */
51 TEST(ChunkGeneratorTest, AdvanceToNextChunk)
52 {
53  ChunkGenerator chunk_generator(0, 1024, 8);
54  EXPECT_EQ(0, chunk_generator.addr());
55  EXPECT_TRUE(chunk_generator.next());
56  EXPECT_EQ(8, chunk_generator.addr());
57  EXPECT_EQ(8, chunk_generator.size());
58  EXPECT_EQ(8, chunk_generator.complete());
59  EXPECT_FALSE(chunk_generator.done());
60  EXPECT_FALSE(chunk_generator.last());
61 }
62 
63 /*
64  * A test to check skipping over bytes.
65  */
66 TEST(ChunkGeneratorTest, SkipBytes)
67 {
68  ChunkGenerator chunk_generator(0, 1024, 8);
69  EXPECT_EQ(0, chunk_generator.addr());
70  EXPECT_TRUE(chunk_generator.next());
71  EXPECT_EQ(8, chunk_generator.addr());
72 
73  chunk_generator.setNext(23);
74  EXPECT_EQ(23 - 8, chunk_generator.size());
75  EXPECT_TRUE(chunk_generator.next());
76  EXPECT_EQ(23, chunk_generator.addr());
77  EXPECT_EQ(1, chunk_generator.size());
78  EXPECT_TRUE(chunk_generator.next());
79  EXPECT_EQ(24, chunk_generator.addr());
80  EXPECT_EQ(8, chunk_generator.size());
81 
82  chunk_generator.setNext(32);
83  EXPECT_EQ(32 - 24, chunk_generator.size());
84  EXPECT_TRUE(chunk_generator.next());
85  EXPECT_EQ(32, chunk_generator.addr());
86  EXPECT_EQ(8, chunk_generator.size());
87 
88  chunk_generator.setNext(64);
89  EXPECT_EQ(64 - 32, chunk_generator.size());
90  EXPECT_TRUE(chunk_generator.next());
91  EXPECT_EQ(64, chunk_generator.addr());
92  EXPECT_EQ(8, chunk_generator.size());
93 
94  chunk_generator.setNext(2048);
95  EXPECT_EQ(1024 - 64, chunk_generator.size());
96  EXPECT_TRUE(chunk_generator.last());
97  EXPECT_FALSE(chunk_generator.next());
98  EXPECT_TRUE(chunk_generator.done());
99 }
100 
101 /*
102  * A test to consume chunks until the last chunk.
103  */
104 TEST(ChunkGeneratorTest, AdvanceToLastChunk)
105 {
106  ChunkGenerator chunk_generator(0, 32, 8);
107  EXPECT_EQ(0, chunk_generator.addr());
108  EXPECT_TRUE(chunk_generator.next());
109  EXPECT_EQ(8, chunk_generator.addr());
110  EXPECT_TRUE(chunk_generator.next());
111  EXPECT_EQ(16, chunk_generator.addr());
112  EXPECT_TRUE(chunk_generator.next());
113  EXPECT_EQ(24, chunk_generator.addr());
114  EXPECT_EQ(8, chunk_generator.size());
115  EXPECT_EQ(24, chunk_generator.complete());
116  EXPECT_FALSE(chunk_generator.done());
117  EXPECT_TRUE(chunk_generator.last());
118 }
119 
120 /*
121  * A test to consume chunks, inclusive of the last chunk.
122  */
123 TEST(ChunkGeneratorTest, AdvanceToTheEnd)
124 {
125  ChunkGenerator chunk_generator(0, 32, 8);
126  EXPECT_EQ(0, chunk_generator.addr());
127  EXPECT_TRUE(chunk_generator.next());
128  EXPECT_EQ(8, chunk_generator.addr());
129  EXPECT_TRUE(chunk_generator.next());
130  EXPECT_EQ(16, chunk_generator.addr());
131  EXPECT_TRUE(chunk_generator.next());
132  EXPECT_EQ(24, chunk_generator.addr());
133  /* The following returns false because we cannot advance to the next to
134  * the next chunk (it does not exist). However, we still process the last
135  * chunk. It is therefore not indicative of failure to change the
136  * state of the object.
137  */
138  EXPECT_FALSE(chunk_generator.next());
139  EXPECT_EQ(24, chunk_generator.addr());
140  EXPECT_EQ(0, chunk_generator.size());
141  EXPECT_EQ(24, chunk_generator.complete());
142  EXPECT_TRUE(chunk_generator.done());
143  EXPECT_TRUE(chunk_generator.last());
144 }
145 
146 /*
147  * A region does is not necessisarily divisable by the chunk size. This will
148  * will result in the final chunk being smaller than the rest.
149  */
150 TEST(ChunkGeneratorTest, SmallerLastChunk)
151 {
152  // There are two chunks. The last will be 6 bytes.
153  ChunkGenerator chunk_generator(0, 14, 8);
154  EXPECT_EQ(0, chunk_generator.addr());
155  EXPECT_TRUE(chunk_generator.next());
156  EXPECT_EQ(8, chunk_generator.addr());
157  EXPECT_EQ(6, chunk_generator.size());
158  EXPECT_EQ(8, chunk_generator.complete());
159  EXPECT_FALSE(chunk_generator.done());
160  EXPECT_TRUE(chunk_generator.last());
161 }
162 
163 /*
164  * When a chunk size is greater than the total size, the chunk size
165  * is effectively that of the region size. This test will verify this
166  * corner-case.
167  */
168 TEST(ChunkGeneratorTest, ChunkSizeGreaterThanTotalSize)
169 {
170  ChunkGenerator chunk_generator(0, 32, 64);
171  EXPECT_EQ(0, chunk_generator.addr());
172  EXPECT_EQ(32, chunk_generator.size());
173  EXPECT_EQ(0, chunk_generator.complete());
174  EXPECT_FALSE(chunk_generator.done());
175  EXPECT_TRUE(chunk_generator.last());
176 
177  // Process the entire region.
178  EXPECT_FALSE(chunk_generator.next());
179  EXPECT_EQ(0, chunk_generator.addr());
180  EXPECT_EQ(0, chunk_generator.size());
181  EXPECT_EQ(0, chunk_generator.complete());
182  EXPECT_TRUE(chunk_generator.done());
183  EXPECT_TRUE(chunk_generator.last());
184 }
185 
186 /*
187  * As a special case, we assume there is no chunking when the chunk size is
188  * zero. Processing a chunk (i.e., execution of "next()"). should progress to
189  * the end of the region.
190  */
191 TEST(ChunkGeneratorTest, ChunkSizeZero)
192 {
193  ChunkGenerator chunk_generator(0, 64, 0);
194  EXPECT_EQ(0, chunk_generator.addr());
195  EXPECT_EQ(64, chunk_generator.size());
196  EXPECT_EQ(0, chunk_generator.complete());
197  EXPECT_FALSE(chunk_generator.done());
198  EXPECT_TRUE(chunk_generator.last());
199 
200  //Process the entire region.
201  EXPECT_FALSE(chunk_generator.next());
202  EXPECT_EQ(0, chunk_generator.addr());
203  EXPECT_EQ(0, chunk_generator.size());
204  EXPECT_EQ(0, chunk_generator.complete());
205  EXPECT_TRUE(chunk_generator.done());
206  EXPECT_TRUE(chunk_generator.last());
207 }
208 
209 /*
210  * A test to ensure a non-zero start functions correctly.
211  */
212 TEST(ChunkGeneratorTest, StartAtNonZero)
213 {
214  ChunkGenerator chunk_generator(4, 32, 8); //End address: 36.
215  EXPECT_EQ(4, chunk_generator.addr());
216  EXPECT_EQ(4, chunk_generator.size());
217  EXPECT_EQ(0, chunk_generator.complete());
218  EXPECT_FALSE(chunk_generator.done());
219  EXPECT_FALSE(chunk_generator.last());
220 
221  /*
222  * As the starting position is 4, moving to the next bit should move to
223  * 8 (i.e., process the remainder of the first chunk in the region).
224  */
225  EXPECT_TRUE(chunk_generator.next());
226  EXPECT_EQ(8, chunk_generator.addr());
227  EXPECT_EQ(8, chunk_generator.size());
228  EXPECT_EQ(4, chunk_generator.complete());
229  EXPECT_FALSE(chunk_generator.done());
230  EXPECT_FALSE(chunk_generator.last());
231 
232  // Process the rest of the region.
233  EXPECT_TRUE(chunk_generator.next());
234  EXPECT_EQ(16, chunk_generator.addr());
235  EXPECT_EQ(8, chunk_generator.size());
236  EXPECT_EQ(12, chunk_generator.complete());
237  EXPECT_FALSE(chunk_generator.done());
238  EXPECT_FALSE(chunk_generator.last());
239 
240  EXPECT_TRUE(chunk_generator.next());
241  EXPECT_EQ(24, chunk_generator.addr());
242  EXPECT_EQ(8, chunk_generator.size());
243  EXPECT_EQ(20, chunk_generator.complete());
244  EXPECT_FALSE(chunk_generator.done());
245  EXPECT_FALSE(chunk_generator.last());
246 
247  // The last chunk is also only 4 bytes.
248  EXPECT_TRUE(chunk_generator.next());
249  EXPECT_EQ(32, chunk_generator.addr());
250  EXPECT_EQ(4, chunk_generator.size());
251  EXPECT_EQ(28, chunk_generator.complete());
252  EXPECT_FALSE(chunk_generator.done());
253  EXPECT_TRUE(chunk_generator.last());
254 
255  EXPECT_FALSE(chunk_generator.next());
256  EXPECT_EQ(32, chunk_generator.addr());
257  EXPECT_EQ(0, chunk_generator.size());
258  EXPECT_EQ(28, chunk_generator.complete());
259  EXPECT_TRUE(chunk_generator.done());
260  EXPECT_TRUE(chunk_generator.last());
261 }
Declaration and inline definition of ChunkGenerator object.
TEST(ChunkGeneratorTest, StartingConditions)
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
bool last() const
Is this the last chunk?
Addr addr() const
Return starting address of current chunk.
Addr complete() const
Number of bytes we have already chunked up.
void setNext(Addr next)
Grow this chunk to cover additional bytes which are already handled.
bool done() const
Are we done? That is, did the last call to next() advance past the end of the region?
Addr size() const
Return size in bytes of current chunk.
bool next()
Advance generator to next chunk.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....

Generated on Wed Dec 21 2022 10:22:28 for gem5 by doxygen 1.9.1