From 7ef92c9684700a19eef5f4e71d8261535bbdded8 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Sun, 31 Dec 2017 23:26:50 -0800 Subject: libperfmgr: Retry when writing to node failed Test: libperfmgr_test Change-Id: Ia3d45293e25eec68e8b3867e969a37d039f4711b --- libperfmgr/HintManager.cc | 2 ++ libperfmgr/Node.cc | 14 +++++++++----- libperfmgr/NodeLooperThread.cc | 2 ++ libperfmgr/RequestGroup.cc | 2 ++ libperfmgr/tests/NodeTest.cc | 21 +++++++++++++++++++++ 5 files changed, 36 insertions(+), 5 deletions(-) (limited to 'libperfmgr') diff --git a/libperfmgr/HintManager.cc b/libperfmgr/HintManager.cc index 2444c7cb..135e55ae 100644 --- a/libperfmgr/HintManager.cc +++ b/libperfmgr/HintManager.cc @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "libperfmgr" + #include #include diff --git a/libperfmgr/Node.cc b/libperfmgr/Node.cc index 9f275ec5..6b24e9f2 100644 --- a/libperfmgr/Node.cc +++ b/libperfmgr/Node.cc @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "libperfmgr" + #include #include @@ -34,7 +36,7 @@ Node::Node(std::string name, std::string node_path, if (reset_on_init) { // Assigning an invalid value so the next Update() will update the // Node's value to default - current_val_index_ = req_sorted.size(); + current_val_index_ = req_sorted_.size(); Update(); } else { current_val_index_ = default_val_index; @@ -76,16 +78,16 @@ std::chrono::milliseconds Node::Update() { // Update node only if request index changes if (value_index != current_val_index_) { - current_val_index_ = value_index; - std::string req_value = - req_sorted_[current_val_index_].GetRequestValue(); + std::string req_value = req_sorted_[value_index].GetRequestValue(); fd_.reset(TEMP_FAILURE_RETRY( open(node_path_.c_str(), O_WRONLY | O_CLOEXEC | O_TRUNC))); if (fd_ == -1 || !android::base::WriteStringToFd(req_value, fd_)) { LOG(ERROR) << "Failed to write to node: " << node_path_ - << " with value: " << req_value; + << " with value: " << req_value << ", fd: " << fd_; + // Retry in 500ms or sooner + expire_time = std::min(expire_time, std::chrono::milliseconds(500)); } else { // For regular file system, we need fsync fsync(fd_); @@ -97,6 +99,8 @@ std::chrono::milliseconds Node::Update() { if ((!hold_fd_) || value_index == default_val_index_) { fd_.reset(); } + // Update current index only when succeed + current_val_index_ = value_index; } } return expire_time; diff --git a/libperfmgr/NodeLooperThread.cc b/libperfmgr/NodeLooperThread.cc index 5c7ba5a5..da7aa652 100644 --- a/libperfmgr/NodeLooperThread.cc +++ b/libperfmgr/NodeLooperThread.cc @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "libperfmgr" + #include #include diff --git a/libperfmgr/RequestGroup.cc b/libperfmgr/RequestGroup.cc index f2cb7aa0..1c7a96ae 100644 --- a/libperfmgr/RequestGroup.cc +++ b/libperfmgr/RequestGroup.cc @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "libperfmgr" + #include "perfmgr/RequestGroup.h" namespace android { diff --git a/libperfmgr/tests/NodeTest.cc b/libperfmgr/tests/NodeTest.cc index c5b97a1b..b1a384d2 100644 --- a/libperfmgr/tests/NodeTest.cc +++ b/libperfmgr/tests/NodeTest.cc @@ -50,6 +50,9 @@ TEST(NodeTest, InitDefaultTest) { TemporaryFile tf; Node t("t", tf.path, {{"value0"}, {"value1"}, {"value2"}}, 1, true); _VerifyPathValue(tf.path, "value1"); + TemporaryFile tf2; + Node t2("t2", tf2.path, {{"value0"}, {"value1"}, {"value2"}}, 0, true); + _VerifyPathValue(tf2.path, "value0"); } // Test GetValueIndex @@ -88,6 +91,24 @@ TEST(NodeTest, GetPropertiesTest) { EXPECT_TRUE(t.GetHoldFd()); } +// Test add request fail and retry +TEST(NodeTest, AddRequestTestFail) { + Node t("t", "/sys/android/nonexist_node_test", + {{"value0"}, {"value1"}, {"value2"}}, 2, true); + auto start = std::chrono::steady_clock::now(); + EXPECT_TRUE(t.AddRequest(1, "INTERACTION", start + 200ms)); + std::chrono::milliseconds expire_time = t.Update(); + // Add request @ value1 + EXPECT_NEAR(std::chrono::milliseconds(200).count(), expire_time.count(), + kTIMING_TOLERANCE_MS); + // Add request @ value0 higher prio than value1 + EXPECT_TRUE(t.AddRequest(0, "LAUNCH", start + 2000ms)); + expire_time = t.Update(); + // Retry in 500 ms + EXPECT_NEAR(std::chrono::milliseconds(500).count(), expire_time.count(), + kTIMING_TOLERANCE_MS); +} + // Test add request TEST(NodeTest, AddRequestTest) { TemporaryFile tf; -- cgit v1.2.3