summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShunkai Yao <yaoshunkai@google.com>2024-01-30 01:53:24 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2024-01-30 01:53:24 +0000
commitf58e2ee24e31c05e77a4e8a10b8b1b53643792e1 (patch)
tree0e7b680e5b0e8d124cc0924d38a348e5b2b9f371
parent3aa16b08350ecd2ecc8fe4db0cf11fc973c02d84 (diff)
parentc459e6947807cdb8e7d05b3f89ed44e9693a8bf4 (diff)
downloadlibfmq-f58e2ee24e31c05e77a4e8a10b8b1b53643792e1.tar.gz
Merge "libfmq: wait EventFlag before timeout check" into main am: c459e69478
Original change: https://android-review.googlesource.com/c/platform/system/libfmq/+/2933575 Change-Id: Icc473bcf110490ccc520dc5c34b91975d5c92c4f Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--EventFlag.cpp10
-rw-r--r--tests/fmq_unit_tests.cpp72
2 files changed, 77 insertions, 5 deletions
diff --git a/EventFlag.cpp b/EventFlag.cpp
index d353873..8cf2760 100644
--- a/EventFlag.cpp
+++ b/EventFlag.cpp
@@ -171,6 +171,11 @@ status_t EventFlag::wait(uint32_t bitmask,
int64_t prevTimeNs = shouldTimeOut ? android::elapsedRealtimeNano() : 0;
status_t status;
while (true) {
+ status = waitHelper(bitmask, efState, timeoutNanoSeconds);
+ if ((status != -EAGAIN) && (status != -EINTR)) {
+ break;
+ }
+
if (shouldTimeOut) {
int64_t currentTimeNs = android::elapsedRealtimeNano();
/*
@@ -185,11 +190,6 @@ status_t EventFlag::wait(uint32_t bitmask,
break;
}
}
-
- status = waitHelper(bitmask, efState, timeoutNanoSeconds);
- if ((status != -EAGAIN) && (status != -EINTR)) {
- break;
- }
}
return status;
}
diff --git a/tests/fmq_unit_tests.cpp b/tests/fmq_unit_tests.cpp
index 08790c8..96a8261 100644
--- a/tests/fmq_unit_tests.cpp
+++ b/tests/fmq_unit_tests.cpp
@@ -695,6 +695,78 @@ TYPED_TEST(BlockingReadWrites, BlockingTimeOutTest) {
}
/*
+ * Test EventFlag wait on a waked flag with a short timeout.
+ */
+TYPED_TEST(BlockingReadWrites, ShortEventFlagWaitWithWakeTest) {
+ std::atomic<uint32_t> eventFlagWord;
+ std::atomic_init(&eventFlagWord, static_cast<uint32_t>(kFmqNotFull));
+ android::hardware::EventFlag* efGroup = nullptr;
+ android::status_t status =
+ android::hardware::EventFlag::createEventFlag(&eventFlagWord, &efGroup);
+ ASSERT_EQ(android::NO_ERROR, status);
+ ASSERT_NE(nullptr, efGroup);
+
+ status = efGroup->wake(kFmqNotEmpty);
+ ASSERT_EQ(android::NO_ERROR, status);
+
+ uint32_t efState = 0;
+ android::status_t ret = efGroup->wait(kFmqNotEmpty, &efState, 1 /* ns */, true /* retry */);
+ ASSERT_EQ(android::NO_ERROR, ret);
+
+ status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
+ ASSERT_EQ(android::NO_ERROR, status);
+}
+
+/*
+ * Test on an EventFlag with no wakeup, short timeout.
+ */
+TYPED_TEST(BlockingReadWrites, ShortEventFlagWaitWithoutWakeTest) {
+ std::atomic<uint32_t> eventFlagWord;
+ std::atomic_init(&eventFlagWord, static_cast<uint32_t>(kFmqNotFull));
+ android::hardware::EventFlag* efGroup = nullptr;
+ android::status_t status =
+ android::hardware::EventFlag::createEventFlag(&eventFlagWord, &efGroup);
+ ASSERT_EQ(android::NO_ERROR, status);
+ ASSERT_NE(nullptr, efGroup);
+
+ uint32_t efState = 0;
+ android::status_t ret = efGroup->wait(kFmqNotEmpty, &efState, 1 /* ns */, true /* retry */);
+ ASSERT_EQ(android::TIMED_OUT, ret);
+
+ status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
+ ASSERT_EQ(android::NO_ERROR, status);
+}
+
+/*
+ * Test FMQ write and read with event flag wait.
+ */
+TYPED_TEST(BlockingReadWrites, FmqWriteAndReadWithShortEventFlagWaitTest) {
+ android::hardware::EventFlag* efGroup = nullptr;
+ android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup);
+ ASSERT_EQ(android::NO_ERROR, status);
+ ASSERT_NE(nullptr, efGroup);
+
+ /*
+ * After waiting for some time write into the FMQ
+ * and call Wake on kFmqNotEmpty.
+ */
+ const size_t dataLen = 16;
+ uint8_t dataW[dataLen] = {0};
+ uint8_t dataR[dataLen] = {0};
+ ASSERT_TRUE(this->mQueue->write(dataW, dataLen));
+ status = efGroup->wake(kFmqNotEmpty);
+ ASSERT_EQ(android::NO_ERROR, status);
+
+ ASSERT_TRUE(this->mQueue->readBlocking(dataR, dataLen, static_cast<uint32_t>(kFmqNotEmpty),
+ static_cast<uint32_t>(kFmqNotFull), 1 /* timeOutNanos */,
+ efGroup));
+ ASSERT_EQ(0, memcmp(dataW, dataR, dataLen));
+
+ status = android::hardware::EventFlag::deleteEventFlag(&efGroup);
+ ASSERT_EQ(android::NO_ERROR, status);
+}
+
+/*
* Test that odd queue sizes do not cause unaligned error
* on access to EventFlag object.
*/