mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 08:15:31 +00:00
Bug 1571390 - BlocksRingBuffer::GetState() takes a snapshot of the current state - r=gregtatum
This makes it easier to grab all BlocksRingBuffer state variables: - Range start and end. - Number of pushed blocks/entries, number of cleared blocks/entries. The function is thread-safe, and the returned values are consistent with each other, but they may become stale straight after the function returns (and the lock is released). They are still valuable to statistics, and to know how far the range has at least reached (but may go further soon). Differential Revision: https://phabricator.services.mozilla.com/D40621 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
f2af619bd3
commit
c05de0f147
@ -183,12 +183,29 @@ class BlocksRingBuffer {
|
|||||||
// Buffer length, constant. No need for locking.
|
// Buffer length, constant. No need for locking.
|
||||||
PowerOfTwo<Length> BufferLength() const { return mBuffer.BufferLength(); }
|
PowerOfTwo<Length> BufferLength() const { return mBuffer.BufferLength(); }
|
||||||
|
|
||||||
// Number of pushed and cleared entries. Live entries = pushed - cleared.
|
// Snapshot of the buffer state.
|
||||||
|
struct State {
|
||||||
|
// Index to the first block.
|
||||||
|
BlockIndex mRangeStart;
|
||||||
|
|
||||||
|
// Index past the last block. Equals mRangeStart if empty.
|
||||||
|
BlockIndex mRangeEnd;
|
||||||
|
|
||||||
|
// Number of blocks that have been pushed into this buffer.
|
||||||
|
uint64_t mPushedBlockCount = 0;
|
||||||
|
|
||||||
|
// Number of blocks that have been removed from this buffer.
|
||||||
|
// Note: Live entries = pushed - cleared.
|
||||||
|
uint64_t mClearedBlockCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get a snapshot of the current state.
|
||||||
// Note that these may change right after this thread-safe call, so they
|
// Note that these may change right after this thread-safe call, so they
|
||||||
// should only be used for statistical purposes.
|
// should only be used for statistical purposes.
|
||||||
Pair<uint64_t, uint64_t> GetPushedAndClearedCounts() const {
|
State GetState() const {
|
||||||
baseprofiler::detail::BaseProfilerAutoLock lock(mMutex);
|
baseprofiler::detail::BaseProfilerAutoLock lock(mMutex);
|
||||||
return {mPushedBlockCount, mClearedBlockCount};
|
return {mFirstReadIndex, mNextWriteIndex, mPushedBlockCount,
|
||||||
|
mClearedBlockCount};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterator-like class used to read from an entry.
|
// Iterator-like class used to read from an entry.
|
||||||
|
@ -465,14 +465,13 @@ void TestBlocksRingBufferAPI() {
|
|||||||
lastDestroyed = aReader.ReadObject<uint32_t>();
|
lastDestroyed = aReader.ReadObject<uint32_t>();
|
||||||
});
|
});
|
||||||
|
|
||||||
# define VERIFY_START_END_DESTROYED(aStart, aEnd, aLastDestroyed) \
|
# define VERIFY_START_END_DESTROYED(aStart, aEnd, aLastDestroyed) \
|
||||||
rb.Read([&](const BlocksRingBuffer::Reader aReader) { \
|
{ \
|
||||||
MOZ_RELEASE_ASSERT(ExtractBlockIndex(aReader.BufferRangeStart()) == \
|
BlocksRingBuffer::State state = rb.GetState(); \
|
||||||
(aStart)); \
|
MOZ_RELEASE_ASSERT(ExtractBlockIndex(state.mRangeStart) == (aStart)); \
|
||||||
MOZ_RELEASE_ASSERT(ExtractBlockIndex(aReader.BufferRangeEnd()) == \
|
MOZ_RELEASE_ASSERT(ExtractBlockIndex(state.mRangeEnd) == (aEnd)); \
|
||||||
(aEnd)); \
|
MOZ_RELEASE_ASSERT(lastDestroyed == (aLastDestroyed)); \
|
||||||
MOZ_RELEASE_ASSERT(lastDestroyed == (aLastDestroyed)); \
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// All entries will contain one 32-bit number. The resulting blocks will
|
// All entries will contain one 32-bit number. The resulting blocks will
|
||||||
// have the following structure:
|
// have the following structure:
|
||||||
@ -795,12 +794,20 @@ void TestBlocksRingBufferThreading() {
|
|||||||
std::atomic<bool> stopReader{false};
|
std::atomic<bool> stopReader{false};
|
||||||
std::thread reader([&]() {
|
std::thread reader([&]() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Pair<uint64_t, uint64_t> counts = rb.GetPushedAndClearedCounts();
|
BlocksRingBuffer::State state = rb.GetState();
|
||||||
printf("Reader: pushed=%llu cleared=%llu alive=%llu lastDestroyed=%d\n",
|
printf(
|
||||||
static_cast<unsigned long long>(counts.first()),
|
"Reader: range=%llu..%llu (%llu bytes) pushed=%llu cleared=%llu "
|
||||||
static_cast<unsigned long long>(counts.second()),
|
"(alive=%llu) lastDestroyed=%d\n",
|
||||||
static_cast<unsigned long long>(counts.first() - counts.second()),
|
static_cast<unsigned long long>(ExtractBlockIndex(state.mRangeStart)),
|
||||||
int(lastDestroyed));
|
static_cast<unsigned long long>(ExtractBlockIndex(state.mRangeEnd)),
|
||||||
|
static_cast<unsigned long long>(ExtractBlockIndex(state.mRangeEnd)) -
|
||||||
|
static_cast<unsigned long long>(
|
||||||
|
ExtractBlockIndex(state.mRangeStart)),
|
||||||
|
static_cast<unsigned long long>(state.mPushedBlockCount),
|
||||||
|
static_cast<unsigned long long>(state.mClearedBlockCount),
|
||||||
|
static_cast<unsigned long long>(state.mPushedBlockCount -
|
||||||
|
state.mClearedBlockCount),
|
||||||
|
int(lastDestroyed));
|
||||||
if (stopReader) {
|
if (stopReader) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user