BpfRingBuf.h - implement wait()
Test: TreeHugger, atest BpfRingbufTest Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I2696077caf4de27dd64e4af1c45a13844ed186c9
This commit is contained in:
@@ -74,11 +74,27 @@ class BpfRingbufTest : public ::testing::Test {
|
|||||||
ASSERT_RESULT_OK(result);
|
ASSERT_RESULT_OK(result);
|
||||||
EXPECT_TRUE(result.value()->isEmpty());
|
EXPECT_TRUE(result.value()->isEmpty());
|
||||||
|
|
||||||
|
struct timespec t1, t2;
|
||||||
|
EXPECT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &t1));
|
||||||
|
EXPECT_FALSE(result.value()->wait(1000 /*ms*/)); // false because wait should timeout
|
||||||
|
EXPECT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &t2));
|
||||||
|
long long time1 = t1.tv_sec * 1000000000LL + t1.tv_nsec;
|
||||||
|
long long time2 = t2.tv_sec * 1000000000LL + t2.tv_nsec;
|
||||||
|
EXPECT_GE(time2 - time1, 1000000000 /*ns*/); // 1000 ms as ns
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
RunProgram();
|
RunProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_FALSE(result.value()->isEmpty());
|
EXPECT_FALSE(result.value()->isEmpty());
|
||||||
|
|
||||||
|
EXPECT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &t1));
|
||||||
|
EXPECT_TRUE(result.value()->wait());
|
||||||
|
EXPECT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &t2));
|
||||||
|
time1 = t1.tv_sec * 1000000000LL + t1.tv_nsec;
|
||||||
|
time2 = t2.tv_sec * 1000000000LL + t2.tv_nsec;
|
||||||
|
EXPECT_LE(time2 - time1, 1000000 /*ns*/); // in x86 CF testing < 5000 ns
|
||||||
|
|
||||||
EXPECT_THAT(result.value()->ConsumeAll(callback), HasValue(n));
|
EXPECT_THAT(result.value()->ConsumeAll(callback), HasValue(n));
|
||||||
EXPECT_TRUE(result.value()->isEmpty());
|
EXPECT_TRUE(result.value()->isEmpty());
|
||||||
EXPECT_EQ(output, TEST_RINGBUF_MAGIC_NUM);
|
EXPECT_EQ(output, TEST_RINGBUF_MAGIC_NUM);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <android-base/result.h>
|
#include <android-base/result.h>
|
||||||
#include <android-base/unique_fd.h>
|
#include <android-base/unique_fd.h>
|
||||||
#include <linux/bpf.h>
|
#include <linux/bpf.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
|
|
||||||
@@ -41,6 +42,9 @@ class BpfRingbufBase {
|
|||||||
|
|
||||||
bool isEmpty(void);
|
bool isEmpty(void);
|
||||||
|
|
||||||
|
// returns !isEmpty() for convenience
|
||||||
|
bool wait(int timeout_ms = -1);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Non-initializing constructor, used by Create.
|
// Non-initializing constructor, used by Create.
|
||||||
BpfRingbufBase(size_t value_size) : mValueSize(value_size) {}
|
BpfRingbufBase(size_t value_size) : mValueSize(value_size) {}
|
||||||
@@ -200,12 +204,21 @@ inline base::Result<void> BpfRingbufBase::Init(const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool BpfRingbufBase::isEmpty(void) {
|
inline bool BpfRingbufBase::isEmpty(void) {
|
||||||
uint32_t prod_pos = mProducerPos->load(std::memory_order_acquire);
|
uint32_t prod_pos = mProducerPos->load(std::memory_order_relaxed);
|
||||||
// Only userspace writes to mConsumerPos, so no need to use std::memory_order_acquire
|
|
||||||
uint64_t cons_pos = mConsumerPos->load(std::memory_order_relaxed);
|
uint64_t cons_pos = mConsumerPos->load(std::memory_order_relaxed);
|
||||||
return (cons_pos & 0xFFFFFFFF) == prod_pos;
|
return (cons_pos & 0xFFFFFFFF) == prod_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool BpfRingbufBase::wait(int timeout_ms) {
|
||||||
|
// possible optimization: if (!isEmpty()) return true;
|
||||||
|
struct pollfd pfd = { // 1-element array
|
||||||
|
.fd = mRingFd.get(),
|
||||||
|
.events = POLLIN,
|
||||||
|
};
|
||||||
|
(void)poll(&pfd, 1, timeout_ms); // 'best effort' poll
|
||||||
|
return !isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
inline base::Result<int> BpfRingbufBase::ConsumeAll(
|
inline base::Result<int> BpfRingbufBase::ConsumeAll(
|
||||||
const std::function<void(const void*)>& callback) {
|
const std::function<void(const void*)>& callback) {
|
||||||
int64_t count = 0;
|
int64_t count = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user