xref: /aosp_15_r20/external/executorch/backends/mediatek/runtime/include/api/APUWareUtilsLib.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1 /*
2  * Copyright (C) 2023 MediaTek Inc., this file is modified on 02/26/2021
3  * by MediaTek Inc. based on MIT License .
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the ""Software""), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 
23 #pragma once
24 
25 #include <android/log.h>
26 #include <dlfcn.h>
27 #include <cstdlib>
28 #include <memory>
29 #include <string>
30 #include <thread>
31 #include <utility>
32 using namespace std;
33 
34 typedef enum {
35   LOW_POWER_MODE = 0, // For model execution preference
36   FAST_SINGLE_ANSWER_MODE, // For model execution preference
37   SUSTAINED_SPEED_MODE, // For model execution preference
38   FAST_COMPILE_MODE, // For model compile preference
39   PERFORMANCE_MODE_MAX,
40 } PERFORMANCE_MODE_E;
41 
42 //------------------------------------- -------------------------------------
43 #define APUWARE_LOG_D(format, ...) \
44   __android_log_print(             \
45       ANDROID_LOG_DEBUG, "APUWARELIB", format "\n", ##__VA_ARGS__);
46 
47 #define APUWARE_LOG_E(format, ...) \
48   __android_log_print(             \
49       ANDROID_LOG_ERROR, "APUWARELIB", format "\n", ##__VA_ARGS__);
50 
voidFunction()51 inline void* voidFunction() {
52   return nullptr;
53 }
54 
55 // ApuWareUtils library construct
56 struct ApuWareUtilsLib {
GetInstanceApuWareUtilsLib57   static struct ApuWareUtilsLib& GetInstance() {
58     static struct ApuWareUtilsLib instance;
59     return instance;
60   }
61 
ApuWareUtilsLibApuWareUtilsLib62   ApuWareUtilsLib() {
63     load();
64   }
65 
66   using AcquirePerformanceLockPtr =
67       std::add_pointer<int32_t(int32_t, PERFORMANCE_MODE_E, uint32_t)>::type;
68   using AcquirePerfParamsLockPtr =
69       std::add_pointer<int32_t(int32_t, uint32_t, int32_t[], uint32_t)>::type;
70   using ReleasePerformanceLockPtr = std::add_pointer<bool(int32_t)>::type;
71 
72   // Open a given library and load symbols
loadApuWareUtilsLib73   bool load() {
74     void* handle = nullptr;
75     const std::string libraries[] = {
76         "libapuwareutils_v2.mtk.so", "libapuwareutils.mtk.so"};
77     for (const auto& lib : libraries) {
78       handle = dlopen(lib.c_str(), RTLD_LAZY | RTLD_LOCAL);
79       if (handle) {
80         APUWARE_LOG_D("dlopen %s", lib.c_str());
81         acquirePerformanceLock =
82             reinterpret_cast<decltype(acquirePerformanceLock)>(
83                 dlsym(handle, "acquirePerformanceLockInternal"));
84         acquirePerfParamsLock =
85             reinterpret_cast<decltype(acquirePerfParamsLock)>(
86                 dlsym(handle, "acquirePerfParamsLockInternal"));
87         releasePerformanceLock =
88             reinterpret_cast<decltype(releasePerformanceLock)>(
89                 dlsym(handle, "releasePerformanceLockInternal"));
90         return mEnable = acquirePerformanceLock && releasePerformanceLock &&
91             acquirePerfParamsLock;
92       } else {
93         APUWARE_LOG_E("unable to open library %s", lib.c_str());
94       }
95     }
96     return false;
97   }
98 
99   bool mEnable = false;
100 
101   AcquirePerformanceLockPtr acquirePerformanceLock =
102       reinterpret_cast<decltype(acquirePerformanceLock)>(voidFunction);
103   AcquirePerfParamsLockPtr acquirePerfParamsLock =
104       reinterpret_cast<decltype(acquirePerfParamsLock)>(voidFunction);
105   ReleasePerformanceLockPtr releasePerformanceLock =
106       reinterpret_cast<decltype(releasePerformanceLock)>(voidFunction);
107 };
108 
109 class ScopePerformancer {
110  public:
111   ScopePerformancer(uint32_t ms = 2000)
mLib(ApuWareUtilsLib::GetInstance ())112       : mLib(ApuWareUtilsLib::GetInstance()), mMs(ms) {
113     mLock = mLib.mEnable;
114     if (mLock) {
115       APUWARE_LOG_D("Powerhal Up");
116       mRunning.store(true);
117       mThread = std::thread(&ScopePerformancer::acquireLockRepeatedly, this);
118     }
119   };
120 
Stop()121   void Stop() {
122     if (mRunning.load()) {
123       mRunning.store(false);
124       mCond.notify_one();
125     }
126   }
127 
~ScopePerformancer()128   ~ScopePerformancer() {
129     Stop();
130     if (mThread.joinable()) {
131       mThread.join();
132     }
133     if (mHalHandle != 0 && mLock) {
134       APUWARE_LOG_D("Powerhal Free");
135       mLib.releasePerformanceLock(mHalHandle);
136       mHalHandle = 0;
137     }
138   }
139 
140  private:
acquireLockRepeatedly()141   void acquireLockRepeatedly() {
142     std::unique_lock<std::mutex> lock(mMutex);
143     while (mRunning.load()) {
144       mHalHandle =
145           mLib.acquirePerformanceLock(mHalHandle, FAST_SINGLE_ANSWER_MODE, mMs);
146       mCond.wait_for(lock, std::chrono::milliseconds(1000), [this] {
147         return !mRunning.load();
148       });
149     }
150   }
151 
152   struct ApuWareUtilsLib mLib;
153 
154   bool mLock = false;
155 
156   int mHalHandle = 0;
157 
158   uint32_t mMs;
159 
160   std::atomic<bool> mRunning{false};
161 
162   std::thread mThread;
163 
164   std::mutex mMutex;
165 
166   std::condition_variable mCond;
167 };