1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci
16484543d1Sopenharmony_ci#ifndef __FFRT_CPU_BOOST_OHOS_H__
17484543d1Sopenharmony_ci#define __FFRT_CPU_BOOST_OHOS_H__
18484543d1Sopenharmony_ci#include <string>
19484543d1Sopenharmony_ci#include <dlfcn.h>
20484543d1Sopenharmony_ci#include "dfx/log/ffrt_log_api.h"
21484543d1Sopenharmony_ci
22484543d1Sopenharmony_cinamespace ffrt {
23484543d1Sopenharmony_ciint cpu_boost_start(int ctx_id);
24484543d1Sopenharmony_ciint cpu_boost_end(int ctx_id);
25484543d1Sopenharmony_ciint cpu_boost_save(int ctx_id);
26484543d1Sopenharmony_ciint cpu_boost_restore(int ctx_id);
27484543d1Sopenharmony_ciconstexpr const char* CPU_BOOST_LIB_PATH = "lib_cpuboost.so";
28484543d1Sopenharmony_ciclass CPUBoostAdapter {
29484543d1Sopenharmony_cipublic:
30484543d1Sopenharmony_ci    CPUBoostAdapter()
31484543d1Sopenharmony_ci    {
32484543d1Sopenharmony_ci        Load();
33484543d1Sopenharmony_ci    }
34484543d1Sopenharmony_ci
35484543d1Sopenharmony_ci    ~CPUBoostAdapter()
36484543d1Sopenharmony_ci    {
37484543d1Sopenharmony_ci        UnLoad();
38484543d1Sopenharmony_ci    }
39484543d1Sopenharmony_ci
40484543d1Sopenharmony_ci    static CPUBoostAdapter* Instance()
41484543d1Sopenharmony_ci    {
42484543d1Sopenharmony_ci        static CPUBoostAdapter instance;
43484543d1Sopenharmony_ci        return &instance;
44484543d1Sopenharmony_ci    }
45484543d1Sopenharmony_ci
46484543d1Sopenharmony_ci#define REG_FUNC(func) using func##Type = decltype(func)*; func##Type func##Temp = nullptr
47484543d1Sopenharmony_ci    REG_FUNC(cpu_boost_start);
48484543d1Sopenharmony_ci    REG_FUNC(cpu_boost_end);
49484543d1Sopenharmony_ci    REG_FUNC(cpu_boost_save);
50484543d1Sopenharmony_ci    REG_FUNC(cpu_boost_restore);
51484543d1Sopenharmony_ci#undef REG_FUNC
52484543d1Sopenharmony_ci
53484543d1Sopenharmony_ciprivate:
54484543d1Sopenharmony_ci    bool Load()
55484543d1Sopenharmony_ci    {
56484543d1Sopenharmony_ci        if (handle != nullptr) {
57484543d1Sopenharmony_ci            FFRT_LOGD("handle exits");
58484543d1Sopenharmony_ci            return true;
59484543d1Sopenharmony_ci        }
60484543d1Sopenharmony_ci
61484543d1Sopenharmony_ci        handle = dlopen(CPU_BOOST_LIB_PATH, RTLD_NOW | RTLD_LOCAL);
62484543d1Sopenharmony_ci        if (handle == nullptr) {
63484543d1Sopenharmony_ci            FFRT_LOGE("load so[%s] fail", CPU_BOOST_LIB_PATH);
64484543d1Sopenharmony_ci            return false;
65484543d1Sopenharmony_ci        }
66484543d1Sopenharmony_ci
67484543d1Sopenharmony_ci        bool loadFlag = true;
68484543d1Sopenharmony_ci
69484543d1Sopenharmony_ci#define LOAD_FUNC(x) x##Temp = reinterpret_cast<x##Type>(dlsym(handle, #x)); \
70484543d1Sopenharmony_ci        if (x##Temp == nullptr) { \
71484543d1Sopenharmony_ci            FFRT_LOGE("load func %s from %s failed", #x, CPU_BOOST_LIB_PATH); \
72484543d1Sopenharmony_ci            loadFlag = false; \
73484543d1Sopenharmony_ci        }
74484543d1Sopenharmony_ci            LOAD_FUNC(cpu_boost_start);
75484543d1Sopenharmony_ci            LOAD_FUNC(cpu_boost_end);
76484543d1Sopenharmony_ci            LOAD_FUNC(cpu_boost_save);
77484543d1Sopenharmony_ci            LOAD_FUNC(cpu_boost_restore);
78484543d1Sopenharmony_ci#undef LOAD_FUNC
79484543d1Sopenharmony_ci        return loadFlag;
80484543d1Sopenharmony_ci    }
81484543d1Sopenharmony_ci
82484543d1Sopenharmony_ci    bool UnLoad()
83484543d1Sopenharmony_ci    {
84484543d1Sopenharmony_ci        if (handle != nullptr) {
85484543d1Sopenharmony_ci            if (dlclose(handle) != 0) {
86484543d1Sopenharmony_ci                return false;
87484543d1Sopenharmony_ci            }
88484543d1Sopenharmony_ci            handle = nullptr;
89484543d1Sopenharmony_ci            return true;
90484543d1Sopenharmony_ci        }
91484543d1Sopenharmony_ci        return true;
92484543d1Sopenharmony_ci    }
93484543d1Sopenharmony_ci
94484543d1Sopenharmony_ci    void* handle = nullptr;
95484543d1Sopenharmony_ci};
96484543d1Sopenharmony_ci
97484543d1Sopenharmony_ci#define EXECUTE_CPU_BOOST_FUNC(x, ctx_id, ret) auto func = CPUBoostAdapter::Instance()->x##Temp; \
98484543d1Sopenharmony_ci        if (func != nullptr) { \
99484543d1Sopenharmony_ci            ret = (func)(ctx_id); \
100484543d1Sopenharmony_ci        } else { \
101484543d1Sopenharmony_ci            ret = -1; \
102484543d1Sopenharmony_ci        }
103484543d1Sopenharmony_ci
104484543d1Sopenharmony_ciinline int CpuBoostStart(int ctx_id)
105484543d1Sopenharmony_ci{
106484543d1Sopenharmony_ci    int ret = 0;
107484543d1Sopenharmony_ci    EXECUTE_CPU_BOOST_FUNC(cpu_boost_start, ctx_id, ret);
108484543d1Sopenharmony_ci    return ret;
109484543d1Sopenharmony_ci}
110484543d1Sopenharmony_ci
111484543d1Sopenharmony_ciinline int CpuBoostEnd(int ctx_id)
112484543d1Sopenharmony_ci{
113484543d1Sopenharmony_ci    int ret = 0;
114484543d1Sopenharmony_ci    EXECUTE_CPU_BOOST_FUNC(cpu_boost_end, ctx_id, ret);
115484543d1Sopenharmony_ci    return ret;
116484543d1Sopenharmony_ci}
117484543d1Sopenharmony_ci
118484543d1Sopenharmony_ciinline int CpuBoostSave(int ctx_id)
119484543d1Sopenharmony_ci{
120484543d1Sopenharmony_ci    int ret = 0;
121484543d1Sopenharmony_ci    EXECUTE_CPU_BOOST_FUNC(cpu_boost_save, ctx_id, ret);
122484543d1Sopenharmony_ci    return ret;
123484543d1Sopenharmony_ci}
124484543d1Sopenharmony_ci
125484543d1Sopenharmony_ciinline int CpuBoostRestore(int ctx_id)
126484543d1Sopenharmony_ci{
127484543d1Sopenharmony_ci    int ret = 0;
128484543d1Sopenharmony_ci    EXECUTE_CPU_BOOST_FUNC(cpu_boost_restore, ctx_id, ret);
129484543d1Sopenharmony_ci    return ret;
130484543d1Sopenharmony_ci}
131484543d1Sopenharmony_ci}
132484543d1Sopenharmony_ci#endif