Home | History | Annotate | Download | only in power
      1 /*
      2  * Copyright (c) 2014 Google, Inc.  All Rights Reserved.
      3  * Copyright (c) 2015 NVIDIA, Inc.  All Rights Reserved.
      4  *
      5  */
      6 #include "timed_qos_manager.h"
      7 #include <fcntl.h>
      8 #include <assert.h>
      9 
     10 #undef LOG_TAG
     11 #define LOG_TAG "powerHAL::TimedQosManager"
     12 
     13 void SysfsQosObject::enter()
     14 {
     15     sysfs_write(mNodeName, mEnterCmd);
     16 }
     17 
     18 void SysfsQosObject::exit()
     19 {
     20     sysfs_write(mNodeName, mExitCmd);
     21 }
     22 
     23 bool TimedQosManager::threadLoop()
     24 {
     25     AutoMutex lock(mLock);
     26 
     27     ALOGI("threadLoop [%s] starting\n", mName);
     28 
     29     while (1) {
     30         if (exitPending()) {
     31             ALOGV("threadLoop [%s] exiting\n", mName);
     32             break;
     33         }
     34         if (mTargetTime == 0) {
     35             // wait for something to do
     36             ALOGV("threadLoop [%s] nothing to do, waiting\n", mName);
     37             mCondition.wait(mLock);
     38             ALOGV("threadLoop [%s] woke from wait\n", mName);
     39         } else {
     40             // open qos file if not already open
     41             mQosObject->enter();
     42 
     43             // wait for target time to expire
     44             nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
     45             ALOGV("threadLoop [%s] waiting with relative time %lld\n",
     46                     mName, mTargetTime - currentTime);
     47             mCondition.waitRelative(mLock, mTargetTime - currentTime);
     48 
     49             // check if we're done.  if not (typically because
     50             // someone extended our time while we were blocked)
     51             // just loop again and sleep until new target time
     52             currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
     53             if (currentTime >= mTargetTime) {
     54                 mQosObject->exit();
     55                 mTargetTime = 0;
     56             } else {
     57                 ALOGV("threadLoop [%s] timeout extended\n");
     58             }
     59         }
     60     }
     61     return false;
     62 }
     63 
     64 void TimedQosManager::requestTimedQos(nsecs_t reltime)
     65 {
     66     AutoMutex lock(mLock);
     67     nsecs_t targetTime = systemTime() + reltime;
     68 
     69     /* new target time should always be ahead of current one */
     70     assert(mTargetTime <= targetTime);
     71     mTargetTime = targetTime;
     72     ALOGV("threadLoop [%s] requesting reltime %lld, mTargetTime set to %lld\n",
     73           mName, reltime, mTargetTime);
     74 
     75     /* wake the Thread.  if it's already waiting on a different
     76      * timeout, this will just wake it early and it'll wait again.
     77      */
     78     mCondition.signal(Condition::WAKE_UP_ALL);
     79 }
     80