arch-arm,cpu: Introduce a getEMI virtual method on StaticInst.
[gem5.git] / src / base / circlebuf.test.cc
1 /*
2 * Copyright (c) 2015, 2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #include <gmock/gmock.h>
39 #include <gtest/gtest.h>
40
41 #include <vector>
42
43 #include "base/circlebuf.hh"
44
45 using testing::ElementsAreArray;
46
47 const char data[] = {
48 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
49 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
50 };
51
52 // A better way to implement this would be with std::span, but that is only
53 // available starting in c++20.
54 template <typename T>
55 std::vector<T>
56 subArr(T *arr, int size, int offset=0)
57 {
58 return std::vector<T>(arr + offset, arr + offset + size);
59 }
60
61 // Basic non-overflow functionality
62 TEST(CircleBufTest, BasicReadWriteNoOverflow)
63 {
64 CircleBuf<char> buf(8);
65 char foo[16];
66
67 // Write empty buffer, no overflow
68 buf.write(data, 8);
69 EXPECT_EQ(buf.size(), 8);
70 buf.peek(foo, 8);
71 EXPECT_THAT(subArr(foo, 8), ElementsAreArray(data, 8));
72
73 // Read 2
74 buf.read(foo, 2);
75 EXPECT_THAT(subArr(foo, 2), ElementsAreArray(data, 2));
76 EXPECT_EQ(buf.size(), 6);
77 buf.read(foo, 6);
78 EXPECT_THAT(subArr(foo, 6), ElementsAreArray(data + 2, 6));
79 EXPECT_EQ(buf.size(), 0);
80 }
81
82 // Basic single write overflow functionality
83 TEST(CircleBufTest, SingleWriteOverflow)
84 {
85 CircleBuf<char> buf(8);
86 char foo[16];
87
88 buf.write(data, 16);
89 EXPECT_EQ(buf.size(), 8);
90 buf.peek(foo, 8);
91 EXPECT_THAT(subArr(foo, 8), ElementsAreArray(data + 8, 8));
92 }
93
94
95 // Multi-write overflow functionality
96 TEST(CircleBufTest, MultiWriteOverflow)
97 {
98 CircleBuf<char> buf(8);
99 char foo[16];
100
101 // Write, no overflow, write overflow
102 buf.write(data, 6);
103 buf.write(data + 8, 6);
104 EXPECT_EQ(buf.size(), 8);
105 buf.peek(foo, 8);
106 EXPECT_THAT(subArr(foo, 2), ElementsAreArray(data + 4, 2));
107 EXPECT_THAT(subArr(foo, 6, 2), ElementsAreArray(data + 8, 6));
108 }
109
110 // Pointer wrap around
111 TEST(CircleBufTest, PointerWrapAround)
112 {
113 CircleBuf<char> buf(8);
114 char foo[16];
115
116 // _start == 0, _stop = 8
117 buf.write(data, 8);
118 // _start == 4, _stop = 8
119 buf.read(foo, 4);
120 // _start == 4, _stop = 12
121 buf.write(data + 8, 4);
122 EXPECT_EQ(buf.size(), 8);
123 // _start == 10, _stop = 12
124 // Normalized: _start == 2, _stop = 4
125 buf.read(foo + 4, 6);
126 EXPECT_EQ(buf.size(), 2);
127 EXPECT_THAT(subArr(foo, 10), ElementsAreArray(data, 10));
128 // Normalized: _start == 4, _stop = 4
129 buf.read(foo + 10, 2);
130 EXPECT_EQ(buf.size(), 0);
131 EXPECT_THAT(subArr(foo, 12), ElementsAreArray(data, 12));
132 }
133
134 // Consume after produce empties queue
135 TEST(CircleBufTest, ProduceConsumeEmpty)
136 {
137 CircleBuf<char> buf(8);
138 char foo[1];
139
140 // buf is empty to begin with.
141 EXPECT_TRUE(buf.empty());
142 // Produce one element.
143 buf.write(foo, 1);
144 EXPECT_FALSE(buf.empty());
145
146 // Read it back out.
147 buf.read(foo, 1);
148
149 // Now the buffer should be empty again.
150 EXPECT_TRUE(buf.empty());
151 }