NNAPI Concurrent Query Management -- HAL and VTS update
The NNAPI requires requests on a model to be asynchronously
processed. This CL implements a basic Event that can later
be used to block the runtime thread until the asynchronous
request has completed.
Bug: 63905942
Test: VtsHalNeuralnetworksV1_0TargetTest (32-bit, 64-bit) with sample driver enabled by cherry-pick
frameworks/ml/nn/runtime/test with and without sample driver enabled
Change-Id: Ie27a574aaaac312e7cbb731750f9c06278357a1c
diff --git a/neuralnetworks/1.0/vts/functional/Event.cpp b/neuralnetworks/1.0/vts/functional/Event.cpp
new file mode 100644
index 0000000..0fab86b
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/Event.cpp
@@ -0,0 +1,76 @@
+#include "Event.h"
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_0 {
+namespace implementation {
+
+Event::Event() : mStatus(Status::WAITING) {}
+
+Event::~Event() {
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+}
+
+Return<void> Event::notify(ReturnedStatus status) {
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mStatus = status == ReturnedStatus::SUCCESS ? Status::SUCCESS : Status::ERROR;
+ if (mStatus == Status::SUCCESS && mCallback != nullptr) {
+ bool success = mCallback();
+ if (!success) {
+ LOG(ERROR) << "Event::notify -- callback failed";
+ }
+ }
+ }
+ mCondition.notify_all();
+ return Void();
+}
+
+Event::Status Event::poll() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mStatus;
+}
+
+Event::Status Event::wait() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this]{return mStatus != Status::WAITING;});
+ return mStatus;
+}
+
+bool Event::on_finish(std::function<bool(void)> callback) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mCallback != nullptr) {
+ LOG(ERROR) << "Event::on_finish -- a callback has already been bound to this event";
+ return false;
+ }
+ if (callback == nullptr) {
+ LOG(ERROR) << "Event::on_finish -- the new callback is invalid";
+ return false;
+ }
+ mCallback = std::move(callback);
+ return true;
+}
+
+bool Event::bind_thread(std::thread&& asyncThread) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mThread.joinable()) {
+ LOG(ERROR) << "Event::bind_thread -- a thread has already been bound to this event";
+ return false;
+ }
+ if (!asyncThread.joinable()) {
+ LOG(ERROR) << "Event::bind_thread -- the new thread is not joinable";
+ return false;
+ }
+ mThread = std::move(asyncThread);
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace neuralnetworks
+} // namespace hardware
+} // namespace android