OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/tracing/core/trace_ring_buffer.h" | |
6 | |
7 #include "base/bit_cast.h" | |
petrcermak
2016/06/28 10:22:30
I don't think you're actually using this.
Primiano Tucci (use gerrit)
2016/06/28 14:52:11
Good spot. I think this is going to be introduced
| |
8 #include "testing/gtest/include/gtest/gtest.h" | |
9 | |
10 namespace tracing { | |
11 namespace v2 { | |
12 | |
13 namespace { | |
14 | |
15 const size_t kChunkSize = TraceRingBuffer::Chunk::kSize; | |
16 | |
17 bool overlap(uint8_t* start1, uint8_t* end1, uint8_t* start2, uint8_t* end2) { | |
18 return start1 < end2 && start2 < end1; | |
19 } | |
20 | |
21 TEST(TraceRingBufferTest, BasicChunkWrapping) { | |
22 const size_t kNumChunks = 5; | |
23 const size_t kBufferSize = kChunkSize * kNumChunks; | |
24 std::unique_ptr<uint8_t[]> storage(new uint8_t[kBufferSize]); | |
25 TraceRingBuffer ring_buffer(storage.get(), kBufferSize); | |
26 | |
27 uint8_t* last_chunk_end = nullptr; | |
28 // Fill the buffer twice to test wrapping logic. | |
29 for (size_t i = 0; i < kNumChunks * 2; ++i) { | |
30 TraceRingBuffer::Chunk* chunk = ring_buffer.TakeChunk(); | |
31 ASSERT_NE(nullptr, chunk); | |
32 const size_t chunk_idx = i % kNumChunks; | |
33 EXPECT_EQ(chunk_idx == 0 ? storage.get() : last_chunk_end, chunk->begin()); | |
34 const size_t kPayloadSize = (chunk_idx + 1) * 8; | |
35 memset(chunk->payload(), chunk_idx + 1, kPayloadSize); | |
36 last_chunk_end = chunk->end(); | |
37 ring_buffer.ReturnChunk(chunk, /* used_size = */ kPayloadSize); | |
38 } | |
39 | |
40 // Now scrape the |storage| buffer and check its contents. | |
41 for (size_t chunk_idx = 0; chunk_idx < kNumChunks; ++chunk_idx) { | |
42 uint8_t* chunk_start = storage.get() + (chunk_idx * kChunkSize); | |
43 const size_t kPayloadSize = (chunk_idx + 1) * 8; | |
44 EXPECT_EQ(kPayloadSize, *reinterpret_cast<uint32_t*>(chunk_start)); | |
45 for (size_t i = 0; i < kPayloadSize; ++i) { | |
petrcermak
2016/06/28 10:22:30
do you need the braces here?
Primiano Tucci (use gerrit)
2016/06/28 14:52:11
Technically it's not mandatory to omit them, but y
| |
46 EXPECT_EQ(chunk_idx + 1, *(chunk_start + sizeof(uint32_t) + i)); | |
47 } | |
48 } | |
49 } | |
50 | |
51 TEST(TraceRingBufferTest, ChunkBankrupcyDoesNotCrash) { | |
52 const size_t kNumChunks = 2; | |
53 const size_t kBufferSize = TraceRingBuffer::Chunk::kSize * kNumChunks; | |
54 std::unique_ptr<uint8_t[]> storage(new uint8_t[kBufferSize]); | |
55 TraceRingBuffer ring_buffer(storage.get(), kBufferSize); | |
56 | |
57 TraceRingBuffer::Chunk* chunk1 = ring_buffer.TakeChunk(); | |
58 ASSERT_NE(nullptr, chunk1); | |
59 | |
60 TraceRingBuffer::Chunk* chunk2 = ring_buffer.TakeChunk(); | |
61 ASSERT_NE(nullptr, chunk2); | |
62 | |
63 for (int i = 0; i < 3; ++i) { | |
64 TraceRingBuffer::Chunk* bankrupcy_chunk = ring_buffer.TakeChunk(); | |
65 ASSERT_NE(nullptr, bankrupcy_chunk); | |
66 ASSERT_FALSE(overlap(bankrupcy_chunk->begin(), bankrupcy_chunk->end(), | |
67 storage.get(), storage.get() + kBufferSize)); | |
68 | |
69 // Make sure that the memory of the bankrupty chunk can be dereferenced. | |
70 memset(bankrupcy_chunk->begin(), 0, kChunkSize); | |
71 } | |
72 | |
73 // Return a chunk and check that the ring buffer is not bankrupt anymore. | |
74 ring_buffer.ReturnChunk(chunk2, 42); | |
75 TraceRingBuffer::Chunk* chunk = ring_buffer.TakeChunk(); | |
76 ASSERT_NE(nullptr, chunk); | |
77 ASSERT_TRUE(overlap(chunk->begin(), chunk->end(), storage.get(), | |
78 storage.get() + kBufferSize)); | |
79 } | |
80 | |
81 } // namespace | |
82 } // namespace v2 | |
83 } // namespace tracing | |
OLD | NEW |