1aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang#include "libbroadcastring/broadcast_ring.h" 2aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 3aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang#include <stdlib.h> 4aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang#include <memory> 5aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang#include <thread> // NOLINT 6aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang#include <sys/mman.h> 7aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 8aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang#include <gtest/gtest.h> 9aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 10aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangnamespace android { 11aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangnamespace dvr { 12aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangnamespace { 13aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 14aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <uint32_t N> 15aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangstruct alignas(8) Aligned { 16aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang char v[N]; 17aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang}; 18aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 19aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <uint32_t N> 20aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangstruct alignas(8) Sized { 21aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Sized() { Clear(); } 22aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang explicit Sized(char c) { Fill(c); } 23aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang char v[sizeof(Aligned<N>)]; 24aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang void Clear() { memset(v, 0, sizeof(v)); } 25aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang void Fill(char c) { memset(v, c, sizeof(v)); } 26aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static Sized Pattern(uint8_t c) { 27aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Sized sized; 28aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (size_t i = 0; i < sizeof(v); ++i) { 29aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang sized.v[i] = static_cast<char>(c + i); 30aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 31aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang return sized; 32aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 33aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool operator==(const Sized& right) const { 34aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static_assert(sizeof(*this) == sizeof(v), "Size mismatch"); 35aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang return !memcmp(v, right.v, sizeof(v)); 36aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 37aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang template <typename SmallerSized> 38aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang SmallerSized Truncate() const { 39aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang SmallerSized val; 40aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static_assert(sizeof(val.v) <= sizeof(v), "Cannot truncate to larger size"); 41aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang memcpy(val.v, v, sizeof(val.v)); 42aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang return val; 43aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 44aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang}; 45aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 46aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangchar FillChar(int val) { return static_cast<char>(val); } 47aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 48aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangstruct FakeMmap { 49aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang explicit FakeMmap(size_t size) : size(size), data(new char[size]) {} 50aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t size; 51aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::unique_ptr<char[]> data; 52aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang void* mmap() { return static_cast<void*>(data.get()); } 53aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang}; 54aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 55aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <typename Ring> 56aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangFakeMmap CreateRing(Ring* ring, uint32_t count) { 57aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang FakeMmap mmap(Ring::MemorySize(count)); 58aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang *ring = Ring::Create(mmap.mmap(), mmap.size, count); 59aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang return mmap; 60aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 61aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 62aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <typename RecordType, bool StaticSize = false, 63aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t StaticCount = 0, uint32_t MaxReserved = 1, 64aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t MinAvailable = 0> 65aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangstruct Traits { 66aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = RecordType; 67aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static constexpr bool kUseStaticRecordSize = StaticSize; 68aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static constexpr uint32_t kStaticRecordCount = StaticCount; 69aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static constexpr uint32_t kMaxReservedRecords = MaxReserved; 70aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static constexpr uint32_t kMinAvailableRecords = MinAvailable; 71aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static constexpr uint32_t kMinRecordCount = MaxReserved + MinAvailable; 72aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang}; 73aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 74aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <typename Record, bool StaticSize = false, uint32_t MaxReserved = 1, 75aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t MinAvailable = 7> 76aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangstruct TraitsDynamic 77aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang : public Traits<Record, StaticSize, 0, MaxReserved, MinAvailable> { 78aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = BroadcastRing<Record, TraitsDynamic>; 79aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static uint32_t MinCount() { return MaxReserved + MinAvailable; } 80aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang}; 81aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 82aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <typename Record, uint32_t StaticCount = 1, bool StaticSize = true, 83aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t MaxReserved = 1, uint32_t MinAvailable = 0> 84aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangstruct TraitsStatic 85aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang : public Traits<Record, true, StaticCount, MaxReserved, MinAvailable> { 86aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = BroadcastRing<Record, TraitsStatic>; 87aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang static uint32_t MinCount() { return StaticCount; } 88aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang}; 89aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 90aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Dynamic_8_NxM = TraitsDynamic<Sized<8>>; 91aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Dynamic_16_NxM = TraitsDynamic<Sized<16>>; 92aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Dynamic_32_NxM = TraitsDynamic<Sized<32>>; 93aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Dynamic_32_32xM = TraitsDynamic<Sized<32>, true>; 94aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Dynamic_16_NxM_1plus0 = TraitsDynamic<Sized<16>, false, 1, 0>; 95aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Dynamic_16_NxM_1plus1 = TraitsDynamic<Sized<16>, false, 1, 1>; 96aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Dynamic_16_NxM_5plus11 = TraitsDynamic<Sized<16>, false, 5, 11>; 97aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Dynamic_256_NxM_1plus0 = TraitsDynamic<Sized<256>, false, 1, 0>; 98aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 99aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Static_8_8x1 = TraitsStatic<Sized<8>, 1>; 100aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Static_8_8x16 = TraitsStatic<Sized<8>, 16>; 101aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Static_16_16x8 = TraitsStatic<Sized<16>, 8>; 102aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Static_16_16x16 = TraitsStatic<Sized<16>, 16>; 103aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Static_16_16x32 = TraitsStatic<Sized<16>, 32>; 104aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing Static_32_Nx8 = TraitsStatic<Sized<32>, 8, false>; 105aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 106aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangusing TraitsList = ::testing::Types<Dynamic_8_NxM, // 107aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Dynamic_16_NxM, // 108aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Dynamic_32_NxM, // 109aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Dynamic_32_32xM, // 110aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Dynamic_16_NxM_1plus0, // 111aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Dynamic_16_NxM_1plus1, // 112aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Dynamic_16_NxM_5plus11, // 113aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Dynamic_256_NxM_1plus0, // 114aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Static_8_8x1, // 115aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Static_8_8x16, // 116aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Static_16_16x8, // 117aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Static_16_16x16, // 118aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Static_16_16x32, // 119aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Static_32_Nx8>; 120aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 121aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} // namespace 122aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 123aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <typename T> 124aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangclass BroadcastRingTest : public ::testing::Test {}; 125aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 126aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTYPED_TEST_CASE(BroadcastRingTest, TraitsList); 127aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 128aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTYPED_TEST(BroadcastRingTest, Geometry) { 129aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = typename TypeParam::Record; 130aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = typename TypeParam::Ring; 131aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring; 132aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&ring, Ring::Traits::MinCount()); 133aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Ring::Traits::MinCount(), ring.record_count()); 134aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(sizeof(Record), ring.record_size()); 135aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 136aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 137aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTYPED_TEST(BroadcastRingTest, PutGet) { 138aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = typename TypeParam::Record; 139aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = typename TypeParam::Ring; 140aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring; 141aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&ring, Ring::Traits::MinCount()); 142aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t oldest_sequence_at_start = ring.GetOldestSequence(); 143aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t next_sequence_at_start = ring.GetNextSequence(); 144aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 145aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = oldest_sequence_at_start; 146aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 147aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(ring.Get(&sequence, &record)); 148aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(oldest_sequence_at_start, sequence); 149aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(), record); 150aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 151aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record original_record(0x1a); 152aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ring.Put(original_record); 153aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 154aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = next_sequence_at_start; 155aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 156aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.Get(&sequence, &record)); 157aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(next_sequence_at_start, sequence); 158aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_record, record); 159aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 160aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 161aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = next_sequence_at_start + 1; 162aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 163aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(ring.Get(&sequence, &record)); 164aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(next_sequence_at_start + 1, sequence); 165aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(), record); 166aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 167aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 168aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 169aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTYPED_TEST(BroadcastRingTest, FillOnce) { 170aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = typename TypeParam::Record; 171aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = typename TypeParam::Ring; 172aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring; 173aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&ring, Ring::Traits::MinCount()); 174aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t next_sequence_at_start = ring.GetNextSequence(); 175aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (uint32_t i = 0; i < ring.record_count(); ++i) 176aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ring.Put(Record(FillChar(i))); 177aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (uint32_t i = 0; i < ring.record_count(); ++i) { 178aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t expected_sequence = next_sequence_at_start + i; 179aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record expected_record(FillChar(i)); 180aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 181aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = ring.GetOldestSequence() + i; 182aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 183aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.Get(&sequence, &record)); 184aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(expected_sequence, sequence); 185aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(expected_record, record); 186aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 187aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 188aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 189aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = ring.GetOldestSequence() + ring.record_count(); 190aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 191aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(ring.Get(&sequence, &record)); 192aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 193aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 194aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 195aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTYPED_TEST(BroadcastRingTest, FillTwice) { 196aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = typename TypeParam::Record; 197aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = typename TypeParam::Ring; 198aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring; 199aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&ring, Ring::Traits::MinCount()); 200aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t next_sequence_at_start = ring.GetNextSequence(); 201aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (uint32_t i = 0; i < 2 * ring.record_count(); ++i) { 202aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record newest_record(FillChar(i)); 203aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ring.Put(newest_record); 204aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 205aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t newest_sequence = next_sequence_at_start + i; 206aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t records_available = std::min(i + 1, ring.record_count()); 207aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t oldest_sequence = newest_sequence - records_available + 1; 208aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(newest_sequence, ring.GetNewestSequence()); 209aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(oldest_sequence, ring.GetOldestSequence()); 210aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(newest_sequence + 1, ring.GetNextSequence()); 211aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 212aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (uint32_t j = 0; j < records_available; ++j) { 213aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t sequence_jth_newest = newest_sequence - j; 214aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record record_jth_newest(FillChar(i - j)); 215aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 216aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 217aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_jth_newest; 218aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 219aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.Get(&sequence, &record)); 220aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(sequence_jth_newest, sequence); 221aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(record_jth_newest, record); 222aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 223aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 224aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 225aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_jth_newest; 226aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 227aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.GetNewest(&sequence, &record)); 228aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(newest_sequence, sequence); 229aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(newest_record, record); 230aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 231aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 232aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 233aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record oldest_record( 234aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang FillChar(i + (oldest_sequence - newest_sequence))); 235aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t sequence_0th_overwritten = oldest_sequence - 1; 236aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t sequence_0th_future = newest_sequence + 1; 237aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t sequence_1st_future = newest_sequence + 2; 238aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 239aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 240aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_0th_overwritten; 241aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 242aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.Get(&sequence, &record)); 243aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(oldest_sequence, sequence); 244aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(oldest_record, record); 245aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 246aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 247aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 248aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_0th_overwritten; 249aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 250aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.GetNewest(&sequence, &record)); 251aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(newest_sequence, sequence); 252aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(newest_record, record); 253aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 254aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 255aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 256aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_0th_future; 257aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 258aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(ring.Get(&sequence, &record)); 259aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(sequence_0th_future, sequence); 260aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(), record); 261aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 262aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 263aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 264aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_0th_future; 265aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 266aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(ring.GetNewest(&sequence, &record)); 267aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(sequence_0th_future, sequence); 268aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(), record); 269aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 270aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 271aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 272aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_1st_future; 273aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 274aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.Get(&sequence, &record)); 275aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(oldest_sequence, sequence); 276aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(oldest_record, record); 277aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 278aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 279aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 280aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_1st_future; 281aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 282aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.GetNewest(&sequence, &record)); 283aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(newest_sequence, sequence); 284aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(newest_record, record); 285aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 286aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 287aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 288aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 289aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTYPED_TEST(BroadcastRingTest, Import) { 290aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = typename TypeParam::Record; 291aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = typename TypeParam::Ring; 292aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring; 293aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&ring, Ring::Traits::MinCount()); 294aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 295aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t sequence_0 = ring.GetNextSequence(); 296aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t sequence_1 = ring.GetNextSequence() + 1; 297aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record record_0 = Record::Pattern(0x00); 298aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record record_1 = Record::Pattern(0x80); 299aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ring.Put(record_0); 300aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ring.Put(record_1); 301aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 302aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 303aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring imported_ring; 304aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 305aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = Ring::Import(mmap.mmap(), mmap.size); 306aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(import_ok); 307aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(ring.record_size(), imported_ring.record_size()); 308aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(ring.record_count(), imported_ring.record_count()); 309aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 310aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang if (ring.record_count() != 1) { 311aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_0; 312aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record imported_record; 313aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record)); 314aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(sequence_0, sequence); 315aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(record_0, imported_record); 316aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 317aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 318aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 319aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = sequence_1; 320aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record imported_record; 321aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record)); 322aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(sequence_1, sequence); 323aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(record_1, imported_record); 324aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 325aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 326aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 327aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 328aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldFailImportIfStaticSizeMismatch) { 329aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRing = typename Static_16_16x16::Ring; 330aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using RecordSizeMismatchRing = typename Static_8_8x16::Ring; 331aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using RecordCountMismatchRing = typename Static_16_16x8::Ring; 332aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 333aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang OriginalRing original_ring; 334aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount()); 335aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 336aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 337aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRing = RecordSizeMismatchRing; 338aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing imported_ring; 339aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 340aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 341aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), mmap.size); 342aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(import_ok); 343aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap_imported = 344aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang CreateRing(&imported_ring, ImportedRing::Traits::MinCount()); 345aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_NE(original_ring.record_size(), imported_ring.record_size()); 346aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_count(), imported_ring.record_count()); 347aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 348aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 349aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 350aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRing = RecordCountMismatchRing; 351aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing imported_ring; 352aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 353aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 354aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), mmap.size); 355aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(import_ok); 356aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap_imported = 357aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang CreateRing(&imported_ring, ImportedRing::Traits::MinCount()); 358aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_size(), imported_ring.record_size()); 359aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_NE(original_ring.record_count(), imported_ring.record_count()); 360aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 361aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 362aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 363aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldFailImportIfDynamicSizeGrows) { 364aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRing = typename Dynamic_8_NxM::Ring; 365aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using RecordSizeGrowsRing = typename Dynamic_16_NxM::Ring; 366aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 367aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang OriginalRing original_ring; 368aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount()); 369aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 370aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 371aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRing = RecordSizeGrowsRing; 372aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing imported_ring; 373aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 374aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 375aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), mmap.size); 376aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(import_ok); 377aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap_imported = 378aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang CreateRing(&imported_ring, ImportedRing::Traits::MinCount()); 379aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_LT(original_ring.record_size(), imported_ring.record_size()); 380aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_count(), imported_ring.record_count()); 381aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 382aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 383aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 384aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldFailImportIfCountTooSmall) { 385aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRing = typename Dynamic_16_NxM_1plus0::Ring; 386aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using MinCountRing = typename Dynamic_16_NxM_1plus1::Ring; 387aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 388aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang OriginalRing original_ring; 389aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount()); 390aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 391aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 392aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRing = MinCountRing; 393aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing imported_ring; 394aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 395aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 396aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), mmap.size); 397aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(import_ok); 398aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap_imported = 399aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang CreateRing(&imported_ring, ImportedRing::Traits::MinCount()); 400aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_size(), imported_ring.record_size()); 401aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_LT(original_ring.record_count(), imported_ring.record_count()); 402aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 403aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 404aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 405aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldFailImportIfMmapTooSmall) { 406aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRing = typename Dynamic_16_NxM::Ring; 407aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 408aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang OriginalRing original_ring; 409aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount()); 410aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 411aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 412aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRing = OriginalRing; 413aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing imported_ring; 414aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 415aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const size_t kMinSize = 416aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::MemorySize(original_ring.record_count()); 417aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = ImportedRing::Import(mmap.mmap(), 0); 418aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(import_ok); 419aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 420aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), kMinSize - 1); 421aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_FALSE(import_ok); 422aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 423aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), kMinSize); 424aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(import_ok); 425aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_size(), imported_ring.record_size()); 426aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_count(), imported_ring.record_count()); 427aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 428aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 429aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 430aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldImportIfDynamicSizeShrinks) { 431aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRing = typename Dynamic_16_NxM::Ring; 432aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using RecordSizeShrinksRing = typename Dynamic_8_NxM::Ring; 433aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 434aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang OriginalRing original_ring; 435aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount()); 436aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 437aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRecord = typename OriginalRing::Record; 438aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t original_sequence_0 = original_ring.GetNextSequence(); 439aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1; 440aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00); 441aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80); 442aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang original_ring.Put(original_record_0); 443aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang original_ring.Put(original_record_1); 444aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 445aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 446aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRing = RecordSizeShrinksRing; 447aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRecord = typename ImportedRing::Record; 448aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing imported_ring; 449aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 450aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 451aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), mmap.size); 452aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(import_ok); 453aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_size(), imported_ring.record_size()); 454aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_count(), imported_ring.record_count()); 455aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_GT(sizeof(OriginalRecord), sizeof(ImportedRecord)); 456aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 457aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 458aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = original_sequence_0; 459aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRecord shrunk_record; 460aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &shrunk_record)); 461aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_sequence_0, sequence); 462aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_record_0.Truncate<ImportedRecord>(), shrunk_record); 463aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 464aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 465aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 466aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = original_sequence_1; 467aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRecord shrunk_record; 468aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &shrunk_record)); 469aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_sequence_1, sequence); 470aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_record_1.Truncate<ImportedRecord>(), shrunk_record); 471aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 472aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 473aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 474aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 475aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldImportIfCompatibleDynamicToStatic) { 476aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRing = typename Dynamic_16_NxM::Ring; 477aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRing = typename Static_16_16x16::Ring; 478aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRecord = typename OriginalRing::Record; 479aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRecord = typename ImportedRing::Record; 480aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using StaticRing = ImportedRing; 481aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 482aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang OriginalRing original_ring; 483aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&original_ring, StaticRing::Traits::MinCount()); 484aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 485aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t original_sequence_0 = original_ring.GetNextSequence(); 486aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1; 487aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00); 488aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80); 489aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang original_ring.Put(original_record_0); 490aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang original_ring.Put(original_record_1); 491aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 492aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 493aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing imported_ring; 494aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 495aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 496aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), mmap.size); 497aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(import_ok); 498aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_size(), imported_ring.record_size()); 499aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_count(), imported_ring.record_count()); 500aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 501aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 502aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = original_sequence_0; 503aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRecord imported_record; 504aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record)); 505aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_sequence_0, sequence); 506aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_record_0, imported_record); 507aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 508aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 509aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 510aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = original_sequence_1; 511aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRecord imported_record; 512aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record)); 513aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_sequence_1, sequence); 514aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_record_1, imported_record); 515aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 516aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 517aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 518aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 519aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldImportIfCompatibleStaticToDynamic) { 520aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRing = typename Static_16_16x16::Ring; 521aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRing = typename Dynamic_16_NxM::Ring; 522aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using OriginalRecord = typename OriginalRing::Record; 523aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using ImportedRecord = typename ImportedRing::Record; 524aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using StaticRing = OriginalRing; 525aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 526aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang OriginalRing original_ring; 527aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto mmap = CreateRing(&original_ring, StaticRing::Traits::MinCount()); 528aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 529aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t original_sequence_0 = original_ring.GetNextSequence(); 530aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1; 531aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00); 532aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80); 533aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang original_ring.Put(original_record_0); 534aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang original_ring.Put(original_record_1); 535aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 536aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 537aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing imported_ring; 538aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 539aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = 540aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRing::Import(mmap.mmap(), mmap.size); 541aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(import_ok); 542aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_size(), imported_ring.record_size()); 543aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_ring.record_count(), imported_ring.record_count()); 544aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 545aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 546aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = original_sequence_0; 547aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRecord imported_record; 548aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record)); 549aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_sequence_0, sequence); 550aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_record_0, imported_record); 551aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 552aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 553aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 554aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = original_sequence_1; 555aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ImportedRecord imported_record; 556aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record)); 557aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_sequence_1, sequence); 558aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(original_record_1, imported_record); 559aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 560aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 561aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 562aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 563aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldImportIfReadonlyMmap) { 564aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = Dynamic_32_NxM::Ring; 565aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = Ring::Record; 566aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 567aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t record_count = Ring::Traits::MinCount(); 568aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t ring_size = Ring::MemorySize(record_count); 569aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 570aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t page_size = sysconf(_SC_PAGESIZE); 571aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t mmap_size = (ring_size + (page_size - 1)) & ~(page_size - 1); 572aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_GE(mmap_size, ring_size); 573aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 574aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang void* mmap_base = mmap(nullptr, mmap_size, PROT_READ | PROT_WRITE, 575aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 576aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_NE(MAP_FAILED, mmap_base); 577aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 578aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring = Ring::Create(mmap_base, mmap_size, record_count); 579aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (uint32_t i = 0; i < record_count; ++i) ring.Put(Record(FillChar(i))); 580aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 581aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_EQ(0, mprotect(mmap_base, mmap_size, PROT_READ)); 582aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 583aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 584aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring imported_ring; 585aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 586aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(imported_ring, import_ok) = Ring::Import(mmap_base, mmap_size); 587aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(import_ok); 588aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(ring.record_size(), imported_ring.record_size()); 589aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(ring.record_count(), imported_ring.record_count()); 590aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 591aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t oldest_sequence = imported_ring.GetOldestSequence(); 592aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (uint32_t i = 0; i < record_count; ++i) { 593aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = oldest_sequence + i; 594aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 595aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(imported_ring.Get(&sequence, &record)); 596aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(FillChar(i)), record); 597aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 598aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 599aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 600aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_EQ(0, munmap(mmap_base, mmap_size)); 601aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 602aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 603aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldDieIfPutReadonlyMmap) { 604aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = Dynamic_32_NxM::Ring; 605aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = Ring::Record; 606aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 607aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t record_count = Ring::Traits::MinCount(); 608aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t ring_size = Ring::MemorySize(record_count); 609aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 610aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t page_size = sysconf(_SC_PAGESIZE); 611aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t mmap_size = (ring_size + (page_size - 1)) & ~(page_size - 1); 612aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_GE(mmap_size, ring_size); 613aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 614aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang void* mmap_base = mmap(nullptr, mmap_size, PROT_READ | PROT_WRITE, 615aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 616aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_NE(MAP_FAILED, mmap_base); 617aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 618aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring = Ring::Create(mmap_base, mmap_size, record_count); 619aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (uint32_t i = 0; i < record_count; ++i) ring.Put(Record(FillChar(i))); 620aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 621aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_EQ(0, mprotect(mmap_base, mmap_size, PROT_READ)); 622aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 623aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_DEATH_IF_SUPPORTED({ ring.Put(Record(7)); }, ""); 624aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 625aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_EQ(0, munmap(mmap_base, mmap_size)); 626aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 627aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 628aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldDieIfCreationMmapTooSmall) { 629aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = Dynamic_32_NxM::Ring; 630aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = Ring::Record; 631aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 632aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t record_count = Ring::Traits::MinCount(); 633aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t ring_size = Ring::MemorySize(record_count); 634aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang FakeMmap mmap(ring_size); 635aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 636aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_DEATH_IF_SUPPORTED({ 637aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring = Ring::Create(mmap.mmap(), ring_size - 1, record_count); 638aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang }, ""); 639aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 640aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring = Ring::Create(mmap.mmap(), ring_size, record_count); 641aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 642aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ring.Put(Record(3)); 643aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 644aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 645aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = ring.GetNewestSequence(); 646aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 647aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.Get(&sequence, &record)); 648aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(3), record); 649aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 650aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 651aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 652aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ShouldDieIfCreationMmapMisaligned) { 653aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = Static_8_8x1::Ring; 654aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = Ring::Record; 655aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 656aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang constexpr int kAlign = Ring::mmap_alignment(); 657aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang constexpr int kMisalign = kAlign / 2; 658aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t ring_size = Ring::MemorySize(); 659aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::unique_ptr<char[]> buf(new char[ring_size + kMisalign]); 660aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 661aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_DEATH_IF_SUPPORTED( 662aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { Ring ring = Ring::Create(buf.get() + kMisalign, ring_size); }, ""); 663aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 664aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring ring = Ring::Create(buf.get(), ring_size); 665aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 666aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ring.Put(Record(3)); 667aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 668aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang { 669aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = ring.GetNewestSequence(); 670aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 671aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_TRUE(ring.Get(&sequence, &record)); 672aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(3), record); 673aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 674aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 675aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 676aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <typename Ring> 677aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangstd::unique_ptr<std::thread> CopyTask(std::atomic<bool>* quit, void* in_base, 678aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t in_size, void* out_base, 679aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang size_t out_size) { 680aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang return std::unique_ptr<std::thread>( 681aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang new std::thread([quit, in_base, in_size, out_base, out_size]() { 682aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = typename Ring::Record; 683aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 684aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 685aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring in_ring; 686aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring out_ring; 687aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(in_ring, import_ok) = Ring::Import(in_base, in_size); 688aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_TRUE(import_ok); 689aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(out_ring, import_ok) = Ring::Import(out_base, out_size); 690aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_TRUE(import_ok); 691aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 692aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = in_ring.GetOldestSequence(); 693aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang while (!std::atomic_load_explicit(quit, std::memory_order_relaxed)) { 694aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 695aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang if (in_ring.Get(&sequence, &record)) { 696aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang out_ring.Put(record); 697aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang sequence++; 698aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 699aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 700aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang })); 701aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 702aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 703aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ThreadedCopySingle) { 704aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = Dynamic_32_NxM::Ring; 705aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = Ring::Record; 706aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring in_ring; 707aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount()); 708aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 709aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring out_ring; 710aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount()); 711aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 712aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::atomic<bool> quit(false); 713aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::unique_ptr<std::thread> copy_task = CopyTask<Ring>( 714aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size); 715aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 716aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record out_record(0x1c); 717aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang out_ring.Put(out_record); 718aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 719aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t in_sequence = in_ring.GetOldestSequence(); 720aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record in_record; 721aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang while (!in_ring.Get(&in_sequence, &in_record)) { 722aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang // Do nothing. 723aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 724aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 725aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(out_record, in_record); 726aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::atomic_store_explicit(&quit, true, std::memory_order_relaxed); 727aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang copy_task->join(); 728aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 729aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 730aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ThreadedCopyLossless) { 731aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = Dynamic_32_NxM::Ring; 732aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = Ring::Record; 733aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring in_ring; 734aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount()); 735aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 736aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring out_ring; 737aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount()); 738aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 739aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::atomic<bool> quit(false); 740aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::unique_ptr<std::thread> copy_task = CopyTask<Ring>( 741aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size); 742aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 743aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang constexpr uint32_t kRecordsToProcess = 10000; 744aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t out_records = 0; 745aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t in_records = 0; 746aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t in_sequence = in_ring.GetNextSequence(); 747aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang while (out_records < kRecordsToProcess || in_records < kRecordsToProcess) { 748aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang if (out_records < kRecordsToProcess && 749aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang out_records - in_records < out_ring.record_count()) { 750aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record out_record(FillChar(out_records)); 751aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang out_ring.Put(out_record); 752aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang out_records++; 753aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 754aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 755aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record in_record; 756aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang while (in_ring.Get(&in_sequence, &in_record)) { 757aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(FillChar(in_records)), in_record); 758aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang in_records++; 759aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang in_sequence++; 760aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 761aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 762aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 763aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(kRecordsToProcess, out_records); 764aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(kRecordsToProcess, in_records); 765aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 766aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::atomic_store_explicit(&quit, true, std::memory_order_relaxed); 767aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang copy_task->join(); 768aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 769aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 770aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ThreadedCopyLossy) { 771aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Ring = Dynamic_32_NxM::Ring; 772aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = Ring::Record; 773aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring in_ring; 774aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount()); 775aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 776aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring out_ring; 777aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount()); 778aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 779aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::atomic<bool> quit(false); 780aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::unique_ptr<std::thread> copy_task = CopyTask<Ring>( 781aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size); 782aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 783aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang constexpr uint32_t kRecordsToProcess = 100000; 784aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t out_records = 0; 785aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t in_records = 0; 786aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t in_sequence = in_ring.GetNextSequence(); 787aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang while (out_records < kRecordsToProcess) { 788aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record out_record(FillChar(out_records)); 789aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang out_ring.Put(out_record); 790aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang out_records++; 791aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 792aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record in_record; 793aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang if (in_ring.GetNewest(&in_sequence, &in_record)) { 794aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(Record(in_record.v[0]), in_record); 795aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang in_records++; 796aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang in_sequence++; 797aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 798aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 799aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 800aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_EQ(kRecordsToProcess, out_records); 801aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang EXPECT_GE(kRecordsToProcess, in_records); 802aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 803aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::atomic_store_explicit(&quit, true, std::memory_order_relaxed); 804aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang copy_task->join(); 805aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 806aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 807aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <typename Ring> 808aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangstd::unique_ptr<std::thread> CheckFillTask(std::atomic<bool>* quit, 809aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang void* in_base, size_t in_size) { 810aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang return std::unique_ptr<std::thread>( 811aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang new std::thread([quit, in_base, in_size]() { 812aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = typename Ring::Record; 813aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 814aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang bool import_ok; 815aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring in_ring; 816aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::tie(in_ring, import_ok) = Ring::Import(in_base, in_size); 817aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_TRUE(import_ok); 818aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 819aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang uint32_t sequence = in_ring.GetOldestSequence(); 820aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang while (!std::atomic_load_explicit(quit, std::memory_order_relaxed)) { 821aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Record record; 822aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang if (in_ring.Get(&sequence, &record)) { 823aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ASSERT_EQ(Record(record.v[0]), record); 824aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang sequence++; 825aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 826aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 827aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang })); 828aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 829aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 830aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangtemplate <typename Ring> 831aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spangvoid ThreadedOverwriteTorture() { 832aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang using Record = typename Ring::Record; 833aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 834aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang // Maximize overwrites by having few records. 835aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const int kMinRecordCount = 1; 836aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const int kMaxRecordCount = 4; 837aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 838aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (int count = kMinRecordCount; count <= kMaxRecordCount; count *= 2) { 839aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang Ring out_ring; 840aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang auto out_mmap = CreateRing(&out_ring, count); 841aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 842aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::atomic<bool> quit(false); 843aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::unique_ptr<std::thread> check_task = 844aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang CheckFillTask<Ring>(&quit, out_mmap.mmap(), out_mmap.size); 845aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 846aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang constexpr int kIterations = 10000; 847aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang for (int i = 0; i < kIterations; ++i) { 848aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang const Record record(FillChar(i)); 849aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang out_ring.Put(record); 850aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 851aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 852aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang std::atomic_store_explicit(&quit, true, std::memory_order_relaxed); 853aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang check_task->join(); 854aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang } 855aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 856aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 857aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ThreadedOverwriteTortureSmall) { 858aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ThreadedOverwriteTorture<Dynamic_16_NxM_1plus0::Ring>(); 859aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 860aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 861aacc1fceefd75e33908fa6feee2cf03688e09374Michael SpangTEST(BroadcastRingTest, ThreadedOverwriteTortureLarge) { 862aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang ThreadedOverwriteTorture<Dynamic_256_NxM_1plus0::Ring>(); 863aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} 864aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang 865aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} // namespace dvr 866aacc1fceefd75e33908fa6feee2cf03688e09374Michael Spang} // namespace android 867