xref: /llvm-project/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp (revision d6d569fc06361cb2324abf5f36192063ce0b4289)
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