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
enter()13 void SysfsQosObject::enter()
14 {
15 sysfs_write(mNodeName, mEnterCmd);
16 }
17
exit()18 void SysfsQosObject::exit()
19 {
20 sysfs_write(mNodeName, mExitCmd);
21 }
22
threadLoop()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
requestTimedQos(nsecs_t reltime)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