1 /*
2  * Copyright (C) 2020 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 #ifndef CHRE_PLATFORM_SHARED_VOTE_CLIENT_H_
18 #define CHRE_PLATFORM_SHARED_VOTE_CLIENT_H_
19 
20 #include "chre/platform/mutex.h"
21 #include "chre/util/lock_guard.h"
22 #include "chre/util/singleton.h"
23 #include "chre/util/time.h"
24 
25 namespace chre {
26 
27 /**
28  * Class used to manage voting for access to DRAM for platforms that require
29  * voting for DRAM memory to be accessible.
30  */
31 class DramVoteClient : public NonCopyable {
32  public:
33   /**
34    * @return true if CHRE currently has a DRAM vote in place.
35    */
isDramVoteActive()36   bool isDramVoteActive() {
37     LockGuard<Mutex> lock(mMutex);
38     return mLastDramVote;
39   }
40 
41   /**
42    * Makes a DRAM access request. An actual vote to the memory manager may not
43    * be cast depending on the current mode and mDramVoteCount.
44    *
45    * @param enabled Whether to request DRAM access.
46    */
47   void voteDramAccess(bool enabled);
48 
49   /**
50    * Increment the DRAM vote count when a client needs to perform some DRAM
51    * activity. A DRAM vote is issued when the count increments from 0.
52    */
53   void incrementDramVoteCount();
54 
55   /**
56    * Decrement the DRAM vote count when a client finishes some activity that has
57    * to be performed in DRAM. A DRAM vote may be removed when the count
58    * decrements to 0, depending on if explicit DRAM votes have been issued from
59    * voteDramAccess.
60    */
61   void decrementDramVoteCount();
62 
63  private:
64   //! The maximum allowed duration to be voted into DRAM by
65   //! incrementDramVoteCount before a FATAL_ERROR is triggered.
66   static constexpr Seconds kMaxDramDuration = Seconds(300);
67 
68   //! Last DRAM request made through voteDramAccess().
69   bool mLastDramRequest = false;
70 
71   //! Last DRAM vote cast to the system.
72   bool mLastDramVote = false;
73 
74   //! The system time mDramVoteCount increments from 0.
75   Milliseconds mVoteCountStart = Milliseconds(0);
76 
77   //! The count of DRAM activities.
78   uint32_t mDramVoteCount = 0;
79 
80   //! Used to protect access to member variables from other threads.
81   Mutex mMutex;
82 
83   /**
84    * Issue a vote to the underlying system. This must be implemented by each
85    * platform to communicate with the right system.
86    *
87    * @param enabled Whether DRAM should be accessible.
88    */
89   void issueDramVote(bool enabled);
90 
91   /**
92    * Check how long the system has been voted into DRAM due to
93    * incrementDramVoteCount. If longer than kMaxDramDuration, trigger a crash.
94    *
95    * @return the duration in milliseconds since the system has been voted into
96    *         big image due to incrementDramVoteCount.
97    */
98   Milliseconds checkDramDuration() const;
99 };
100 
101 //! Provides an alias to the DramVoteClient singleton
102 typedef Singleton<DramVoteClient> DramVoteClientSingleton;
103 
104 extern template class Singleton<DramVoteClient>;
105 
106 }  // namespace chre
107 
108 #endif  // CHRE_PLATFORM_SHARED_VOTE_CLIENT_H_
109