1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef __FFRT_CPU_BOOST_OHOS_H__
17 #define __FFRT_CPU_BOOST_OHOS_H__
18 #include <string>
19 #include <dlfcn.h>
20 #include "dfx/log/ffrt_log_api.h"
21 
22 namespace ffrt {
23 int cpu_boost_start(int ctx_id);
24 int cpu_boost_end(int ctx_id);
25 int cpu_boost_save(int ctx_id);
26 int cpu_boost_restore(int ctx_id);
27 constexpr const char* CPU_BOOST_LIB_PATH = "lib_cpuboost.so";
28 class CPUBoostAdapter {
29 public:
CPUBoostAdapter()30     CPUBoostAdapter()
31     {
32         Load();
33     }
34 
~CPUBoostAdapter()35     ~CPUBoostAdapter()
36     {
37         UnLoad();
38     }
39 
Instance()40     static CPUBoostAdapter* Instance()
41     {
42         static CPUBoostAdapter instance;
43         return &instance;
44     }
45 
46 #define REG_FUNC(func) using func##Type = decltype(func)*; func##Type func##Temp = nullptr
47     REG_FUNC(cpu_boost_start);
48     REG_FUNC(cpu_boost_end);
49     REG_FUNC(cpu_boost_save);
50     REG_FUNC(cpu_boost_restore);
51 #undef REG_FUNC
52 
53 private:
Load()54     bool Load()
55     {
56         if (handle != nullptr) {
57             FFRT_LOGD("handle exits");
58             return true;
59         }
60 
61         handle = dlopen(CPU_BOOST_LIB_PATH, RTLD_NOW | RTLD_LOCAL);
62         if (handle == nullptr) {
63             FFRT_LOGE("load so[%s] fail", CPU_BOOST_LIB_PATH);
64             return false;
65         }
66 
67         bool loadFlag = true;
68 
69 #define LOAD_FUNC(x) x##Temp = reinterpret_cast<x##Type>(dlsym(handle, #x)); \
70         if (x##Temp == nullptr) { \
71             FFRT_LOGE("load func %s from %s failed", #x, CPU_BOOST_LIB_PATH); \
72             loadFlag = false; \
73         }
74             LOAD_FUNC(cpu_boost_start);
75             LOAD_FUNC(cpu_boost_end);
76             LOAD_FUNC(cpu_boost_save);
77             LOAD_FUNC(cpu_boost_restore);
78 #undef LOAD_FUNC
79         return loadFlag;
80     }
81 
UnLoad()82     bool UnLoad()
83     {
84         if (handle != nullptr) {
85             if (dlclose(handle) != 0) {
86                 return false;
87             }
88             handle = nullptr;
89             return true;
90         }
91         return true;
92     }
93 
94     void* handle = nullptr;
95 };
96 
97 #define EXECUTE_CPU_BOOST_FUNC(x, ctx_id, ret) auto func = CPUBoostAdapter::Instance()->x##Temp; \
98         if (func != nullptr) { \
99             ret = (func)(ctx_id); \
100         } else { \
101             ret = -1; \
102         }
103 
CpuBoostStart(int ctx_id)104 inline int CpuBoostStart(int ctx_id)
105 {
106     int ret = 0;
107     EXECUTE_CPU_BOOST_FUNC(cpu_boost_start, ctx_id, ret);
108     return ret;
109 }
110 
CpuBoostEnd(int ctx_id)111 inline int CpuBoostEnd(int ctx_id)
112 {
113     int ret = 0;
114     EXECUTE_CPU_BOOST_FUNC(cpu_boost_end, ctx_id, ret);
115     return ret;
116 }
117 
CpuBoostSave(int ctx_id)118 inline int CpuBoostSave(int ctx_id)
119 {
120     int ret = 0;
121     EXECUTE_CPU_BOOST_FUNC(cpu_boost_save, ctx_id, ret);
122     return ret;
123 }
124 
CpuBoostRestore(int ctx_id)125 inline int CpuBoostRestore(int ctx_id)
126 {
127     int ret = 0;
128     EXECUTE_CPU_BOOST_FUNC(cpu_boost_restore, ctx_id, ret);
129     return ret;
130 }
131 }
132 #endif