diff --git a/staticlibs/native/bpf_headers/BpfRingbufTest.cpp b/staticlibs/native/bpf_headers/BpfRingbufTest.cpp index 6c0841c614..e4de812804 100644 --- a/staticlibs/native/bpf_headers/BpfRingbufTest.cpp +++ b/staticlibs/native/bpf_headers/BpfRingbufTest.cpp @@ -72,12 +72,15 @@ class BpfRingbufTest : public ::testing::Test { auto result = BpfRingbuf::Create(mRingbufPath.c_str()); ASSERT_RESULT_OK(result); + EXPECT_TRUE(result.value()->isEmpty()); for (int i = 0; i < n; i++) { RunProgram(); } + EXPECT_FALSE(result.value()->isEmpty()); EXPECT_THAT(result.value()->ConsumeAll(callback), HasValue(n)); + EXPECT_TRUE(result.value()->isEmpty()); EXPECT_EQ(output, TEST_RINGBUF_MAGIC_NUM); EXPECT_EQ(run_count, n); } diff --git a/staticlibs/native/bpf_headers/include/bpf/BpfRingbuf.h b/staticlibs/native/bpf_headers/include/bpf/BpfRingbuf.h index dd1504c92b..9aff79081f 100644 --- a/staticlibs/native/bpf_headers/include/bpf/BpfRingbuf.h +++ b/staticlibs/native/bpf_headers/include/bpf/BpfRingbuf.h @@ -39,6 +39,8 @@ class BpfRingbufBase { mProducerPos = nullptr; } + bool isEmpty(void); + protected: // Non-initializing constructor, used by Create. BpfRingbufBase(size_t value_size) : mValueSize(value_size) {} @@ -197,6 +199,13 @@ inline base::Result BpfRingbufBase::Init(const char* path) { return {}; } +inline bool BpfRingbufBase::isEmpty(void) { + uint32_t prod_pos = mProducerPos->load(std::memory_order_acquire); + // Only userspace writes to mConsumerPos, so no need to use std::memory_order_acquire + uint64_t cons_pos = mConsumerPos->load(std::memory_order_relaxed); + return (cons_pos & 0xFFFFFFFF) == prod_pos; +} + inline base::Result BpfRingbufBase::ConsumeAll( const std::function& callback) { int64_t count = 0;