summaryrefslogtreecommitdiffstats
path: root/power-libperfmgr/InteractionHandler.cpp
diff options
context:
space:
mode:
authorWei Wang <wvw@google.com>2020-02-21 10:25:38 -0800
committerWei Wang <wvw@google.com>2020-02-22 05:53:29 +0000
commit0772cc0ef3498f5beffb640377aab1f5f3c3a30e (patch)
tree4fc685a663a6ae0d4c093162a8abf9f505c9039d /power-libperfmgr/InteractionHandler.cpp
parent8e4e6b03921822c45b2d55706ca90e47cc1e2f78 (diff)
downloadplatform_hardware_google_pixel-0772cc0ef3498f5beffb640377aab1f5f3c3a30e.tar.gz
platform_hardware_google_pixel-0772cc0ef3498f5beffb640377aab1f5f3c3a30e.tar.bz2
platform_hardware_google_pixel-0772cc0ef3498f5beffb640377aab1f5f3c3a30e.zip
Split PowerHAL into HIDL impl and library
Bug: 147840817 Test: boot Change-Id: Ieb394e0433c4775e84e11e881898933ef93fd08d (cherry picked from commit 2bcf2514fd608493f4d7c6306bb933f7fec6ee24)
Diffstat (limited to 'power-libperfmgr/InteractionHandler.cpp')
-rw-r--r--power-libperfmgr/InteractionHandler.cpp251
1 files changed, 0 insertions, 251 deletions
diff --git a/power-libperfmgr/InteractionHandler.cpp b/power-libperfmgr/InteractionHandler.cpp
deleted file mode 100644
index da6a917..0000000
--- a/power-libperfmgr/InteractionHandler.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "android.hardware.power@1.3-service.pixel-libperfmgr"
-#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
-
-#include <fcntl.h>
-#include <poll.h>
-#include <sys/eventfd.h>
-#include <time.h>
-#include <unistd.h>
-#include <utils/Log.h>
-#include <utils/Trace.h>
-#include <memory>
-
-#include "InteractionHandler.h"
-
-#define MAX_LENGTH 64
-
-#define MSINSEC 1000L
-#define USINMS 1000000L
-
-static const std::vector<std::string> fb_idle_patch = {"/sys/class/drm/card0/device/idle_state",
- "/sys/class/graphics/fb0/idle_state"};
-
-InteractionHandler::InteractionHandler(std::shared_ptr<HintManager> const &hint_manager)
- : mState(INTERACTION_STATE_UNINITIALIZED),
- mWaitMs(100),
- mMinDurationMs(1400),
- mMaxDurationMs(5650),
- mDurationMs(0),
- mHintManager(hint_manager) {}
-
-InteractionHandler::~InteractionHandler() {
- Exit();
-}
-
-static int fb_idle_open(void) {
- int fd;
- for (auto &path : fb_idle_patch) {
- fd = open(path.c_str(), O_RDONLY);
- if (fd >= 0)
- return fd;
- }
- ALOGE("Unable to open fb idle state path (%d)", errno);
- return -1;
-}
-
-bool InteractionHandler::Init() {
- std::lock_guard<std::mutex> lk(mLock);
-
- if (mState != INTERACTION_STATE_UNINITIALIZED)
- return true;
-
- int fd = fb_idle_open();
- if (fd < 0)
- return false;
- mIdleFd = fd;
-
- mEventFd = eventfd(0, EFD_NONBLOCK);
- if (mEventFd < 0) {
- ALOGE("Unable to create event fd (%d)", errno);
- close(mIdleFd);
- return false;
- }
-
- mState = INTERACTION_STATE_IDLE;
- mThread = std::unique_ptr<std::thread>(new std::thread(&InteractionHandler::Routine, this));
-
- return true;
-}
-
-void InteractionHandler::Exit() {
- std::unique_lock<std::mutex> lk(mLock);
- if (mState == INTERACTION_STATE_UNINITIALIZED)
- return;
-
- AbortWaitLocked();
- mState = INTERACTION_STATE_UNINITIALIZED;
- lk.unlock();
-
- mCond.notify_all();
- mThread->join();
-
- close(mEventFd);
- close(mIdleFd);
-}
-
-void InteractionHandler::PerfLock() {
- ALOGV("%s: acquiring perf lock", __func__);
- if (!mHintManager->DoHint("INTERACTION")) {
- ALOGE("%s: do hint INTERACTION failed", __func__);
- }
- ATRACE_INT("interaction_lock", 1);
-}
-
-void InteractionHandler::PerfRel() {
- ALOGV("%s: releasing perf lock", __func__);
- if (!mHintManager->EndHint("INTERACTION")) {
- ALOGE("%s: end hint INTERACTION failed", __func__);
- }
- ATRACE_INT("interaction_lock", 0);
-}
-
-size_t InteractionHandler::CalcTimespecDiffMs(struct timespec start, struct timespec end) {
- size_t diff_in_us = 0;
- diff_in_us += (end.tv_sec - start.tv_sec) * MSINSEC;
- diff_in_us += (end.tv_nsec - start.tv_nsec) / USINMS;
- return diff_in_us;
-}
-
-void InteractionHandler::Acquire(int32_t duration) {
- ATRACE_CALL();
-
- std::lock_guard<std::mutex> lk(mLock);
- if (mState == INTERACTION_STATE_UNINITIALIZED) {
- ALOGW("%s: called while uninitialized", __func__);
- return;
- }
-
- int inputDuration = duration + 650;
- int finalDuration;
- if (inputDuration > mMaxDurationMs)
- finalDuration = mMaxDurationMs;
- else if (inputDuration > mMinDurationMs)
- finalDuration = inputDuration;
- else
- finalDuration = mMinDurationMs;
-
- struct timespec cur_timespec;
- clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
- if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) {
- size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec);
- // don't hint if previous hint's duration covers this hint's duration
- if (elapsed_time <= (mDurationMs - finalDuration)) {
- ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld", __func__,
- static_cast<int>(mDurationMs), static_cast<int>(finalDuration),
- static_cast<long long>(elapsed_time));
- return;
- }
- }
- mLastTimespec = cur_timespec;
- mDurationMs = finalDuration;
-
- ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration);
-
- if (mState == INTERACTION_STATE_WAITING)
- AbortWaitLocked();
- else if (mState == INTERACTION_STATE_IDLE)
- PerfLock();
-
- mState = INTERACTION_STATE_INTERACTION;
- mCond.notify_one();
-}
-
-void InteractionHandler::Release() {
- std::lock_guard<std::mutex> lk(mLock);
- if (mState == INTERACTION_STATE_WAITING) {
- ATRACE_CALL();
- PerfRel();
- mState = INTERACTION_STATE_IDLE;
- } else {
- // clear any wait aborts pending in event fd
- uint64_t val;
- ssize_t ret = read(mEventFd, &val, sizeof(val));
-
- ALOGW_IF(ret < 0, "%s: failed to clear eventfd (%zd, %d)", __func__, ret, errno);
- }
-}
-
-// should be called while locked
-void InteractionHandler::AbortWaitLocked() {
- uint64_t val = 1;
- ssize_t ret = write(mEventFd, &val, sizeof(val));
- if (ret != sizeof(val))
- ALOGW("Unable to write to event fd (%zd)", ret);
-}
-
-void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) {
- char data[MAX_LENGTH];
- ssize_t ret;
- struct pollfd pfd[2];
-
- ATRACE_CALL();
-
- ALOGV("%s: wait:%d timeout:%d", __func__, wait_ms, timeout_ms);
-
- pfd[0].fd = mEventFd;
- pfd[0].events = POLLIN;
- pfd[1].fd = mIdleFd;
- pfd[1].events = POLLPRI | POLLERR;
-
- ret = poll(pfd, 1, wait_ms);
- if (ret > 0) {
- ALOGV("%s: wait aborted", __func__);
- return;
- } else if (ret < 0) {
- ALOGE("%s: error in poll while waiting", __func__);
- return;
- }
-
- ret = pread(mIdleFd, data, sizeof(data), 0);
- if (!ret) {
- ALOGE("%s: Unexpected EOF!", __func__);
- return;
- }
-
- if (!strncmp(data, "idle", 4)) {
- ALOGV("%s: already idle", __func__);
- return;
- }
-
- ret = poll(pfd, 2, timeout_ms);
- if (ret < 0)
- ALOGE("%s: Error on waiting for idle (%zd)", __func__, ret);
- else if (ret == 0)
- ALOGV("%s: timed out waiting for idle", __func__);
- else if (pfd[0].revents)
- ALOGV("%s: wait for idle aborted", __func__);
- else if (pfd[1].revents)
- ALOGV("%s: idle detected", __func__);
-}
-
-void InteractionHandler::Routine() {
- std::unique_lock<std::mutex> lk(mLock, std::defer_lock);
-
- while (true) {
- lk.lock();
- mCond.wait(lk, [&] { return mState != INTERACTION_STATE_IDLE; });
- if (mState == INTERACTION_STATE_UNINITIALIZED)
- return;
- mState = INTERACTION_STATE_WAITING;
- lk.unlock();
-
- WaitForIdle(mWaitMs, mDurationMs);
- Release();
- }
-}