1*d6d569fcSNico Weber //===-- sanitizer_vector_test.cpp -----------------------------------------===//
2*d6d569fcSNico Weber //
3*d6d569fcSNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*d6d569fcSNico Weber // See https://llvm.org/LICENSE.txt for license information.
5*d6d569fcSNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*d6d569fcSNico Weber //
7*d6d569fcSNico Weber //===----------------------------------------------------------------------===//
8*d6d569fcSNico Weber //
9*d6d569fcSNico Weber // This file is a part of *Sanitizer runtime.
10*d6d569fcSNico Weber //
11*d6d569fcSNico Weber //===----------------------------------------------------------------------===//
12*d6d569fcSNico Weber #include "sanitizer_common/sanitizer_ring_buffer.h"
13*d6d569fcSNico Weber #include "gtest/gtest.h"
14*d6d569fcSNico Weber
15*d6d569fcSNico Weber namespace __sanitizer {
16*d6d569fcSNico Weber
17*d6d569fcSNico Weber struct LargeStruct {
18*d6d569fcSNico Weber int64_t v;
19*d6d569fcSNico Weber int64_t extra[3];
20*d6d569fcSNico Weber
LargeStruct__sanitizer::LargeStruct21*d6d569fcSNico Weber explicit LargeStruct(int64_t v) : v(v) {}
operator int64_t__sanitizer::LargeStruct22*d6d569fcSNico Weber operator int64_t() { return v; }
23*d6d569fcSNico Weber };
24*d6d569fcSNico Weber
25*d6d569fcSNico Weber struct Struct10Bytes {
26*d6d569fcSNico Weber short t[3];
27*d6d569fcSNico Weber };
28*d6d569fcSNico Weber
TEST(RingBuffer,Construct)29*d6d569fcSNico Weber TEST(RingBuffer, Construct) {
30*d6d569fcSNico Weber RingBuffer<int64_t> *RBlong = RingBuffer<int64_t>::New(20);
31*d6d569fcSNico Weber EXPECT_EQ(RBlong->size(), 20U);
32*d6d569fcSNico Weber RBlong->Delete();
33*d6d569fcSNico Weber }
34*d6d569fcSNico Weber
TestRB()35*d6d569fcSNico Weber template <class T> void TestRB() {
36*d6d569fcSNico Weber RingBuffer<T> *RB;
37*d6d569fcSNico Weber const size_t Sizes[] = {1, 2, 3, 5, 8, 16, 20, 40, 10000};
38*d6d569fcSNico Weber for (size_t Size : Sizes) {
39*d6d569fcSNico Weber RB = RingBuffer<T>::New(Size);
40*d6d569fcSNico Weber EXPECT_EQ(RB->size(), Size);
41*d6d569fcSNico Weber RB->Delete();
42*d6d569fcSNico Weber }
43*d6d569fcSNico Weber
44*d6d569fcSNico Weber RB = RingBuffer<T>::New(4);
45*d6d569fcSNico Weber EXPECT_EQ(RB->size(), 4U);
46*d6d569fcSNico Weber #define EXPECT_RING_BUFFER(a0, a1, a2, a3) \
47*d6d569fcSNico Weber EXPECT_EQ((int64_t)(*RB)[0], (int64_t)a0); \
48*d6d569fcSNico Weber EXPECT_EQ((int64_t)(*RB)[1], (int64_t)a1); \
49*d6d569fcSNico Weber EXPECT_EQ((int64_t)(*RB)[2], (int64_t)a2); \
50*d6d569fcSNico Weber EXPECT_EQ((int64_t)(*RB)[3], (int64_t)a3);
51*d6d569fcSNico Weber
52*d6d569fcSNico Weber RB->push(T(1)); EXPECT_RING_BUFFER(1, 0, 0, 0);
53*d6d569fcSNico Weber RB->push(T(2)); EXPECT_RING_BUFFER(2, 1, 0, 0);
54*d6d569fcSNico Weber RB->push(T(3)); EXPECT_RING_BUFFER(3, 2, 1, 0);
55*d6d569fcSNico Weber RB->push(T(4)); EXPECT_RING_BUFFER(4, 3, 2, 1);
56*d6d569fcSNico Weber RB->push(T(5)); EXPECT_RING_BUFFER(5, 4, 3, 2);
57*d6d569fcSNico Weber RB->push(T(6)); EXPECT_RING_BUFFER(6, 5, 4, 3);
58*d6d569fcSNico Weber RB->push(T(7)); EXPECT_RING_BUFFER(7, 6, 5, 4);
59*d6d569fcSNico Weber RB->push(T(8)); EXPECT_RING_BUFFER(8, 7, 6, 5);
60*d6d569fcSNico Weber RB->push(T(9)); EXPECT_RING_BUFFER(9, 8, 7, 6);
61*d6d569fcSNico Weber RB->push(T(10)); EXPECT_RING_BUFFER(10, 9, 8, 7);
62*d6d569fcSNico Weber RB->push(T(11)); EXPECT_RING_BUFFER(11, 10, 9, 8);
63*d6d569fcSNico Weber RB->push(T(12)); EXPECT_RING_BUFFER(12, 11, 10, 9);
64*d6d569fcSNico Weber
65*d6d569fcSNico Weber #undef EXPECT_RING_BUFFER
66*d6d569fcSNico Weber }
67*d6d569fcSNico Weber
68*d6d569fcSNico Weber #if SANITIZER_WORDSIZE == 64
TEST(RingBuffer,int64)69*d6d569fcSNico Weber TEST(RingBuffer, int64) {
70*d6d569fcSNico Weber TestRB<int64_t>();
71*d6d569fcSNico Weber }
72*d6d569fcSNico Weber
TEST(RingBuffer,LargeStruct)73*d6d569fcSNico Weber TEST(RingBuffer, LargeStruct) {
74*d6d569fcSNico Weber TestRB<LargeStruct>();
75*d6d569fcSNico Weber }
76*d6d569fcSNico Weber
77*d6d569fcSNico Weber template<typename T>
AllocCompactRingBuffer(size_t count)78*d6d569fcSNico Weber CompactRingBuffer<T> *AllocCompactRingBuffer(size_t count) {
79*d6d569fcSNico Weber size_t sz = sizeof(T) * count;
80*d6d569fcSNico Weber EXPECT_EQ(0ULL, sz % 4096);
81*d6d569fcSNico Weber void *p = MmapAlignedOrDieOnFatalError(sz, sz * 2, "CompactRingBuffer");
82*d6d569fcSNico Weber return new CompactRingBuffer<T>(p, sz);
83*d6d569fcSNico Weber }
84*d6d569fcSNico Weber
TEST(CompactRingBuffer,int64)85*d6d569fcSNico Weber TEST(CompactRingBuffer, int64) {
86*d6d569fcSNico Weber const size_t page_sizes[] = {1, 2, 4, 128};
87*d6d569fcSNico Weber
88*d6d569fcSNico Weber for (size_t pages : page_sizes) {
89*d6d569fcSNico Weber size_t count = 4096 * pages / sizeof(int64_t);
90*d6d569fcSNico Weber auto R = AllocCompactRingBuffer<int64_t>(count);
91*d6d569fcSNico Weber int64_t top = count * 3 + 13;
92*d6d569fcSNico Weber for (int64_t i = 0; i < top; ++i) R->push(i);
93*d6d569fcSNico Weber for (int64_t i = 0; i < (int64_t)count; ++i)
94*d6d569fcSNico Weber EXPECT_EQ(top - i - 1, (*R)[i]);
95*d6d569fcSNico Weber }
96*d6d569fcSNico Weber }
97*d6d569fcSNico Weber #endif
98*d6d569fcSNico Weber } // namespace __sanitizer
99