1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #ifndef ANDROID_TIME_CHECK_H
19 #define ANDROID_TIME_CHECK_H
20 
21 #include <utils/KeyedVector.h>
22 #include <utils/Thread.h>
23 #include <vector>
24 
25 namespace android {
26 
27 // A class monitoring execution time for a code block (scoped variable) and causing an assert
28 // if it exceeds a certain time
29 
30 class TimeCheck {
31 public:
32 
33     // The default timeout is chosen to be less than system server watchdog timeout
34     static constexpr uint32_t kDefaultTimeOutMs = 5000;
35 
36             TimeCheck(const char *tag, uint32_t timeoutMs = kDefaultTimeOutMs);
37             ~TimeCheck();
38     static  void setAudioHalPids(const std::vector<pid_t>& pids);
39     static  std::vector<pid_t> getAudioHalPids();
40 
41 private:
42 
43     class TimeCheckThread : public Thread {
44     public:
45 
TimeCheckThread()46                             TimeCheckThread() {}
47         virtual             ~TimeCheckThread() override;
48 
49                 nsecs_t     startMonitoring(const char *tag, uint32_t timeoutMs);
50                 void        stopMonitoring(nsecs_t endTimeNs);
51 
52     private:
53 
54                 // RefBase
onFirstRef()55         virtual void        onFirstRef() override { run("TimeCheckThread", PRIORITY_URGENT_AUDIO); }
56 
57                 // Thread
58         virtual bool        threadLoop() override;
59 
60                 Condition           mCond;
61                 Mutex               mMutex;
62                 // using the end time in ns as key is OK given the risk is low that two entries
63                 // are added in such a way that <add time> + <timeout> are the same for both.
64                 KeyedVector< nsecs_t, const char*>  mMonitorRequests;
65     };
66 
67     static sp<TimeCheckThread> getTimeCheckThread();
68     static void accessAudioHalPids(std::vector<pid_t>* pids, bool update);
69 
70     const           nsecs_t mEndTimeNs;
71 };
72 
73 }; // namespace android
74 
75 #endif  // ANDROID_TIME_CHECK_H
76