!6 soc_perf仓库迁移

Merge pull request !6 from cuijiawei/master
This commit is contained in:
openharmony_ci
2023-05-24 03:32:19 +00:00
committed by Gitee
49 changed files with 4384 additions and 51 deletions
+47 -23
View File
@@ -1,36 +1,60 @@
# resourceschedule_soc_perf
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
## 统一调频
#### Software Architecture
Software architecture description
### 调频接口说明
#### Installation
当前可支持的调频接口说明
1. xxxx
2. xxxx
3. xxxx
| 接口 | 说明 |
|----------|-------|
| PerfRequest(int32_t cmdId, const std::string& msg) | 用于性能提频使用 |
| PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) | 用于性能提频使用且支持ON/OFF事件 |
| PowerLimitBoost(bool onOffTag, const std::string& msg) | 用于限制boost无法突破功耗限频 |
| ThermalLimitBoost(bool onOffTag, const std::string& msg) | 用于限制boost无法突破热限频 |
| LimitRequest(int32_t clientId, const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg) | 用于热或功耗模块的限频且支持多项值一同设置 |
#### Instructions
如表格所示,所有的调频接口都以cmdID为核心,将调频场景和调频参数互相关联,实现提频或者限频的功能。
带onOffTag参数的接口表示该接口支持ON/OFF的开关调频模式,一般用于生效时间不固定的长期调频事件,需要调用者手动开启或者关闭。
msg参数为拓展字符串信息,可承载例如调用客户端pid/tid等信息。
1. xxxx
2. xxxx
3. xxxx
### 调频配置说明
#### Contribution
当前configs目录下的配置文件
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
| 配置文件 | 说明 |
|----------|-------|
| socperf_resource_config.xml | 定义产品可支持的资源配置,例如CPU/GPU/DDR/NPU等 |
| socperf_boost_config.xml | 用于性能提频的配置文件 |
各个xml配置文件都需要按产品定制,不同产品的配置不相同。
对于指定的某产品,所有可支持配置的资源都定义在socperf_resource_config.xml内,支持单路径/多路径配置,任何资源都有唯一的resID。
socperf_boost_config.xml使用的cmdID不能重复。
#### Gitee Feature
### 调频使用举例
以点击提频事件为例。
点击场景提频为固定生效时间,无需使用ON/OFF手动开启或关闭,故使用PerfRequest接口即可。因此需要在合适的地方调用soc_perf提供的IPC接口PerfRequest实现提频请求。
资源调度服务对所有事件的采集有统一的入口,即资源调度框架对订阅事件的插件进行分发的机制,调频服务也依赖该机制实现对于各个需要调频的场景的感知。
调频服务已实现为一个单独的调频插件socperf_plugin,定义在/ressched/plugins/socperf_plugin目录下。
要实现点击场景的提频,分为点击事件插桩、事件上报给资源调度框架、框架给插件分发事件、生效调频服务四个步骤。
第一步,
ACE子系统仓内实现了对资源调度框架提供的可动态加载接口ReportData的封装,路径为/framework/base/ressched/ressched_report.h
并在/framework/core/gestures/click_recognizer.cpp增加了打点作为手势识别中对点击事件的判定
第二步,
通过动态加载libressched_client.z.so,调用资源调度框架提供的接口ReportData,ACE子系统将点击事件上报给全局资源调度子系统
第三步,
在资源调度框架里,点击事件类型定义在/ressched/interfaces/innerkits/ressched_client/include/res_type.h内,为RES_TYPE_CLICK_RECOGNIZE
由于调频插件socperf_plugin在初始化过程中已完成了对该点击事件的订阅,因此框架会在接受到事件通知时将点击事件分发给调频插件
第四步,
调频插件socperf_plugin对于点击事件分配了cmdIDPERF_REQUEST_CMD_ID_EVENT_CLICK,路径在/ressched/plugins/socperf_plugin/src/socperf_plugin.cpp下
通过调用调频服务提供的IPC接口PerfRequest,插件会给调频服务发送请求,实现点击提频功能。
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
+23 -28
View File
@@ -1,39 +1,34 @@
# resourceschedule_soc_perf
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
## SocPerf
#### 软件架构
软件架构说明
### Interfaces
Supported SocPerf interfaces description
#### 安装教程
| Interface | Description |
|----------|-------|
| PerfRequest(int32_t cmdId, const std::string& msg) | Used for Performace boost freq |
| PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) | Used for Performace boost freq and support ON/OFF |
| PowerLimitBoost(bool onOffTag, const std::string& msg) | Used for Power limit freq which cannot be boosted |
| ThermalLimitBoost(bool onOffTag, const std::string& msg) | Used for Thermal limit freq which cannot be boosted |
| LimitRequest(int32_t clientId, const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg) | Used for Power or Thermal limit freq and multiple freq items can be set together |
1. xxxx
2. xxxx
3. xxxx
All interfaces are based on the key parameter cmdID, cmdID connects scenes and configs, which is used to boost freq or limit freq.
Interface with parameter onOffTag means it support ON/OFF event. Normally, these interfaces are used for long-term event,
which needs user to turn on or turn off manually.
Parameter msg is used for extra information, like client's pid and tid.
#### 使用说明
### Configs
1. xxxx
2. xxxx
3. xxxx
Config files description
#### 参与贡献
| File | Description |
|----------|-------|
| socperf_resource_config.xml | Define resource which can be modifysuch as CPU/GPU/DDR/NPU |
| socperf_boost_config.xml | Config file used for Performace boost |
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
All xml files are different for particular products.
For specific product, all resources which could be modify are defined in socperf_resource_config.xml. Each resource has its own resID.
The cmdID in the socperf_boost_config.xml/socperf_resource_config.xml/socperf_thermal_config.xml must be different.
+72
View File
@@ -0,0 +1,72 @@
{
"name": "@ohos/soc_perf",
"description": "resource schedule service",
"version": "3.1",
"license": "Apache License 2.0",
"publishAs": "code-segment",
"segment": {
"destPath": "foundation/resourceschedule/resource_schedule_service/soc_perf"
},
"dirs": {},
"scripts": {},
"component": {
"name": "soc_perf",
"subsystem": "resourceschedule",
"syscap": [],
"features": [],
"adapted_system_type": [
"mini",
"small",
"standard"
],
"rom": "2048KB",
"ram": "10240KB",
"deps": {
"components": [
"c_utils",
"config_policy",
"eventhandler",
"hitrace_native",
"hiviewdfx_hilog_native",
"ipc",
"libxml2",
"safwk",
"samgr"
],
"third_party": []
},
"build": {
"group_type": {
"base_group" : [
"//foundation/resourceschedule/resource_schedule_service/soc_perf/profile:socperf_config"
],
"fwk_group" : [
"//foundation/resourceschedule/resource_schedule_service/soc_perf/interfaces/inner_api/socperf_client:socperf_client"
],
"service_group" : [
"//foundation/resourceschedule/resource_schedule_service/soc_perf/sa_profile:socperf_sa_profile",
"//foundation/resourceschedule/resource_schedule_service/soc_perf/services:socperf_server"
]
},
"inner_kits": [
{
"header": {
"header_base": "//foundation/resourceschedule/resource_schedule_service/soc_perf/interfaces/inner_api/socperf_client/include",
"header_files": [
"i_socperf_service.h",
"socperf_action_type.h",
"socperf_client.h",
"socperf_proxy.h"
]
},
"name": "//foundation/resourceschedule/resource_schedule_service/soc_perf/interfaces/inner_api/socperf_client:socperf_client"
}
],
"test": [
"//foundation/resourceschedule/resource_schedule_service/soc_perf/test/unittest:unittest",
"//foundation/resourceschedule/resource_schedule_service/soc_perf/test/fuzztest:fuzztest",
"//foundation/resourceschedule/resource_schedule_service/soc_perf/test/testutil:socperf_test"
]
}
}
}
+75
View File
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_COMMON_INCLUDE_SOCPERF_LOG_H
#define SOC_PERF_COMMON_INCLUDE_SOCPERF_LOG_H
#include "hilog/log.h"
namespace OHOS {
namespace SOCPERF {
#ifndef LOG_TAG_SOC_PERF
#define LOG_TAG_SOC_PERF "socperf"
#endif
#ifndef LOG_TAG_DOMAIN_ID_SOC_PERF
#define LOG_TAG_DOMAIN_ID_SOC_PERF 0xD001703
#endif
static constexpr OHOS::HiviewDFX::HiLogLabel SOC_PERF_LOG_LABEL = {
LOG_CORE,
LOG_TAG_DOMAIN_ID_SOC_PERF,
LOG_TAG_SOC_PERF
};
class SocPerfLog {
public:
SocPerfLog() = delete;
~SocPerfLog() = delete;
static bool IsDebugLogEnabled()
{
return isDebugLogEnabled_;
}
static void EnableDebugLog()
{
isDebugLogEnabled_ = true;
}
static void DisableDebugLog()
{
isDebugLogEnabled_ = false;
}
private:
static bool isDebugLogEnabled_;
};
#define SOC_PERF_PRINT_LOG(Level, fmt, ...) \
OHOS::HiviewDFX::HiLog::Level(SOC_PERF_LOG_LABEL, "[%{public}s]: " fmt, __FUNCTION__, ##__VA_ARGS__)
#define SOC_PERF_LOGD(fmt, ...) \
if (SocPerfLog::IsDebugLogEnabled()) \
SOC_PERF_PRINT_LOG(Debug, fmt, ##__VA_ARGS__)
#define SOC_PERF_LOGI(fmt, ...) SOC_PERF_PRINT_LOG(Info, fmt, ##__VA_ARGS__)
#define SOC_PERF_LOGW(fmt, ...) SOC_PERF_PRINT_LOG(Warn, fmt, ##__VA_ARGS__)
#define SOC_PERF_LOGE(fmt, ...) SOC_PERF_PRINT_LOG(Error, fmt, ##__VA_ARGS__)
#define SOC_PERF_LOGF(fmt, ...) SOC_PERF_PRINT_LOG(Fatal, fmt, ##__VA_ARGS__)
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_COMMON_INCLUDE_SOCPERF_LOG_H
+22
View File
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "socperf_log.h"
namespace OHOS {
namespace SOCPERF {
bool SocPerfLog::isDebugLogEnabled_ = HiLogIsLoggable(LOG_TAG_DOMAIN_ID_SOC_PERF, LOG_TAG_SOC_PERF, LOG_DEBUG);
} // namespace SOCPERF
} // namespace OHOS
@@ -0,0 +1,45 @@
# Copyright (c) 2022-2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
import("../../../soc_perf.gni")
config("socperf_client_public_config") {
include_dirs = [
"include",
"${socperf_common}/include",
]
}
ohos_shared_library("socperf_client") {
sources = [
"${socperf_common}/src/socperf_log.cpp",
"src/socperf_client.cpp",
"src/socperf_proxy.cpp",
]
public_configs = [ ":socperf_client_public_config" ]
external_deps = [
"c_utils:utils",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_single",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
innerapi_tags = [ "platformsdk" ]
version_script = "libsocperf_client.versionscript"
part_name = "soc_perf"
subsystem_name = "resourceschedule"
}
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_I_SOCPERF_SERVICE_H
#define SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_I_SOCPERF_SERVICE_H
#include <string>
#include "iremote_broker.h"
#include "iremote_stub.h"
#include "iremote_proxy.h"
#include "iremote_object.h"
#include "system_ability.h"
#include "system_ability_definition.h"
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "socperf_action_type.h"
namespace OHOS {
namespace SOCPERF {
class ISocPerfService : public IRemoteBroker {
public:
/**
* @brief Sending a performance request.
*
* @param cmdId scene id defined in config file.
* @param msg Additional string info, which is used for other extensions.
*/
virtual void PerfRequest(int32_t cmdId, const std::string& msg) = 0;
/**
* @brief Sending a performance request.
*
* @param cmdId Scene id defined in config file.
* @param onOffTag Indicates the start of end of a long-term frequency increase event.
* @param msg Additional string info, which is used for other extensions.
*/
virtual void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) = 0;
/**
* @brief Sending a power limit boost request.
*
* @param onOffTag Indicates the start of end of a power limit boost event.
* @param msg Additional string info, which is used for other extensions.
*/
virtual void PowerLimitBoost(bool onOffTag, const std::string& msg) = 0;
/**
* @brief Sending a thermal limit boost request.
*
* @param onOffTag Indicates the start of end of a thermal limit boost event.
* @param msg Additional string info, which is used for other extensions.
*/
virtual void ThermalLimitBoost(bool onOffTag, const std::string& msg) = 0;
/**
* @brief Sending a limit request.
*
* @param clientId Used to indentify the caller of frequency limiting, such as
* the thermal module or power consumption module.
* @param configs Indicates the specific value to be limited.
* @param msg Additional string info, which is used for other extensions.
*/
virtual void LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg) = 0;
public:
enum {
TRANS_IPC_ID_PERF_REQUEST = 0x0001,
TRANS_IPC_ID_PERF_REQUEST_EX = 0x0002,
TRANS_IPC_ID_POWER_LIMIT_BOOST_FREQ = 0x0005,
TRANS_IPC_ID_THERMAL_LIMIT_BOOST_FREQ = 0x0008,
TRANS_IPC_ID_LIMIT_REQUEST = 0x0009,
};
public:
DECLARE_INTERFACE_DESCRIPTOR(u"Resourceschedule.ISocPerfService");
};
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_I_SOCPERF_SERVICE_H
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_ACTION_TYPE_H
#define SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_ACTION_TYPE_H
#include <stdint.h>
namespace OHOS {
namespace SOCPERF {
enum ActionType : uint32_t {
ACTION_TYPE_PERF,
ACTION_TYPE_POWER,
ACTION_TYPE_THERMAL,
ACTION_TYPE_MAX
};
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_ACTION_TYPE_H
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_CLIENT_H
#define SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_CLIENT_H
#include <cstdint> // for int32_t
#include <iosfwd> // for string
#include <vector> // for vector
#include "i_socperf_service.h" // for ISocPerfService
namespace OHOS {
namespace SOCPERF {
class SocPerfClient {
public:
/**
* @brief Get the Instance object
*
* @return SocPerfClient&
*/
static SocPerfClient& GetInstance();
/**
* @brief Sending a performance request.
*
* @param cmdId Scene id defined in config file.
* @param msg Additional string info, which is used for other extensions.
*/
void PerfRequest(int32_t cmdId, const std::string& msg);
/**
* @brief Sending a performance request.
*
* @param cmdId Scene id defined in config file.
* @param onOffTag Indicates the start of end of a long-term frequency increase event.
* @param msg Additional string info, which is used for other extensions.
*/
void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg);
/**
* @brief Sending a power limit boost request.
*
* @param onOffTag Indicates the start of end of a power limit boost event.
* @param msg Additional string info, which is used for other extensions.
*/
void PowerLimitBoost(bool onOffTag, const std::string& msg);
/**
* @brief Sending a thermal limit boost request.
*
* @param onOffTag Indicates the start of end of a thermal limit boost event.
* @param msg Additional string info, which is used for other extensions.
*/
void ThermalLimitBoost(bool onOffTag, const std::string& msg);
/**
* @brief Sending a limit request.
*
* @param clientId Used to indentify the caller of frequency limiting, such as
* the thermal module or power consumption module.
* @param configs Indicates the specific value to be limited.
* @param msg Additional string info, which is used for other extensions.
*/
void LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg);
/**
* @brief Reset SocperfClient
*
*/
void ResetClient();
private:
SocPerfClient() {}
~SocPerfClient() {}
private:
bool CheckClientValid();
std::string AddPidAndTidInfo(const std::string& msg);
private:
class SocPerfDeathRecipient : public IRemoteObject::DeathRecipient {
public:
explicit SocPerfDeathRecipient(SocPerfClient &socPerfClient);
~SocPerfDeathRecipient();
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
private:
SocPerfClient &socPerfClient_;
};
private:
std::mutex mutex_;
sptr<ISocPerfService> client;
sptr<SocPerfDeathRecipient> recipient_;
};
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_CLIENT_H
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_PROXY_H
#define SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_PROXY_H
#include "i_socperf_service.h"
namespace OHOS {
namespace SOCPERF {
class SocPerfProxy : public IRemoteProxy<ISocPerfService> {
public:
/**
* @brief Sending a performance request.
*
* @param cmdId Scene id defined in config file.
* @param msg Additional string info, which is used for other extensions.
*/
void PerfRequest(int32_t cmdId, const std::string& msg) override;
/**
* @brief Sending a performance request.
*
* @param cmdId Scene id defined in config file.
* @param onOffTag Indicates the start of end of a long-term frequency increase event.
* @param msg Additional string info, which is used for other extensions.
*/
void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) override;
/**
* @brief Sending a power limit boost request.
*
* @param onOffTag Indicates the start of end of a power limit boost event.
* @param msg Additional string info, which is used for other extensions.
*/
void PowerLimitBoost(bool onOffTag, const std::string& msg) override;
/**
* @brief Sending a thermal limit boost request.
*
* @param onOffTag Indicates the start of end of a thermal limit boost event.
* @param msg Additional string info, which is used for other extensions.
*/
void ThermalLimitBoost(bool onOffTag, const std::string& msg) override;
/**
* @brief Sending a limit request.
*
* @param clientId Used to indentify the caller of frequency limiting, such as
* the thermal module or power consumption module.
* @param configs Indicates the specific value to be limited.
* @param msg Additional string info, which is used for other extensions.
*/
void LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg) override;
public:
/**
* @brief Construct a new SocPerfProxy object.
*
* @param impl RemoteObject.
*/
explicit SocPerfProxy(const sptr<IRemoteObject> &impl)
: IRemoteProxy<ISocPerfService>(impl) {}
/**
* @brief Destroy the SocPerfProxy object.
*
*/
virtual ~SocPerfProxy() {}
private:
static inline BrokerDelegator<SocPerfProxy> delegator_;
};
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_PROXY_H
@@ -0,0 +1,27 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
1.0 {
global:
*ISocPerfService*;
*SocPerfClient*GetInstance*;
*SocPerfClient*PerfRequest*;
*SocPerfClient*PerfRequestEx*;
*SocPerfClient*PowerLimitBoost*;
*SocPerfClient*ThermalLimitBoost*;
*SocPerfClient*LimitRequest*;
*SocPerfClient*ResetClient*;
*SocPerfProxy*;
local:
*;
};
@@ -0,0 +1,141 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "socperf_client.h"
#include <string> // for basic_string, to_string
#include <unistd.h> // for getpid, gettid
#include "socperf_log.h"
namespace OHOS {
namespace SOCPERF {
SocPerfClient& SocPerfClient::GetInstance()
{
static SocPerfClient instance;
return instance;
}
bool SocPerfClient::CheckClientValid()
{
std::lock_guard<std::mutex> lock(mutex_);
if (client) {
return true;
}
sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (!samgr) {
SOC_PERF_LOGE("Failed to get SystemAbilityManager.");
return false;
}
sptr<IRemoteObject> object = samgr->CheckSystemAbility(SOC_PERF_SERVICE_SA_ID);
if (!object) {
SOC_PERF_LOGE("Failed to get SystemAbility[1906].");
return false;
}
client = iface_cast<ISocPerfService>(object);
if (!client || !client->AsObject()) {
SOC_PERF_LOGE("Failed to get SocPerfClient.");
return false;
}
recipient_ = new (std::nothrow) SocPerfDeathRecipient(*this);
if (!recipient_) {
return false;
}
client->AsObject()->AddDeathRecipient(recipient_);
return true;
}
void SocPerfClient::ResetClient()
{
std::lock_guard<std::mutex> lock(mutex_);
if (client && client->AsObject()) {
client->AsObject()->RemoveDeathRecipient(recipient_);
}
client = nullptr;
}
SocPerfClient::SocPerfDeathRecipient::SocPerfDeathRecipient(SocPerfClient &socPerfClient)
: socPerfClient_(socPerfClient) {}
SocPerfClient::SocPerfDeathRecipient::~SocPerfDeathRecipient() {}
void SocPerfClient::SocPerfDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
{
socPerfClient_.ResetClient();
}
std::string SocPerfClient::AddPidAndTidInfo(const std::string& msg)
{
std::string str;
int32_t pid = getpid();
int32_t tid = gettid();
str.append("pid=").append(std::to_string(pid)).append("|");
str.append("tid=").append(std::to_string(tid));
if (msg.size() > 0) {
str.append("|").append(msg);
}
return str;
}
void SocPerfClient::PerfRequest(int32_t cmdId, const std::string& msg)
{
if (!CheckClientValid()) {
return;
}
std::string newMsg = AddPidAndTidInfo(msg);
client->PerfRequest(cmdId, newMsg);
}
void SocPerfClient::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg)
{
if (!CheckClientValid()) {
return;
}
std::string newMsg = AddPidAndTidInfo(msg);
client->PerfRequestEx(cmdId, onOffTag, newMsg);
}
void SocPerfClient::PowerLimitBoost(bool onOffTag, const std::string& msg)
{
if (!CheckClientValid()) {
return;
}
std::string newMsg = AddPidAndTidInfo(msg);
client->PowerLimitBoost(onOffTag, newMsg);
}
void SocPerfClient::ThermalLimitBoost(bool onOffTag, const std::string& msg)
{
if (!CheckClientValid()) {
return;
}
std::string newMsg = AddPidAndTidInfo(msg);
client->ThermalLimitBoost(onOffTag, newMsg);
}
void SocPerfClient::LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg)
{
if (!CheckClientValid()) {
return;
}
std::string newMsg = AddPidAndTidInfo(msg);
client->LimitRequest(clientId, tags, configs, newMsg);
}
} // namespace SOCPERF
} // namespace OHOS
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "socperf_proxy.h"
namespace OHOS {
namespace SOCPERF {
void SocPerfProxy::PerfRequest(int32_t cmdId, const std::string& msg)
{
MessageParcel data;
MessageParcel reply;
MessageOption option = { MessageOption::TF_ASYNC };
if (!data.WriteInterfaceToken(GetDescriptor())) {
return;
}
data.WriteInt32(cmdId);
data.WriteString(msg);
Remote()->SendRequest(TRANS_IPC_ID_PERF_REQUEST, data, reply, option);
}
void SocPerfProxy::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg)
{
MessageParcel data;
MessageParcel reply;
MessageOption option = { MessageOption::TF_ASYNC };
if (!data.WriteInterfaceToken(GetDescriptor())) {
return;
}
data.WriteInt32(cmdId);
data.WriteBool(onOffTag);
data.WriteString(msg);
Remote()->SendRequest(TRANS_IPC_ID_PERF_REQUEST_EX, data, reply, option);
}
void SocPerfProxy::PowerLimitBoost(bool onOffTag, const std::string& msg)
{
MessageParcel data;
MessageParcel reply;
MessageOption option = { MessageOption::TF_ASYNC };
if (!data.WriteInterfaceToken(GetDescriptor())) {
return;
}
data.WriteBool(onOffTag);
data.WriteString(msg);
Remote()->SendRequest(TRANS_IPC_ID_POWER_LIMIT_BOOST_FREQ, data, reply, option);
}
void SocPerfProxy::ThermalLimitBoost(bool onOffTag, const std::string& msg)
{
MessageParcel data;
MessageParcel reply;
MessageOption option = { MessageOption::TF_ASYNC };
if (!data.WriteInterfaceToken(GetDescriptor())) {
return;
}
data.WriteBool(onOffTag);
data.WriteString(msg);
Remote()->SendRequest(TRANS_IPC_ID_THERMAL_LIMIT_BOOST_FREQ, data, reply, option);
}
void SocPerfProxy::LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg)
{
MessageParcel data;
MessageParcel reply;
MessageOption option = { MessageOption::TF_ASYNC };
if (!data.WriteInterfaceToken(GetDescriptor())) {
return;
}
data.WriteInt32(clientId);
data.WriteInt32Vector(tags);
data.WriteInt64Vector(configs);
data.WriteString(msg);
Remote()->SendRequest(TRANS_IPC_ID_LIMIT_REQUEST, data, reply, option);
}
} // namespace SOCPERF
} // namespace OHOS
+36
View File
@@ -0,0 +1,36 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
ohos_prebuilt_etc("socperf_resource_config") {
source = "socperf_resource_config.xml"
install_enable = true
module_install_dir = "etc/soc_perf"
part_name = "soc_perf"
subsystem_name = "resourceschedule"
}
ohos_prebuilt_etc("socperf_boost_config") {
source = "socperf_boost_config.xml"
install_enable = true
module_install_dir = "etc/soc_perf"
part_name = "soc_perf"
subsystem_name = "resourceschedule"
}
group("socperf_config") {
deps = [
":socperf_boost_config",
":socperf_resource_config",
]
}
+17
View File
@@ -0,0 +1,17 @@
<?xml version='1.0' encoding="utf-8"?>
<!--
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<Configs>
</Configs>
+17
View File
@@ -0,0 +1,17 @@
<?xml version='1.0' encoding="utf-8"?>
<!--
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<Configs>
</Configs>
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<info>
<process>resource_schedule_service</process>
<systemability>
<name>1906</name>
<libpath>libsocperf_server.z.so</libpath>
<run-on-create>true</run-on-create>
<distributed>false</distributed>
<dump-level>1</dump-level>
</systemability>
</info>
+19
View File
@@ -0,0 +1,19 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos/sa_profile/sa_profile.gni")
ohos_sa_profile("socperf_sa_profile") {
sources = [ "1906.xml" ]
part_name = "soc_perf"
}
+91
View File
@@ -0,0 +1,91 @@
# Copyright (c) 2022-2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
import("../soc_perf.gni")
config("socperf_server_config") {
include_dirs = [
"core/include",
"server/include",
"${socperf_common}/include",
"${socperf_interfaces}/inner_api/socperf_client/include",
]
}
ohos_shared_library("socperf_server") {
configs = [ ":socperf_server_config" ]
sources = [
"${socperf_common}/src/socperf_log.cpp",
"core/src/socperf.cpp",
"core/src/socperf_handler.cpp",
"server/src/socperf_server.cpp",
"server/src/socperf_stub.cpp",
]
deps = [ "//third_party/libxml2:xml2" ]
external_deps = [
"c_utils:utils",
"eventhandler:libeventhandler",
"hitrace_native:hitrace_meter",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_single",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
defines = []
if (customization_config_policy_enable) {
external_deps += [ "config_policy:configpolicy_util" ]
defines += [ "CUSTOMIZATION_CONFIG_POLICY_ENABLE" ]
}
shlib_type = "sa"
part_name = "soc_perf"
subsystem_name = "resourceschedule"
}
ohos_static_library("socperf_server_static") {
configs = [ ":socperf_server_config" ]
sources = [
"${socperf_common}/src/socperf_log.cpp",
"core/src/socperf.cpp",
"core/src/socperf_handler.cpp",
"server/src/socperf_server.cpp",
"server/src/socperf_stub.cpp",
]
deps = [ "//third_party/libxml2:xml2" ]
external_deps = [
"c_utils:utils",
"eventhandler:libeventhandler",
"hitrace_native:hitrace_meter",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_single",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
defines = []
if (customization_config_policy_enable) {
external_deps += [ "config_policy:configpolicy_util" ]
defines += [ "CUSTOMIZATION_CONFIG_POLICY_ENABLE" ]
}
part_name = "soc_perf"
subsystem_name = "resourceschedule"
}
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_H
#define SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_H
#include <string>
#include <vector>
#include <unordered_map>
#include <unistd.h>
#include "libxml/parser.h"
#include "libxml/tree.h"
#include "socperf_common.h"
#include "socperf_handler.h"
namespace OHOS {
namespace SOCPERF {
class SocPerf {
public:
bool Init();
void PerfRequest(int32_t cmdId, const std::string& msg);
void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg);
void PowerLimitBoost(bool onOffTag, const std::string& msg);
void ThermalLimitBoost(bool onOffTag, const std::string& msg);
void LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg);
public:
SocPerf();
~SocPerf();
private:
std::unordered_map<int32_t, std::shared_ptr<Actions>> perfActionsInfo;
std::vector<std::shared_ptr<SocPerfHandler>> handlers;
bool handlerSwitch[MAX_HANDLER_THREADS] = { false };
bool enabled = false;
std::unordered_map<int32_t, std::shared_ptr<ResNode>> resNodeInfo;
std::unordered_map<int32_t, std::shared_ptr<GovResNode>> govResNodeInfo;
std::unordered_map<std::string, int32_t> resStrToIdInfo;
std::vector<std::unordered_map<int32_t, int32_t>> limitRequest;
private:
std::mutex mutex_;
std::string GetRealConfigPath(const std::string configFile);
std::shared_ptr<SocPerfHandler> GetHandlerByResId(int32_t resId);
bool LoadConfigXmlFile(std::string configFile);
bool CreateHandlers();
void InitHandlerThreads();
bool LoadResource(xmlNode* rootNode, std::string configFile);
bool LoadGovResource(xmlNode* rootNode, std::string configFile);
bool LoadCmd(xmlNode* rootNode, std::string configFile);
bool CheckResourceTag(char* id, char* name, char* pair, char* mode, std::string configFile);
bool CheckResourceTag(char* def, char* path, std::string configFile);
bool LoadResourceAvailable(std::shared_ptr<ResNode> resNode, char* node);
bool CheckPairResIdValid();
bool CheckResDefValid();
bool CheckGovResourceTag(char* id, char* name, std::string configFile);
bool LoadGovResourceAvailable(std::shared_ptr<GovResNode> govResNode, char* level, char* node);
bool CheckGovResDefValid();
bool CheckCmdTag(char* id, char* name, std::string configFile);
bool CheckActionResIdAndValueValid(std::string configFile);
void DoFreqActions(std::shared_ptr<Actions> actions, int32_t onOff, int32_t actionType);
void PrintCachedInfo();
void SendLimitRequestEvent(int32_t clientId, int32_t resId, int64_t resValue);
void SendLimitRequestEventOff(std::shared_ptr<SocPerfHandler> handler,
int32_t clientId, int32_t resId, int32_t eventId);
void SendLimitRequestEventOn(std::shared_ptr<SocPerfHandler> handler,
int32_t clientId, int32_t resId, int64_t resValue, int32_t eventId);
};
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_H
+367
View File
@@ -0,0 +1,367 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_COMMON_H
#define SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_COMMON_H
#include <climits>
#include <list>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include "socperf_log.h"
#include "socperf_action_type.h"
namespace OHOS {
namespace SOCPERF {
enum EventType {
EVENT_INVALID = -1,
EVENT_OFF,
EVENT_ON
};
const std::string SOCPERF_RESOURCE_CONFIG_XML = "etc/soc_perf/socperf_resource_config.xml";
const std::string SOCPERF_BOOST_CONFIG_XML = "etc/soc_perf/socperf_boost_config.xml";
const int64_t MAX_INT_VALUE = 0x7FFFFFFFFFFFFFFF;
const int64_t MIN_INT_VALUE = 0x8000000000000000;
const int32_t INVALID_VALUE = INT_MIN;
const int32_t RESET_VALUE = -1;
/*
* Divide all resource id into five sections, resource of each section is processed in an individual handler thread.
* handlerId = resourceId / RES_ID_NUMS_PER_TYPE - 1
* Resource section: [1000, 1999] [2000, 2999] [3000, 3999] [4000, 4999] [5000, 5999]
* Handler Thread: handlers[0] handlers[1] handlers[2] handlers[3] handlers[4]
*/
const int32_t MAX_HANDLER_THREADS = 5;
const int32_t MIN_RESOURCE_ID = 1000;
const int32_t MAX_RESOURCE_ID = 5999;
const int32_t RES_ID_ADDITION = 10000;
const int32_t RES_ID_AND_VALUE_PAIR = 2;
const int32_t RES_ID_NUMS_PER_TYPE = 1000;
class ResNode {
public:
int32_t id;
std::string name;
int64_t def;
std::string path;
int32_t mode;
int32_t pair;
std::unordered_set<int64_t> available;
public:
ResNode(int32_t resId, std::string resName, int32_t resMode, int32_t resPair)
{
id = resId;
name = resName;
mode = resMode;
pair = resPair;
def = INVALID_VALUE;
}
~ResNode() {}
void PrintString()
{
SOC_PERF_LOGD("resNode-> id: [%{public}d], name: [%{public}s]", id, name.c_str());
SOC_PERF_LOGD(" path: [%{public}s]", path.c_str());
SOC_PERF_LOGD(" def: [%{public}lld], mode: [%{public}d], pair: [%{public}d]",
(long long)def, mode, pair);
std::string str;
str.append("available(").append(std::to_string((int32_t)available.size())).append("): ");
str.append("[");
for (auto validValue : available) {
str.append(std::to_string(validValue)).append(",");
}
if (!available.empty()) {
str.pop_back();
}
str.append("]");
SOC_PERF_LOGD(" %{public}s", str.c_str());
}
};
class GovResNode {
public:
int32_t id;
std::string name;
int64_t def;
std::vector<std::string> paths;
std::unordered_set<int64_t> available;
std::unordered_map<int64_t, std::vector<std::string>> levelToStr;
public:
GovResNode(int32_t govResId, std::string govResName)
{
id = govResId;
name = govResName;
def = INVALID_VALUE;
}
~GovResNode() {}
void PrintString()
{
SOC_PERF_LOGD("govResNode-> id: [%{public}d], name: [%{public}s]", id, name.c_str());
SOC_PERF_LOGD(" def: [%{public}lld]", (long long)def);
for (auto path : paths) {
SOC_PERF_LOGD(" path: [%{public}s]", path.c_str());
}
std::string str;
str.append("available(").append(std::to_string((int32_t)available.size())).append("): ");
str.append("[");
for (auto validValue : available) {
str.append(std::to_string(validValue)).append(",");
}
if (!available.empty()) {
str.pop_back();
}
str.append("]");
SOC_PERF_LOGD(" %{public}s", str.c_str());
for (auto iter = levelToStr.begin(); iter != levelToStr.end(); ++iter) {
std::string str2;
int64_t level = iter->first;
std::vector<std::string> result = iter->second;
for (int32_t i = 0; i < (int32_t)result.size(); i++) {
str2.append(result[i]).append(",");
}
if (!result.empty()) {
str2.pop_back();
}
SOC_PERF_LOGD(" %{public}lld: [%{public}s]", (long long)level, str2.c_str());
}
}
};
class Action {
public:
int32_t duration;
std::vector<int64_t> variable;
public:
Action() {}
~Action() {}
};
class Actions {
public:
int32_t id;
std::string name;
std::list<std::shared_ptr<Action>> actionList;
public:
Actions(int32_t cmdId, std::string cmdName)
{
id = cmdId;
name = cmdName;
}
~Actions() {}
void PrintString()
{
SOC_PERF_LOGD("Actions-> id: [%{public}d], name: [%{public}s]", id, name.c_str());
for (auto iter = actionList.begin(); iter != actionList.end(); iter++) {
std::shared_ptr<Action> action = *iter;
std::string str;
str.append("variable(").append(std::to_string((int32_t)action->variable.size())).append("): [");
for (int32_t i = 0; i < (int32_t)action->variable.size(); i++) {
str.append(std::to_string(action->variable[i])).append(",");
}
if (!action->variable.empty()) {
str.pop_back();
}
str.append("]");
SOC_PERF_LOGD(" duration: [%{public}d], %{public}s", action->duration, str.c_str());
}
}
};
class ResAction {
public:
int64_t value;
int32_t duration;
int32_t type;
int32_t onOff;
public:
ResAction(int64_t resActionValue, int32_t resActionDuration, int32_t resActionType, int32_t resActionOnOff)
{
value = resActionValue;
duration = resActionDuration;
type = resActionType;
onOff = resActionOnOff;
}
~ResAction() {}
bool TotalSame(std::shared_ptr<ResAction> resAction)
{
if (value == resAction->value
&& duration == resAction->duration
&& type == resAction->type
&& onOff == resAction->onOff) {
return true;
}
return false;
}
bool PartSame(std::shared_ptr<ResAction> resAction)
{
if (value == resAction->value
&& duration == resAction->duration
&& type == resAction->type) {
return true;
}
return false;
}
};
class ResActionItem {
public:
ResActionItem(int32_t id)
{
resId = id;
}
~ResActionItem() = default;
int32_t resId;
std::shared_ptr<ResAction> resAction = nullptr;
std::shared_ptr<ResActionItem> next = nullptr;
};
class ResStatus {
public:
std::vector<std::list<std::shared_ptr<ResAction>>> resActionList;
std::vector<int64_t> candidates;
int64_t candidate;
int64_t current;
public:
explicit ResStatus(int64_t val)
{
resActionList = std::vector<std::list<std::shared_ptr<ResAction>>>(ACTION_TYPE_MAX);
candidates = std::vector<int64_t>(ACTION_TYPE_MAX);
candidates[ACTION_TYPE_PERF] = INVALID_VALUE;
candidates[ACTION_TYPE_POWER] = INVALID_VALUE;
candidates[ACTION_TYPE_THERMAL] = INVALID_VALUE;
candidate = val;
current = val;
}
~ResStatus() {}
std::string ToString()
{
std::string str;
str.append("perf:[");
for (auto iter = resActionList[ACTION_TYPE_PERF].begin();
iter != resActionList[ACTION_TYPE_PERF].end(); ++iter) {
str.append(std::to_string((*iter)->value)).append(",");
}
if (!resActionList[ACTION_TYPE_PERF].empty()) {
str.pop_back();
}
str.append("]power:[");
for (auto iter = resActionList[ACTION_TYPE_POWER].begin();
iter != resActionList[ACTION_TYPE_POWER].end(); ++iter) {
str.append(std::to_string((*iter)->value)).append(",");
}
if (!resActionList[ACTION_TYPE_POWER].empty()) {
str.pop_back();
}
str.append("]thermal:[");
for (auto iter = resActionList[ACTION_TYPE_THERMAL].begin();
iter != resActionList[ACTION_TYPE_THERMAL].end(); ++iter) {
str.append(std::to_string((*iter)->value)).append(",");
}
if (!resActionList[ACTION_TYPE_THERMAL].empty()) {
str.pop_back();
}
str.append("]candidates[");
for (auto iter = candidates.begin(); iter != candidates.end(); ++iter) {
str.append(std::to_string(*iter)).append(",");
}
str.pop_back();
str.append("]candidate[").append(std::to_string(candidate));
str.append("]current[").append(std::to_string(current)).append("]");
return str;
}
};
static inline int64_t Max(int64_t num1, int64_t num2)
{
if (num1 >= num2) {
return num1;
}
return num2;
}
static inline int64_t Max(int64_t num1, int64_t num2, int64_t num3)
{
return Max(Max(num1, num2), num3);
}
static inline int64_t Min(int64_t num1, int64_t num2)
{
if (num1 <= num2) {
return num1;
}
return num2;
}
static inline int64_t Min(int64_t num1, int64_t num2, int64_t num3)
{
return Min(Min(num1, num2), num3);
}
static inline bool IsNumber(std::string str)
{
for (int32_t i = 0; i < (int32_t)str.size(); i++) {
if (i == 0 && str.at(i) == '-') {
continue;
}
if (str.at(i) < '0' || str.at(i) > '9') {
return false;
}
}
return true;
}
static inline bool IsValidResId(int32_t id)
{
if (id < MIN_RESOURCE_ID || id > MAX_RESOURCE_ID) {
return false;
}
return true;
}
static inline std::vector<std::string> Split(std::string str, std::string pattern)
{
int32_t position;
std::vector<std::string> result;
str += pattern;
int32_t length = (int32_t)str.size();
for (int32_t i = 0; i < length; i++) {
position = (int32_t)str.find(pattern, i);
if (position < length) {
std::string tmp = str.substr(i, position - i);
result.push_back(tmp);
i = position + (int32_t)pattern.size() - 1;
}
}
return result;
}
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_SERVICES_CORE_INCLUDE_COMMON_H
+79
View File
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_HANDLER_H
#define SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_HANDLER_H
#include <memory> // for shared_ptr
#include <string> // for string
#include <unordered_map> // for unordered_map
#include <stdint.h> // for uint32_t
#include "event_handler.h" // for EventHandler
#include "event_runner.h"
#include "inner_event.h" // for InnerEvent, InnerEvent::Pointer
namespace OHOS { namespace SOCPERF { class GovResNode; } }
namespace OHOS { namespace SOCPERF { class ResAction; } }
namespace OHOS { namespace SOCPERF { class ResNode; } }
namespace OHOS { namespace SOCPERF { class ResStatus; } }
namespace OHOS {
namespace SOCPERF {
enum SocPerfInnerEvent : uint32_t {
INNER_EVENT_ID_INIT_RES_NODE_INFO = 0,
INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO,
INNER_EVENT_ID_DO_FREQ_ACTION,
INNER_EVENT_ID_DO_FREQ_ACTION_PACK,
INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED,
INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ,
INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ,
INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL,
};
class SocPerfHandler : public AppExecFwk::EventHandler {
public:
explicit SocPerfHandler(const std::shared_ptr<AppExecFwk::EventRunner>& runner);
~SocPerfHandler() override;
void ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event) override;
private:
std::unordered_map<int32_t, std::shared_ptr<ResNode>> resNodeInfo;
std::unordered_map<int32_t, std::shared_ptr<GovResNode>> govResNodeInfo;
std::unordered_map<int32_t, std::shared_ptr<ResStatus>> resStatusInfo;
std::unordered_map<std::string, int32_t> fdInfo;
bool powerLimitBoost = false;
bool thermalLimitBoost = false;
private:
void HandleDoFreqActionLevel(int32_t resId, std::shared_ptr<ResAction> resAction);
bool GetResValueByLevel(int32_t resId, int32_t level, int64_t& resValue);
void UpdateResActionList(int32_t resId, std::shared_ptr<ResAction> resAction, bool delayed);
void UpdateCandidatesValue(int32_t resId, int32_t type);
void ArbitrateCandidate(int32_t resId);
void ArbitratePairRes(int32_t resId);
void UpdatePairResValue(int32_t minResId, int64_t minResValue, int32_t maxResId, int64_t maxResValue);
void UpdateCurrentValue(int32_t resId, int64_t value);
void WriteNode(std::string path, std::string value);
bool ExistNoCandidate(
int32_t resId, std::shared_ptr<ResStatus> resStatus, int64_t perf, int64_t power, int64_t thermal);
bool IsGovResId(int32_t resId);
bool IsResId(int32_t resId);
bool IsValidResId(int32_t resId);
int32_t GetFdForFilePath(std::string filePath);
};
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_HANDLER_H
+752
View File
@@ -0,0 +1,752 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "socperf.h"
#ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
#include "config_policy_utils.h"
#endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
#include "hitrace_meter.h"
namespace OHOS {
namespace SOCPERF {
SocPerf::SocPerf()
{
}
SocPerf::~SocPerf()
{
}
bool SocPerf::Init()
{
#ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
if (!LoadConfigXmlFile(SOCPERF_RESOURCE_CONFIG_XML)) {
SOC_PERF_LOGE("Failed to load %{public}s", SOCPERF_RESOURCE_CONFIG_XML.c_str());
return false;
}
if (!LoadConfigXmlFile(SOCPERF_BOOST_CONFIG_XML)) {
SOC_PERF_LOGE("Failed to load %{public}s", SOCPERF_BOOST_CONFIG_XML.c_str());
return false;
}
#endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
PrintCachedInfo();
if (!CreateHandlers()) {
SOC_PERF_LOGE("Failed to create handler threads");
return false;
}
InitHandlerThreads();
resNodeInfo.clear();
govResNodeInfo.clear();
resStrToIdInfo.clear();
limitRequest = std::vector<std::unordered_map<int32_t, int32_t>>(ACTION_TYPE_MAX);
enabled = true;
SOC_PERF_LOGD("SocPerf Init SUCCESS!");
return true;
}
void SocPerf::PerfRequest(int32_t cmdId, const std::string& msg)
{
if (!enabled) {
SOC_PERF_LOGE("SocPerf disabled!");
return;
}
if (perfActionsInfo.find(cmdId) == perfActionsInfo.end()) {
SOC_PERF_LOGE("Invalid PerfRequest cmdId[%{public}d]", cmdId);
return;
}
SOC_PERF_LOGD("cmdId[%{public}d]msg[%{public}s]", cmdId, msg.c_str());
std::string trace_str(__func__);
trace_str.append(",cmdId[").append(std::to_string(cmdId)).append("]");
trace_str.append(",msg[").append(msg).append("]");
StartTrace(HITRACE_TAG_OHOS, trace_str, -1);
DoFreqActions(perfActionsInfo[cmdId], EVENT_INVALID, ACTION_TYPE_PERF);
FinishTrace(HITRACE_TAG_OHOS);
}
void SocPerf::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg)
{
if (!enabled) {
SOC_PERF_LOGE("SocPerf disabled!");
return;
}
if (perfActionsInfo.find(cmdId) == perfActionsInfo.end()) {
SOC_PERF_LOGE("Invalid PerfRequestEx cmdId[%{public}d]", cmdId);
return;
}
SOC_PERF_LOGD("cmdId[%{public}d]onOffTag[%{public}d]msg[%{public}s]",
cmdId, onOffTag, msg.c_str());
std::string trace_str(__func__);
trace_str.append(",cmdId[").append(std::to_string(cmdId)).append("]");
trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]");
trace_str.append(",msg[").append(msg).append("]");
StartTrace(HITRACE_TAG_OHOS, trace_str, -1);
DoFreqActions(perfActionsInfo[cmdId], onOffTag ? EVENT_ON : EVENT_OFF, ACTION_TYPE_PERF);
FinishTrace(HITRACE_TAG_OHOS);
}
void SocPerf::PowerLimitBoost(bool onOffTag, const std::string& msg)
{
if (!enabled) {
SOC_PERF_LOGE("SocPerf disabled!");
return;
}
SOC_PERF_LOGD("onOffTag[%{public}d]msg[%{public}s]", onOffTag, msg.c_str());
std::string trace_str(__func__);
trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]");
trace_str.append(",msg[").append(msg).append("]");
StartTrace(HITRACE_TAG_OHOS, trace_str, -1);
for (auto handler : handlers) {
if (handler) {
auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ, onOffTag ? 1 : 0);
handler->SendEvent(event);
}
}
FinishTrace(HITRACE_TAG_OHOS);
}
void SocPerf::ThermalLimitBoost(bool onOffTag, const std::string& msg)
{
if (!enabled) {
SOC_PERF_LOGE("SocPerf disabled!");
return;
}
SOC_PERF_LOGD("onOffTag[%{public}d]msg[%{public}s]", onOffTag, msg.c_str());
std::string trace_str(__func__);
trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]");
trace_str.append(",msg[").append(msg).append("]");
StartTrace(HITRACE_TAG_OHOS, trace_str, -1);
for (auto handler : handlers) {
if (handler) {
auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ, onOffTag ? 1 : 0);
handler->SendEvent(event);
}
}
FinishTrace(HITRACE_TAG_OHOS);
}
void SocPerf::SendLimitRequestEventOff(std::shared_ptr<SocPerfHandler> handler,
int32_t clientId, int32_t resId, int32_t eventId)
{
auto iter = limitRequest[clientId].find(resId);
if (iter != limitRequest[clientId].end()
&& limitRequest[clientId][resId] != INVALID_VALUE) {
auto resAction = std::make_shared<ResAction>(
limitRequest[clientId][resId], 0, clientId, EVENT_OFF);
auto event = AppExecFwk::InnerEvent::Get(eventId, resAction, resId);
handler->SendEvent(event);
limitRequest[clientId].erase(iter);
}
}
void SocPerf::SendLimitRequestEventOn(std::shared_ptr<SocPerfHandler> handler,
int32_t clientId, int32_t resId, int64_t resValue, int32_t eventId)
{
if (resValue != INVALID_VALUE && resValue != RESET_VALUE) {
auto resAction = std::make_shared<ResAction>(resValue, 0, clientId, EVENT_ON);
auto event = AppExecFwk::InnerEvent::Get(eventId, resAction, resId);
handler->SendEvent(event);
limitRequest[clientId].insert(std::pair<int32_t, int32_t>(resId, resValue));
}
}
void SocPerf::SendLimitRequestEvent(int32_t clientId, int32_t resId, int64_t resValue)
{
int32_t eventId, realResId, levelResId;
if (resId > RES_ID_ADDITION) {
realResId = resId - RES_ID_ADDITION;
levelResId = resId;
eventId = INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL;
} else {
realResId = resId;
levelResId = resId + RES_ID_ADDITION;
eventId = INNER_EVENT_ID_DO_FREQ_ACTION;
}
auto handler = GetHandlerByResId(realResId);
if (!handler) {
return;
}
std::lock_guard<std::mutex> lock(mutex_);
SendLimitRequestEventOff(handler, clientId, realResId, INNER_EVENT_ID_DO_FREQ_ACTION);
SendLimitRequestEventOff(handler, clientId, levelResId, INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL);
SendLimitRequestEventOn(handler, clientId, resId, resValue, eventId);
}
void SocPerf::LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg)
{
if (!enabled) {
SOC_PERF_LOGE("SocPerf disabled!");
return;
}
if (tags.size() != configs.size()) {
SOC_PERF_LOGE("tags'size and configs' size must be the same!");
return;
}
if (clientId <= (int32_t)ACTION_TYPE_PERF || clientId >= (int32_t)ACTION_TYPE_MAX) {
SOC_PERF_LOGE("clientId must be between ACTION_TYPE_PERF and ACTION_TYPE_MAX!");
return;
}
for (int32_t i = 0; i < (int32_t)tags.size(); i++) {
SOC_PERF_LOGD("clientId[%{public}d],tags[%{public}d],configs[%{public}lld],msg[%{public}s]",
clientId, tags[i], (long long)configs[i], msg.c_str());
SendLimitRequestEvent(clientId, tags[i], configs[i]);
}
}
void SocPerf::DoFreqActions(std::shared_ptr<Actions> actions, int32_t onOff, int32_t actionType)
{
std::shared_ptr<ResActionItem> header[MAX_HANDLER_THREADS] = { nullptr };
std::shared_ptr<ResActionItem> curItem[MAX_HANDLER_THREADS] = { nullptr };
for (auto iter = actions->actionList.begin(); iter != actions->actionList.end(); iter++) {
std::shared_ptr<Action> action = *iter;
for (int32_t i = 0; i < (int32_t)action->variable.size() - 1; i += RES_ID_AND_VALUE_PAIR) {
if (!IsValidResId(action->variable[i])) {
continue;
}
auto resActionItem = std::make_shared<ResActionItem>(action->variable[i]);
resActionItem->resAction =
std::make_shared<ResAction>(action->variable[i + 1], action->duration, actionType, onOff);
int32_t id = action->variable[i] / RES_ID_NUMS_PER_TYPE - 1;
if (curItem[id]) {
curItem[id]->next = resActionItem;
} else {
header[id] = resActionItem;
}
curItem[id] = resActionItem;
}
}
for (int32_t i = 0; i < MAX_HANDLER_THREADS; ++i) {
if (!handlers[i] || !header[i]) {
continue;
}
auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_DO_FREQ_ACTION_PACK, header[i]);
handlers[i]->SendEvent(event);
}
}
#ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
std::string SocPerf::GetRealConfigPath(const std::string configFile)
{
char buf[PATH_MAX + 1];
char* configFilePath = GetOneCfgFile(configFile.c_str(), buf, PATH_MAX + 1);
char tmpPath[PATH_MAX + 1] = {0};
if (!configFilePath || strlen(configFilePath) == 0 || strlen(configFilePath) > PATH_MAX ||
!realpath(configFilePath, tmpPath)) {
SOC_PERF_LOGE("load %{public}s file fail", configFile.c_str());
return "";
}
return std::string(tmpPath);
}
#endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
std::shared_ptr<SocPerfHandler> SocPerf::GetHandlerByResId(int32_t resId)
{
if (!IsValidResId(resId)) {
return nullptr;
}
return handlers[resId / RES_ID_NUMS_PER_TYPE - 1];
}
#ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
bool SocPerf::LoadConfigXmlFile(std::string configFile)
{
std::string realConfigFile = GetRealConfigPath(configFile);
if (realConfigFile.size() <= 0) {
return false;
}
xmlKeepBlanksDefault(0);
xmlDoc* file = xmlReadFile(realConfigFile.c_str(), nullptr, XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
if (!file) {
SOC_PERF_LOGE("Failed to open xml file");
return false;
}
xmlNode* rootNode = xmlDocGetRootElement(file);
if (!rootNode) {
SOC_PERF_LOGE("Failed to get xml file's RootNode");
xmlFreeDoc(file);
return false;
}
if (!xmlStrcmp(rootNode->name, reinterpret_cast<const xmlChar*>("Configs"))) {
if (realConfigFile.find(SOCPERF_RESOURCE_CONFIG_XML) != std::string::npos) {
xmlNode* child = rootNode->children;
for (; child; child = child->next) {
if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("Resource"))) {
if (!LoadResource(child, realConfigFile)) {
xmlFreeDoc(file);
return false;
}
} else if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("GovResource"))) {
if (!LoadGovResource(child, realConfigFile)) {
xmlFreeDoc(file);
return false;
}
}
}
} else {
if (!LoadCmd(rootNode, realConfigFile)) {
xmlFreeDoc(file);
return false;
}
}
} else {
SOC_PERF_LOGE("Wrong format for xml file");
xmlFreeDoc(file);
return false;
}
xmlFreeDoc(file);
SOC_PERF_LOGD("Success to Load %{public}s", configFile.c_str());
return true;
}
#endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
bool SocPerf::CreateHandlers()
{
handlers = std::vector<std::shared_ptr<SocPerfHandler>>(MAX_HANDLER_THREADS);
std::string threadName = "socperf#";
for (int32_t i = 0; i < (int32_t)handlers.size(); i++) {
if (!handlerSwitch[i]) {
handlers[i] = nullptr;
continue;
}
auto runner = AppExecFwk::EventRunner::Create(threadName + std::to_string(i));
if (!runner) {
SOC_PERF_LOGE("Failed to Create EventRunner");
return false;
}
handlers[i] = std::make_shared<SocPerfHandler>(runner);
}
SOC_PERF_LOGD("Success to Create All Handler threads");
return true;
}
void SocPerf::InitHandlerThreads()
{
for (auto iter = resNodeInfo.begin(); iter != resNodeInfo.end(); ++iter) {
std::shared_ptr<ResNode> resNode = iter->second;
auto handler = GetHandlerByResId(resNode->id);
if (!handler) {
continue;
}
auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_INIT_RES_NODE_INFO, resNode);
handler->SendEvent(event);
}
for (auto iter = govResNodeInfo.begin(); iter != govResNodeInfo.end(); ++iter) {
std::shared_ptr<GovResNode> govResNode = iter->second;
auto handler = GetHandlerByResId(govResNode->id);
if (!handler) {
continue;
}
auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO, govResNode);
handler->SendEvent(event);
}
}
bool SocPerf::LoadResource(xmlNode* child, std::string configFile)
{
xmlNode* grandson = child->children;
for (; grandson; grandson = grandson->next) {
if (!xmlStrcmp(grandson->name, reinterpret_cast<const xmlChar*>("res"))) {
char* id = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("id")));
char* name = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("name")));
char* pair = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("pair")));
char* mode = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("mode")));
if (!CheckResourceTag(id, name, pair, mode, configFile)) {
xmlFree(id);
xmlFree(name);
xmlFree(pair);
xmlFree(mode);
return false;
}
xmlNode* greatGrandson = grandson->children;
std::shared_ptr<ResNode> resNode = std::make_shared<ResNode>(
atoi(id), name, mode ? atoi(mode) : 0, pair ? atoi(pair) : INVALID_VALUE);
xmlFree(id);
xmlFree(name);
xmlFree(pair);
xmlFree(mode);
char *def = nullptr;
char *path = nullptr;
char *node = nullptr;
for (; greatGrandson; greatGrandson = greatGrandson->next) {
if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("default"))) {
xmlFree(def);
def = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
} else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("path"))) {
xmlFree(path);
path = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
} else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("node"))) {
xmlFree(node);
node = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
}
}
if (!CheckResourceTag(def, path, configFile)) {
xmlFree(def);
xmlFree(path);
xmlFree(node);
return false;
}
resNode->def = atoll(def);
resNode->path = path;
xmlFree(def);
xmlFree(path);
if (node && !LoadResourceAvailable(resNode, node)) {
SOC_PERF_LOGE("Invalid resource node for %{public}s", configFile.c_str());
xmlFree(node);
return false;
}
xmlFree(node);
resStrToIdInfo.insert(std::pair<std::string, int32_t>(resNode->name, resNode->id));
resNodeInfo.insert(std::pair<int32_t, std::shared_ptr<ResNode>>(resNode->id, resNode));
handlerSwitch[resNode->id / RES_ID_NUMS_PER_TYPE - 1] = true;
}
}
if (!CheckPairResIdValid() || !CheckResDefValid()) {
return false;
}
return true;
}
bool SocPerf::LoadGovResource(xmlNode* child, std::string configFile)
{
xmlNode* grandson = child->children;
for (; grandson; grandson = grandson->next) {
if (xmlStrcmp(grandson->name, reinterpret_cast<const xmlChar*>("res"))) {
continue;
}
char* id = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("id")));
char* name = reinterpret_cast<char*>(xmlGetProp(grandson, reinterpret_cast<const xmlChar*>("name")));
if (!CheckGovResourceTag(id, name, configFile)) {
xmlFree(id);
xmlFree(name);
return false;
}
xmlNode* greatGrandson = grandson->children;
std::shared_ptr<GovResNode> govResNode = std::make_shared<GovResNode>(atoi(id), name);
xmlFree(id);
xmlFree(name);
handlerSwitch[govResNode->id / RES_ID_NUMS_PER_TYPE - 1] = true;
for (; greatGrandson; greatGrandson = greatGrandson->next) {
if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("default"))) {
char* def = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
if (!def || !IsNumber(def)) {
SOC_PERF_LOGE("Invalid governor resource default for %{public}s", configFile.c_str());
xmlFree(def);
return false;
}
govResNode->def = atoll(def);
xmlFree(def);
} else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("path"))) {
char* path = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
if (!path) {
SOC_PERF_LOGE("Invalid governor resource path for %{public}s", configFile.c_str());
return false;
}
govResNode->paths.push_back(path);
xmlFree(path);
} else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("node"))) {
char* level = reinterpret_cast<char*>(
xmlGetProp(greatGrandson, reinterpret_cast<const xmlChar*>("level")));
char* node = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
if (!level || !IsNumber(level) || !node
|| !LoadGovResourceAvailable(govResNode, level, node)) {
SOC_PERF_LOGE("Invalid governor resource node for %{public}s", configFile.c_str());
xmlFree(level);
xmlFree(node);
return false;
}
xmlFree(level);
xmlFree(node);
}
}
resStrToIdInfo.insert(std::pair<std::string, int32_t>(govResNode->name, govResNode->id));
govResNodeInfo.insert(std::pair<int32_t, std::shared_ptr<GovResNode>>(govResNode->id, govResNode));
}
if (!CheckGovResDefValid()) {
return false;
}
return true;
}
bool SocPerf::LoadCmd(xmlNode* rootNode, std::string configFile)
{
xmlNode* child = rootNode->children;
for (; child; child = child->next) { // Iterate all cmdID
if (xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("cmd"))) {
continue;
}
char* id = reinterpret_cast<char*>(xmlGetProp(child, reinterpret_cast<const xmlChar*>("id")));
char* name = reinterpret_cast<char*>(xmlGetProp(child, reinterpret_cast<const xmlChar*>("name")));
if (!CheckCmdTag(id, name, configFile)) {
xmlFree(id);
xmlFree(name);
return false;
}
xmlNode* grandson = child->children;
std::shared_ptr<Actions> actions = std::make_shared<Actions>(atoi(id), name);
xmlFree(id);
xmlFree(name);
for (; grandson; grandson = grandson->next) { // Iterate all Action
std::shared_ptr<Action> action = std::make_shared<Action>();
xmlNode* greatGrandson = grandson->children;
for (; greatGrandson; greatGrandson = greatGrandson->next) { // Iterate duration and all res
if (!xmlStrcmp(greatGrandson->name, reinterpret_cast<const xmlChar*>("duration"))) {
char* duration = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
if (!duration || !IsNumber(duration)) {
SOC_PERF_LOGE("Invalid cmd duration for %{public}s", configFile.c_str());
xmlFree(duration);
return false;
}
action->duration = atoi(duration);
xmlFree(duration);
} else {
char* resStr = reinterpret_cast<char*>(const_cast<xmlChar*>(greatGrandson->name));
char* resValue = reinterpret_cast<char*>(xmlNodeGetContent(greatGrandson));
if (!resStr || resStrToIdInfo.find(resStr) == resStrToIdInfo.end()
|| !resValue || !IsNumber(resValue)) {
SOC_PERF_LOGE("Invalid cmd resource(%{public}s) for %{public}s", resStr, configFile.c_str());
xmlFree(resValue);
return false;
}
action->variable.push_back(resStrToIdInfo[resStr]);
action->variable.push_back(atoll(resValue));
xmlFree(resValue);
}
}
actions->actionList.push_back(action);
}
if (configFile.find(SOCPERF_BOOST_CONFIG_XML) != std::string::npos) {
perfActionsInfo.insert(std::pair<int32_t, std::shared_ptr<Actions>>(actions->id, actions));
}
}
if (!CheckActionResIdAndValueValid(configFile)) {
return false;
}
return true;
}
bool SocPerf::CheckResourceTag(char* id, char* name, char* pair, char* mode, std::string configFile)
{
if (!id || !IsNumber(id) || !IsValidResId(atoi(id))) {
SOC_PERF_LOGE("Invalid resource id for %{public}s", configFile.c_str());
return false;
}
if (!name) {
SOC_PERF_LOGE("Invalid resource name for %{public}s", configFile.c_str());
return false;
}
if (pair && (!IsNumber(pair) || !IsValidResId(atoi(pair)))) {
SOC_PERF_LOGE("Invalid resource pair for %{public}s", configFile.c_str());
return false;
}
if (mode && !IsNumber(mode)) {
SOC_PERF_LOGE("Invalid resource mode for %{public}s", configFile.c_str());
return false;
}
return true;
}
bool SocPerf::CheckResourceTag(char* def, char* path, std::string configFile)
{
if (!def || !IsNumber(def)) {
SOC_PERF_LOGE("Invalid resource default for %{public}s", configFile.c_str());
return false;
}
if (!path) {
SOC_PERF_LOGE("Invalid resource path for %{public}s", configFile.c_str());
return false;
}
return true;
}
bool SocPerf::LoadResourceAvailable(std::shared_ptr<ResNode> resNode, char* node)
{
std::string nodeStr = node;
std::vector<std::string> result = Split(nodeStr, " ");
for (auto str : result) {
if (IsNumber(str)) {
resNode->available.insert(stoll(str));
} else {
return false;
}
}
return true;
}
bool SocPerf::CheckPairResIdValid()
{
for (auto iter = resNodeInfo.begin(); iter != resNodeInfo.end(); ++iter) {
int32_t resId = iter->first;
std::shared_ptr<ResNode> resNode = iter->second;
int32_t pairResId = resNode->pair;
if (pairResId != INVALID_VALUE && resNodeInfo.find(pairResId) == resNodeInfo.end()) {
SOC_PERF_LOGE("resId[%{public}d]'s pairResId[%{public}d] is not valid", resId, pairResId);
return false;
}
}
return true;
}
bool SocPerf::CheckResDefValid()
{
for (auto iter = resNodeInfo.begin(); iter != resNodeInfo.end(); ++iter) {
int32_t resId = iter->first;
std::shared_ptr<ResNode> resNode = iter->second;
int64_t def = resNode->def;
if (!resNode->available.empty() && resNode->available.find(def) == resNode->available.end()) {
SOC_PERF_LOGE("resId[%{public}d]'s def[%{public}lld] is not valid", resId, (long long)def);
return false;
}
}
return true;
}
bool SocPerf::CheckGovResourceTag(char* id, char* name, std::string configFile)
{
if (!id || !IsNumber(id) || !IsValidResId(atoi(id))) {
SOC_PERF_LOGE("Invalid governor resource id for %{public}s", configFile.c_str());
return false;
}
if (!name) {
SOC_PERF_LOGE("Invalid governor resource name for %{public}s", configFile.c_str());
return false;
}
return true;
}
bool SocPerf::LoadGovResourceAvailable(std::shared_ptr<GovResNode> govResNode, char* level, char* node)
{
govResNode->available.insert(atoll(level));
std::string nodeStr = node;
std::vector<std::string> result = Split(nodeStr, "|");
if (result.size() != govResNode->paths.size()) {
SOC_PERF_LOGE("Invalid governor resource node matches paths");
return false;
}
govResNode->levelToStr.insert(std::pair<int32_t, std::vector<std::string>>(atoll(level), result));
return true;
}
bool SocPerf::CheckGovResDefValid()
{
for (auto iter = govResNodeInfo.begin(); iter != govResNodeInfo.end(); ++iter) {
int32_t govResId = iter->first;
std::shared_ptr<GovResNode> govResNode = iter->second;
int32_t def = govResNode->def;
if (govResNode->available.find(def) == govResNode->available.end()) {
SOC_PERF_LOGE("govResId[%{public}d]'s def[%{public}d] is not valid", govResId, def);
return false;
}
}
return true;
}
bool SocPerf::CheckCmdTag(char* id, char* name, std::string configFile)
{
if (!id || !IsNumber(id)) {
SOC_PERF_LOGE("Invalid cmd id for %{public}s", configFile.c_str());
return false;
}
if (!name) {
SOC_PERF_LOGE("Invalid cmd name for %{public}s", configFile.c_str());
return false;
}
return true;
}
bool SocPerf::CheckActionResIdAndValueValid(std::string configFile)
{
std::unordered_map<int32_t, std::shared_ptr<Actions>> actionsInfo;
if (configFile.find(SOCPERF_BOOST_CONFIG_XML) != std::string::npos) {
actionsInfo = perfActionsInfo;
}
for (auto actionsIter = actionsInfo.begin(); actionsIter != actionsInfo.end(); ++actionsIter) {
int32_t actionId = actionsIter->first;
std::shared_ptr<Actions> actions = actionsIter->second;
for (auto actionIter = actions->actionList.begin(); actionIter != actions->actionList.end(); ++actionIter) {
std::shared_ptr<Action> action = *actionIter;
for (int32_t i = 0; i < (int32_t)action->variable.size() - 1; i += RES_ID_AND_VALUE_PAIR) {
int32_t resId = action->variable[i];
int64_t resValue = action->variable[i + 1];
if (resNodeInfo.find(resId) != resNodeInfo.end()) {
if (!resNodeInfo[resId]->available.empty()
&& resNodeInfo[resId]->available.find(resValue) == resNodeInfo[resId]->available.end()) {
SOC_PERF_LOGE("action[%{public}d]'s resValue[%{public}lld] is not valid",
actionId, (long long)resValue);
return false;
}
} else if (govResNodeInfo.find(resId) != govResNodeInfo.end()) {
if (govResNodeInfo[resId]->available.find(resValue) == govResNodeInfo[resId]->available.end()) {
SOC_PERF_LOGE("action[%{public}d]'s resValue[%{public}lld] is not valid",
actionId, (long long)resValue);
return false;
}
} else {
SOC_PERF_LOGE("action[%{public}d]'s resId[%{public}d] is not valid", actionId, resId);
return false;
}
}
}
}
return true;
}
void SocPerf::PrintCachedInfo()
{
SOC_PERF_LOGD("------------------------------------");
SOC_PERF_LOGD("resNodeInfo(%{public}d)", (int32_t)resNodeInfo.size());
for (auto iter = resNodeInfo.begin(); iter != resNodeInfo.end(); ++iter) {
std::shared_ptr<ResNode> resNode = iter->second;
resNode->PrintString();
}
SOC_PERF_LOGD("------------------------------------");
SOC_PERF_LOGD("govResNodeInfo(%{public}d)", (int32_t)govResNodeInfo.size());
for (auto iter = govResNodeInfo.begin(); iter != govResNodeInfo.end(); ++iter) {
std::shared_ptr<GovResNode> govResNode = iter->second;
govResNode->PrintString();
}
SOC_PERF_LOGD("------------------------------------");
SOC_PERF_LOGD("perfActionsInfo(%{public}d)", (int32_t)perfActionsInfo.size());
for (auto iter = perfActionsInfo.begin(); iter != perfActionsInfo.end(); ++iter) {
std::shared_ptr<Actions> actions = iter->second;
actions->PrintString();
}
SOC_PERF_LOGD("------------------------------------");
}
} // namespace SOCPERF
} // namespace OHOS
+431
View File
@@ -0,0 +1,431 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "socperf_handler.h"
#include <cstdio> // for FILE
#include <cstdint> // for int32_t
#include <climits> // for PATH_MAX
#include <list> // for list, __list_iterator, operator!=
#include <new> // for operator delete, operator new
#include <cstdlib> // for realpath
#include <set> // for set
#include <string> // for basic_string, to_string
#include <unordered_map> // for unordered_map, operator==, operator!=
#include <utility> // for pair
#include <vector> // for vector
#include <unistd.h> // for open, write
#include <fcntl.h> // for O_RDWR, O_CLOEXEC
#include "socperf_common.h" // for ResStatus, ResAction, ResNode, INVALID_V...
namespace OHOS {
namespace SOCPERF {
SocPerfHandler::SocPerfHandler(
const std::shared_ptr<AppExecFwk::EventRunner>& runner) : AppExecFwk::EventHandler(runner)
{
}
SocPerfHandler::~SocPerfHandler()
{
}
void SocPerfHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
{
if (event == nullptr) {
return;
}
switch (event->GetInnerEventId()) {
case INNER_EVENT_ID_INIT_RES_NODE_INFO: {
auto resNode = event->GetSharedObject<ResNode>();
if (resNode != nullptr) {
resNodeInfo.insert(std::pair<int32_t, std::shared_ptr<ResNode>>(resNode->id, resNode));
WriteNode(resNode->path, std::to_string(resNode->def));
auto resStatus = std::make_shared<ResStatus>(resNode->def);
resStatusInfo.insert(std::pair<int32_t, std::shared_ptr<ResStatus>>(resNode->id, resStatus));
}
break;
}
case INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO: {
auto govResNode = event->GetSharedObject<GovResNode>();
if (govResNode != nullptr) {
govResNodeInfo.insert(std::pair<int32_t, std::shared_ptr<GovResNode>>(govResNode->id, govResNode));
for (int32_t i = 0; i < (int32_t)govResNode->paths.size(); i++) {
WriteNode(govResNode->paths[i], govResNode->levelToStr[govResNode->def][i]);
}
auto resStatus = std::make_shared<ResStatus>(govResNode->def);
resStatusInfo.insert(std::pair<int32_t, std::shared_ptr<ResStatus>>(govResNode->id, resStatus));
}
break;
}
case INNER_EVENT_ID_DO_FREQ_ACTION: {
int32_t resId = event->GetParam();
if (!IsValidResId(resId)) {
return;
}
std::shared_ptr<ResAction> resAction = event->GetSharedObject<ResAction>();
if (resAction != nullptr) {
UpdateResActionList(resId, resAction, false);
}
break;
}
case INNER_EVENT_ID_DO_FREQ_ACTION_PACK: {
std::shared_ptr<ResActionItem> head = event->GetSharedObject<ResActionItem>();
while (head) {
if (IsValidResId(head->resId)) {
UpdateResActionList(head->resId, head->resAction, false);
}
auto temp = head->next;
head->next = nullptr;
head = temp;
}
break;
}
case INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED: {
int32_t resId = event->GetParam();
if (!IsValidResId(resId)) {
return;
}
std::shared_ptr<ResAction> resAction = event->GetSharedObject<ResAction>();
if (resAction != nullptr) {
UpdateResActionList(resId, resAction, true);
}
break;
}
case INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ: {
powerLimitBoost = event->GetParam() == 1;
for (auto iter = resStatusInfo.begin(); iter != resStatusInfo.end(); ++iter) {
ArbitrateCandidate(iter->first);
}
break;
}
case INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ: {
thermalLimitBoost = event->GetParam() == 1;
for (auto iter = resStatusInfo.begin(); iter != resStatusInfo.end(); ++iter) {
ArbitrateCandidate(iter->first);
}
break;
}
case INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL: {
HandleDoFreqActionLevel(event->GetParam(), event->GetSharedObject<ResAction>());
break;
}
default: {
break;
}
}
}
void SocPerfHandler::HandleDoFreqActionLevel(int32_t resId, std::shared_ptr<ResAction> resAction)
{
int32_t realResId = resId - RES_ID_ADDITION;
if (!IsValidResId(realResId) || !resAction) {
return;
}
int32_t level = (int32_t)resAction->value;
if (!GetResValueByLevel(realResId, level, resAction->value)) {
return;
}
UpdateResActionList(realResId, resAction, false);
}
bool SocPerfHandler::GetResValueByLevel(int32_t resId, int32_t level, int64_t& resValue)
{
if (resNodeInfo.find(resId) == resNodeInfo.end()
|| resNodeInfo[resId]->available.empty()) {
SOC_PERF_LOGE("resId[%{public}d] is not valid.", resId);
return false;
}
if (level < 0) {
return false;
}
std::set<int64_t> available;
for (auto a : resNodeInfo[resId]->available) {
available.insert(a);
}
int32_t len = (int32_t)available.size();
auto iter = available.begin();
if (level < len) {
std::advance(iter, len - 1 - level);
}
resValue = *iter;
return true;
}
void SocPerfHandler::UpdateResActionList(int32_t resId, std::shared_ptr<ResAction> resAction, bool delayed)
{
std::shared_ptr<ResStatus> resStatus = resStatusInfo[resId];
int32_t type = resAction->type;
if (delayed) {
for (auto iter = resStatus->resActionList[type].begin();
iter != resStatus->resActionList[type].end(); ++iter) {
if (resAction == *iter) {
resStatus->resActionList[type].erase(iter);
UpdateCandidatesValue(resId, type);
break;
}
}
} else {
switch (resAction->onOff) {
case EVENT_INVALID: {
resStatus->resActionList[type].push_back(resAction);
UpdateCandidatesValue(resId, type);
auto event = AppExecFwk::InnerEvent::Get(
INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED, resAction, resId);
this->SendEvent(event, resAction->duration);
break;
}
case EVENT_ON: {
if (resAction->duration == 0) {
for (auto iter = resStatus->resActionList[type].begin();
iter != resStatus->resActionList[type].end(); ++iter) {
if (resAction->TotalSame(*iter)) {
resStatus->resActionList[type].erase(iter);
break;
}
}
resStatus->resActionList[type].push_back(resAction);
UpdateCandidatesValue(resId, type);
} else {
resStatus->resActionList[type].push_back(resAction);
UpdateCandidatesValue(resId, type);
auto event = AppExecFwk::InnerEvent::Get(
INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED, resAction, resId);
this->SendEvent(event, resAction->duration);
}
break;
}
case EVENT_OFF: {
for (auto iter = resStatus->resActionList[type].begin();
iter != resStatus->resActionList[type].end(); ++iter) {
if (resAction->PartSame(*iter) && (*iter)->onOff == EVENT_ON) {
resStatus->resActionList[type].erase(iter);
UpdateCandidatesValue(resId, type);
break;
}
}
break;
}
default: {
break;
}
}
}
}
void SocPerfHandler::UpdateCandidatesValue(int32_t resId, int32_t type)
{
std::shared_ptr<ResStatus> resStatus = resStatusInfo[resId];
int64_t prev = resStatus->candidates[type];
if (resStatus->resActionList[type].empty()) {
resStatus->candidates[type] = INVALID_VALUE;
} else {
if (type == ACTION_TYPE_PERF) {
int64_t res = MIN_INT_VALUE;
for (auto iter = resStatus->resActionList[type].begin();
iter != resStatus->resActionList[type].end(); ++iter) {
res = Max(res, (*iter)->value);
}
resStatus->candidates[type] = res;
} else {
int64_t res = MAX_INT_VALUE;
for (auto iter = resStatus->resActionList[type].begin();
iter != resStatus->resActionList[type].end(); ++iter) {
res = Min(res, (*iter)->value);
}
resStatus->candidates[type] = res;
}
}
if (resStatus->candidates[type] != prev) {
ArbitrateCandidate(resId);
}
}
void SocPerfHandler::ArbitrateCandidate(int32_t resId)
{
std::shared_ptr<ResStatus> resStatus = resStatusInfo[resId];
int64_t candidatePerf = resStatus->candidates[ACTION_TYPE_PERF];
int64_t candidatePower = resStatus->candidates[ACTION_TYPE_POWER];
int64_t candidateThermal = resStatus->candidates[ACTION_TYPE_THERMAL];
if (ExistNoCandidate(resId, resStatus, candidatePerf, candidatePower, candidateThermal)) {
return;
}
if (!powerLimitBoost && !thermalLimitBoost) {
if (candidatePerf != INVALID_VALUE) {
resStatus->candidate = Max(candidatePerf, candidatePower, candidateThermal);
} else {
resStatus->candidate =
(candidatePower == INVALID_VALUE) ? candidateThermal :
((candidateThermal == INVALID_VALUE) ? candidatePower : Min(candidatePower, candidateThermal));
}
} else if (!powerLimitBoost && thermalLimitBoost) {
resStatus->candidate =
(candidateThermal != INVALID_VALUE) ? candidateThermal : Max(candidatePerf, candidatePower);
} else if (powerLimitBoost && !thermalLimitBoost) {
resStatus->candidate =
(candidatePower != INVALID_VALUE) ? candidatePower : Max(candidatePerf, candidateThermal);
} else {
if (candidatePower == INVALID_VALUE && candidateThermal == INVALID_VALUE) {
resStatus->candidate = candidatePerf;
} else {
resStatus->candidate =
(candidatePower == INVALID_VALUE) ? candidateThermal :
((candidateThermal == INVALID_VALUE) ? candidatePower : Min(candidatePower, candidateThermal));
}
}
ArbitratePairRes(resId);
}
void SocPerfHandler::ArbitratePairRes(int32_t resId)
{
if (IsGovResId(resId)) {
UpdateCurrentValue(resId, resStatusInfo[resId]->candidate);
return;
}
int32_t pairResId = resNodeInfo[resId]->pair;
if (pairResId == INVALID_VALUE) {
UpdateCurrentValue(resId, resStatusInfo[resId]->candidate);
return;
}
if (resNodeInfo[resId]->mode == 1) {
if (resStatusInfo[resId]->candidate < resStatusInfo[pairResId]->candidate) {
if (powerLimitBoost || thermalLimitBoost) {
UpdatePairResValue(pairResId,
resStatusInfo[resId]->candidate, resId, resStatusInfo[resId]->candidate);
} else {
UpdatePairResValue(pairResId,
resStatusInfo[pairResId]->candidate, resId, resStatusInfo[pairResId]->candidate);
}
} else {
UpdatePairResValue(pairResId,
resStatusInfo[pairResId]->candidate, resId, resStatusInfo[resId]->candidate);
}
} else {
if (resStatusInfo[resId]->candidate > resStatusInfo[pairResId]->candidate) {
if (powerLimitBoost || thermalLimitBoost) {
UpdatePairResValue(resId,
resStatusInfo[pairResId]->candidate, pairResId, resStatusInfo[pairResId]->candidate);
} else {
UpdatePairResValue(resId,
resStatusInfo[resId]->candidate, pairResId, resStatusInfo[resId]->candidate);
}
} else {
UpdatePairResValue(resId,
resStatusInfo[resId]->candidate, pairResId, resStatusInfo[pairResId]->candidate);
}
}
}
void SocPerfHandler::UpdatePairResValue(int32_t minResId, int64_t minResValue, int32_t maxResId, int64_t maxResValue)
{
WriteNode(resNodeInfo[minResId]->path, std::to_string(resNodeInfo[minResId]->def));
WriteNode(resNodeInfo[maxResId]->path, std::to_string(resNodeInfo[maxResId]->def));
UpdateCurrentValue(minResId, minResValue);
UpdateCurrentValue(maxResId, maxResValue);
}
void SocPerfHandler::UpdateCurrentValue(int32_t resId, int64_t currValue)
{
resStatusInfo[resId]->current = currValue;
if (IsGovResId(resId)) {
if (govResNodeInfo[resId]->levelToStr.find(currValue) != govResNodeInfo[resId]->levelToStr.end()) {
std::vector<std::string> targetStrs = govResNodeInfo[resId]->levelToStr[resStatusInfo[resId]->current];
for (int32_t i = 0; i < (int32_t)govResNodeInfo[resId]->paths.size(); i++) {
WriteNode(govResNodeInfo[resId]->paths[i], targetStrs[i]);
}
}
} else if (IsResId(resId)) {
WriteNode(resNodeInfo[resId]->path, std::to_string(resStatusInfo[resId]->current));
}
}
void SocPerfHandler::WriteNode(std::string filePath, std::string value)
{
int32_t fd = GetFdForFilePath(filePath);
if (fd < 0) {
return;
}
write(fd, value.c_str(), value.size());
}
int32_t SocPerfHandler::GetFdForFilePath(std::string filePath)
{
if (fdInfo.find(filePath) != fdInfo.end()) {
return fdInfo[filePath];
}
char path[PATH_MAX + 1] = {0};
if (filePath.size() == 0 || filePath.size() > PATH_MAX || !realpath(filePath.c_str(), path)) {
return -1;
}
int32_t fd = open(path, O_RDWR | O_CLOEXEC);
if (fd < 0) {
return fd;
}
fdInfo.insert(std::pair<std::string, int32_t>(filePath, fd));
return fdInfo[filePath];
}
bool SocPerfHandler::ExistNoCandidate(
int32_t resId, std::shared_ptr<ResStatus> resStatus, int64_t perf, int64_t power, int64_t thermal)
{
if (perf == INVALID_VALUE && power == INVALID_VALUE && thermal == INVALID_VALUE) {
if (IsGovResId(resId)) {
resStatus->candidate = govResNodeInfo[resId]->def;
} else if (IsResId(resId)) {
resStatus->candidate = resNodeInfo[resId]->def;
}
ArbitratePairRes(resId);
return true;
}
return false;
}
bool SocPerfHandler::IsGovResId(int32_t resId)
{
if (resNodeInfo.find(resId) == resNodeInfo.end()
&& govResNodeInfo.find(resId) != govResNodeInfo.end()) {
return true;
}
return false;
}
bool SocPerfHandler::IsResId(int32_t resId)
{
if (govResNodeInfo.find(resId) == govResNodeInfo.end()
&& resNodeInfo.find(resId) != resNodeInfo.end()) {
return true;
}
return false;
}
bool SocPerfHandler::IsValidResId(int32_t resId)
{
if (resNodeInfo.find(resId) == resNodeInfo.end()
&& govResNodeInfo.find(resId) == govResNodeInfo.end()) {
return false;
}
if (resStatusInfo.find(resId) == resStatusInfo.end()) {
return false;
}
return true;
}
} // namespace SOCPERF
} // namespace OHOS
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_SERVER_H
#define SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_SERVER_H
#include <file_ex.h>
#include <string_ex.h>
#include "i_socperf_service.h"
#include "singleton.h"
#include "socperf_stub.h"
#include "socperf.h"
namespace OHOS {
namespace SOCPERF {
class SocPerfServer : public SystemAbility, public SocPerfStub,
public std::enable_shared_from_this<SocPerfServer> {
DISALLOW_COPY_AND_MOVE(SocPerfServer);
DECLARE_SYSTEM_ABILITY(SocPerfServer);
DECLARE_DELAYED_SINGLETON(SocPerfServer);
public:
void PerfRequest(int32_t cmdId, const std::string& msg) override;
void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) override;
void PowerLimitBoost(bool onOffTag, const std::string& msg) override;
void ThermalLimitBoost(bool onOffTag, const std::string& msg) override;
void LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg) override;
int32_t Dump(int32_t fd, const std::vector<std::u16string>& args) override;
public:
SocPerfServer(int32_t systemAbilityId, bool runOnCreate);
protected:
void OnStart() override;
void OnStop() override;
private:
SocPerf socPerf;
};
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_SERVER_H
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_STUB_H
#define SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_STUB_H
#include <cstdint> // for int32_t, uint32_t
#include "i_socperf_service.h"
namespace OHOS {
namespace SOCPERF {
class SocPerfStub : public IRemoteStub<ISocPerfService> {
public:
SocPerfStub() = default;
~SocPerfStub() override = default;
DISALLOW_COPY_AND_MOVE(SocPerfStub);
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option) override;
};
} // namespace SOCPERF
} // namespace OHOS
#endif // SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_STUB_H
+93
View File
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "socperf_server.h"
namespace OHOS {
namespace SOCPERF {
const bool REGISTER_RESULT =
SystemAbility::MakeAndRegisterAbility(DelayedSingleton<SocPerfServer>::GetInstance().get());
SocPerfServer::SocPerfServer() : SystemAbility(SOC_PERF_SERVICE_SA_ID, true)
{
}
SocPerfServer::~SocPerfServer()
{
}
void SocPerfServer::OnStart()
{
if (!Publish(DelayedSingleton<SocPerfServer>::GetInstance().get())) {
SOC_PERF_LOGE("Register SystemAbility for SocPerf FAILED.");
return;
}
if (!socPerf.Init()) {
SOC_PERF_LOGE("SocPerf Init FAILED");
return;
}
}
void SocPerfServer::OnStop()
{
}
int32_t SocPerfServer::Dump(int32_t fd, const std::vector<std::u16string>& args)
{
std::vector<std::string> argsInStr;
std::transform(args.begin(), args.end(), std::back_inserter(argsInStr),
[](const std::u16string &arg) {
return Str16ToStr8(arg);
});
std::string result;
result.append("usage: soc_perf service dump [<options>]\n")
.append(" 1. PerfRequest(cmdId, msg)\n")
.append(" 2. PerfRequestEx(cmdId, onOffTag, msg)\n")
.append(" 3. LimitRequest(clientId, tags, configs, msg)\n")
.append(" -h: show the help.\n")
.append(" -a: show all info.\n");
if (!SaveStringToFd(fd, result)) {
SOC_PERF_LOGE("Dump FAILED");
}
return ERR_OK;
}
void SocPerfServer::PerfRequest(int32_t cmdId, const std::string& msg)
{
socPerf.PerfRequest(cmdId, msg);
}
void SocPerfServer::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg)
{
socPerf.PerfRequestEx(cmdId, onOffTag, msg);
}
void SocPerfServer::PowerLimitBoost(bool onOffTag, const std::string& msg)
{
socPerf.PowerLimitBoost(onOffTag, msg);
}
void SocPerfServer::ThermalLimitBoost(bool onOffTag, const std::string& msg)
{
socPerf.ThermalLimitBoost(onOffTag, msg);
}
void SocPerfServer::LimitRequest(int32_t clientId,
const std::vector<int32_t>& tags, const std::vector<int64_t>& configs, const std::string& msg)
{
socPerf.LimitRequest(clientId, tags, configs, msg);
}
} // namespace SOCPERF
} // namespace OHOS
+73
View File
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "socperf_stub.h"
#include <cstdint> // for int32_t
#include <iosfwd> // for string
#include <string> // for basic_string, operator!=, u16string
#include <vector> // for vector
namespace OHOS {
namespace SOCPERF {
int32_t SocPerfStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option)
{
auto remoteDescriptor = data.ReadInterfaceToken();
if (GetDescriptor() != remoteDescriptor) {
return ERR_INVALID_STATE;
}
switch (code) {
case TRANS_IPC_ID_PERF_REQUEST: {
int32_t cmdId = data.ReadInt32();
std::string msg = data.ReadString();
PerfRequest(cmdId, msg);
return 0;
}
case TRANS_IPC_ID_PERF_REQUEST_EX: {
int32_t cmdId = data.ReadInt32();
bool onOffTag = data.ReadBool();
std::string msg = data.ReadString();
PerfRequestEx(cmdId, onOffTag, msg);
return 0;
}
case TRANS_IPC_ID_POWER_LIMIT_BOOST_FREQ: {
bool onOffTag = data.ReadBool();
std::string msg = data.ReadString();
PowerLimitBoost(onOffTag, msg);
return 0;
}
case TRANS_IPC_ID_THERMAL_LIMIT_BOOST_FREQ: {
bool onOffTag = data.ReadBool();
std::string msg = data.ReadString();
ThermalLimitBoost(onOffTag, msg);
return 0;
}
case TRANS_IPC_ID_LIMIT_REQUEST: {
int32_t clientId = data.ReadInt32();
std::vector<int32_t> tags;
data.ReadInt32Vector(&tags);
std::vector<int64_t> configs;
data.ReadInt64Vector(&configs);
std::string msg = data.ReadString();
LimitRequest(clientId, tags, configs, msg);
return 0;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
}
} // namespace SOCPERF
} // namespace OHOS
+31
View File
@@ -0,0 +1,31 @@
# Copyright (C) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
socperf_path =
"//foundation/resourceschedule/resource_schedule_service/soc_perf"
socperf_services = "${socperf_path}/services"
socperf_common = "${socperf_path}/common"
socperf_interfaces = "${socperf_path}/interfaces"
socperf_test = "${socperf_path}/test"
declare_args() {
customization_config_policy_enable = true
if (defined(global_parts_info) &&
!defined(global_parts_info.customization_config_policy)) {
customization_config_policy_enable = false
}
}
+22
View File
@@ -0,0 +1,22 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
group("fuzztest") {
testonly = true
deps = [
"loadconfigxmlfile_fuzzer:fuzztest",
"perfrequest_fuzzer:fuzztest",
"socperf_fuzzer:fuzztest",
]
}
@@ -0,0 +1,60 @@
# Copyright (c) 2022-2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#####################hydra-fuzz###################
import("//build/config/features.gni")
import("//build/test.gni")
import("../../../soc_perf.gni")
module_output_path = "resource_schedule_service/soc_perf"
##############################fuzztest##########################################
config("module_private_config") {
include_dirs = [
"${socperf_common}/include",
"${socperf_interfaces}/inner_api/socperf_client/include",
"${socperf_services}/core/include",
"${socperf_services}/server/include",
]
}
ohos_fuzztest("LoadConfigXmlFileFuzzTest") {
module_out_path = module_output_path
fuzz_config_file = "${socperf_test}/fuzztest/loadconfigxmlfile_fuzzer"
configs = [ ":module_private_config" ]
cflags = [
"-g",
"-O0",
"-Wno-unused-variable",
"-fno-omit-frame-pointer",
]
sources = [ "loadconfigxmlfile_fuzzer.cpp" ]
deps = [ "${socperf_services}:socperf_server_static" ]
external_deps = [
"c_utils:utils",
"hiviewdfx_hilog_native:libhilog",
]
}
###############################################################################
group("fuzztest") {
testonly = true
deps = [
# deps file
":LoadConfigXmlFileFuzzTest",
]
}
###############################################################################
@@ -0,0 +1,28 @@
<?xml version='1.0' encoding="utf-8"?>
<!-- Copyright (c) 2022 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Configs>
<Resource>
<res id="1000" name="lit_cpu_min_freq" pair="1001">
<default>408000</default>
<path>/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq</path>
<node>408000 600000 816000 1104000 1416000 1608000 1800000 1992000</node>
</res>
<res id="1001" name="lit_cpu_max_freq" pair="1000" mode="1">
<default>1992000</default>
<path>/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq</path>
<node>408000 600000 816000 1104000 1416000 1608000 1800000 1992000</node>
</res>
</Resource>
</Configs>
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "loadconfigxmlfile_fuzzer.h"
#define private public
#include "socperf.h"
namespace OHOS {
namespace SOCPERF {
const std::string fuzzedFile = "myFuzzed.xml";
const int32_t FILE_RETURN_SUCCESS = 1;
std::mutex mutexLock;
std::unique_ptr<SocPerf> socPerf = nullptr;
bool DoInit()
{
std::lock_guard<std::mutex> lock(mutexLock);
if (socPerf) {
return true;
}
socPerf = std::make_unique<SocPerf>();
return socPerf != nullptr;
}
void DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
{
if (!DoInit()) {
return;
}
// generate fuzzed xml
FILE *pFile = fopen(fuzzedFile.c_str(), "wb");
if (!pFile) {
return;
}
int32_t retCode = fwrite(reinterpret_cast<const void*>(data), size, 1, pFile); // 1 means count=1
if (retCode < FILE_RETURN_SUCCESS) {
(void)fclose(pFile);
pFile = nullptr;
return;
}
(void)fclose(pFile);
pFile = nullptr;
socPerf->LoadConfigXmlFile(fuzzedFile);
}
} // namespace SOCPERF
} // namespace OHOS
/* Fuzzer entry point */
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
/* Run your code on data */
OHOS::SOCPERF::DoSomethingInterestingWithMyAPI(data, size);
return 0;
}
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TEST_FUZZTEST_LOADCONFIGXMLFILE_FUZZER_H
#define TEST_FUZZTEST_LOADCONFIGXMLFILE_FUZZER_H
#define FUZZ_PROJECT_NAME "loadconfigxmlfile_fuzzer"
#endif
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2022 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
+60
View File
@@ -0,0 +1,60 @@
# Copyright (c) 2022-2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#####################hydra-fuzz###################
import("//build/config/features.gni")
import("//build/test.gni")
import("../../../soc_perf.gni")
##############################fuzztest##########################################
ohos_fuzztest("PerfRequestFuzzTest") {
module_out_path = "soc_perf/socperftest"
fuzz_config_file = "${socperf_test}/fuzztest/perfrequest_fuzzer"
include_dirs = [
"${socperf_common}/include",
"${socperf_interfaces}/inner_api/socperf_client:socperf_client",
"${socperf_services}/core/include",
]
cflags = [
"-g",
"-O0",
"-Wno-unused-variable",
"-fno-omit-frame-pointer",
]
sources = [ "perfrequest_fuzzer.cpp" ]
deps = [ "${socperf_interfaces}/inner_api/socperf_client:socperf_client" ]
external_deps = [
"c_utils:utils",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_single",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
}
###############################################################################
group("fuzztest") {
testonly = true
deps = []
deps += [
# deps file
":PerfRequestFuzzTest",
]
}
###############################################################################
@@ -0,0 +1,14 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FUZZ
@@ -0,0 +1,198 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "perfrequest_fuzzer.h"
#include "socperf_client.h"
#include <securec.h>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#ifndef errno_t
typedef int errno_t;
#endif
#ifndef EOK
#define EOK 0
#endif
namespace OHOS {
namespace SOCPERF {
const uint8_t* g_data = nullptr;
size_t g_size = 0;
size_t g_pos;
/*
* describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
* tips: only support basic type
*/
template<class T>
T GetData()
{
T object {};
size_t objectSize = sizeof(object);
if (g_data == nullptr || objectSize > g_size - g_pos) {
return object;
}
errno_t ret = memcpy_s(&object, objectSize, g_data + g_pos, objectSize);
if (ret != EOK) {
return {};
}
g_pos += objectSize;
return object;
}
/*
* get a string from g_data
*/
std::string GetStringFromData(int strlen)
{
if (strlen <= 0) {
return "";
}
char cstr[strlen];
cstr[strlen - 1] = '\0';
for (int i = 0; i < strlen - 1; i++) {
char tmp = GetData<char>();
if (tmp == '\0') {
tmp = '1';
}
cstr[i] = tmp;
}
std::string str(cstr);
return str;
}
bool PerfRequestFuzzTest(const uint8_t* data, size_t size)
{
if (data == nullptr) {
return false;
}
// initialize
g_data = data;
g_size = size;
g_pos = 0;
// getdata
std::string msg;
int32_t cmdId = GetData<int32_t>();
msg = GetStringFromData(int(size) - sizeof(int32_t));
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(cmdId, msg);
return true;
}
bool PerfRequestExFuzzTest(const uint8_t* data, size_t size)
{
if (data == nullptr) {
return false;
}
// initialize
g_data = data;
g_size = size;
g_pos = 0;
// getdata
std::string msg;
int32_t cmdId = GetData<int32_t>();
bool onOffTag = GetData<bool>();
msg = GetStringFromData(int(size) - sizeof(int32_t) - sizeof(bool));
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(cmdId, onOffTag, msg);
return true;
}
bool PowerLimitBoostFuzzTest(const uint8_t* data, size_t size)
{
if (data == nullptr) {
return false;
}
// initialize
g_data = data;
g_size = size;
g_pos = 0;
// getdata
std::string msg;
bool onOffTag = GetData<bool>();
msg = GetStringFromData(int(size) - sizeof(bool));
OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(onOffTag, msg);
return true;
}
bool ThermalLimitBoostFuzzTest(const uint8_t* data, size_t size)
{
if (data == nullptr) {
return false;
}
// initialize
g_data = data;
g_size = size;
g_pos = 0;
// getdata
std::string msg;
bool onOffTag = GetData<bool>();
msg = GetStringFromData(int(size) - sizeof(bool));
OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(onOffTag, msg);
return true;
}
bool LimitRequestFuzzTest(const uint8_t* data, size_t size)
{
if (data == nullptr) {
return false;
}
// initialize
g_data = data;
g_size = size;
g_pos = 0;
// getdata
std::vector<int32_t> tags;
std::vector<int64_t> configs;
std::string msg;
int32_t tagsNumber = GetData<int32_t>();
int64_t configsNumber = GetData<int64_t>();
int32_t clientId = GetData<int32_t>();
tags.push_back(tagsNumber);
configs.push_back(configsNumber);
msg = GetStringFromData(int(size) - sizeof(int32_t) - sizeof(int32_t) - sizeof(int64_t));
OHOS::SOCPERF::SocPerfClient::GetInstance().LimitRequest(clientId, tags, configs, msg);
return true;
}
} // namespace SOCPERF
} // namespace OHOS
/* Fuzzer entry point */
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
/* Run your code on data */
OHOS::SOCPERF::PerfRequestFuzzTest(data, size);
OHOS::SOCPERF::PerfRequestExFuzzTest(data, size);
OHOS::SOCPERF::PowerLimitBoostFuzzTest(data, size);
OHOS::SOCPERF::ThermalLimitBoostFuzzTest(data, size);
OHOS::SOCPERF::LimitRequestFuzzTest(data, size);
return 0;
}
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PERFREQUEST_FUZZER_H
#define PERFREQUEST_FUZZER_H
#include <cstdint>
#include <unistd.h>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#define FUZZ_PROJECT_NAME "perfrequest_fuzzer"
#endif
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2023 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
+55
View File
@@ -0,0 +1,55 @@
# Copyright (c) 2022-2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#####################hydra-fuzz###################
import("//build/config/features.gni")
import("//build/test.gni")
import("../../../soc_perf.gni")
module_output_path = "resource_schedule_service/soc_perf"
##############################fuzztest##########################################
ohos_fuzztest("SocPerfFuzzTest") {
module_out_path = module_output_path
fuzz_config_file = "${socperf_test}/fuzztest/socperf_fuzzer"
include_dirs = []
cflags = [
"-g",
"-O0",
"-Wno-unused-variable",
"-fno-omit-frame-pointer",
]
sources = [ "socperf_fuzzer.cpp" ]
deps = [ "${socperf_interfaces}/inner_api/socperf_client:socperf_client" ]
external_deps = [
"c_utils:utils",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_single",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
}
###############################################################################
group("fuzztest") {
testonly = true
deps = []
deps += [
# deps file
":SocPerfFuzzTest",
]
}
###############################################################################
+14
View File
@@ -0,0 +1,14 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FUZZ
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2022 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<fuzz_config>
<fuzztest>
<!-- maximum length of a test input -->
<max_len>1000</max_len>
<!-- maximum total time in seconds to run the fuzzer -->
<max_total_time>300</max_total_time>
<!-- memory usage limit in Mb -->
<rss_limit_mb>4096</rss_limit_mb>
</fuzztest>
</fuzz_config>
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "socperf_fuzzer.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
#include "i_socperf_service.h"
#include "socperf_log.h"
namespace OHOS {
namespace SOCPERF {
constexpr int32_t MIN_LEN = 4;
std::mutex mutexLock;
sptr<IRemoteObject> remoteObj = nullptr;
bool DoInit()
{
std::lock_guard<std::mutex> lock(mutexLock);
if (remoteObj) {
return true;
}
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (!samgr) {
return false;
}
remoteObj = samgr->GetSystemAbility(SOC_PERF_SERVICE_SA_ID);
if (!remoteObj) {
return false;
}
return true;
}
int32_t onRemoteRequest(uint32_t code, MessageParcel& data)
{
if (!DoInit()) {
return -1;
}
MessageParcel reply;
MessageOption option;
return remoteObj->SendRequest(code, data, reply, option);
}
bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
{
if (size <= MIN_LEN) {
return false;
}
MessageParcel dataMessageParcel;
if (!dataMessageParcel.WriteInterfaceToken(IRemoteStub<ISocPerfService>::GetDescriptor())) {
return false;
}
uint32_t code = *(reinterpret_cast<const uint32_t*>(data));
size -= sizeof(uint32_t);
dataMessageParcel.WriteBuffer(data + sizeof(uint32_t), size);
dataMessageParcel.RewindRead(0);
onRemoteRequest(code, dataMessageParcel);
return true;
}
} // namespace SOCPERF
} // namespace OHOS
/* Fuzzer entry point */
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
/* Run your code on data */
OHOS::SOCPERF::DoSomethingInterestingWithMyAPI(data, size);
return 0;
}
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TEST_FUZZTEST_SOCPERF_FUZZER_H
#define TEST_FUZZTEST_SOCPERF_FUZZER_H
#define FUZZ_PROJECT_NAME "socperf_fuzzer"
#endif
+33
View File
@@ -0,0 +1,33 @@
# Copyright (c) 2022-2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
import("../../soc_perf.gni")
ohos_executable("socperf_test") {
sources = [ "socperf_test.cpp" ]
deps = [ "${socperf_interfaces}/inner_api/socperf_client:socperf_client" ]
external_deps = [
"c_utils:utils",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_single",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
part_name = "soc_perf"
subsystem_name = "resourceschedule"
}
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdint> // for int32_t
#include <cstdlib> // for atoi
#include <vector> // for vector
#include <cstring> // for strcmp
#include "socperf_client.h" // for SocPerfClient
const static int32_t PARAMETERS_NUM_MIN = 2;
const static int32_t PARAMETERS_NUM_WITHOUT_EX = 3;
const static int32_t PARAMETERS_NUM_WITH_EX = 4;
const static int32_t PARAMETERS_NUM_LIMIT = 5;
static void PerfRequest(int32_t argc, char *argv[])
{
if (argc == PARAMETERS_NUM_WITHOUT_EX) {
char* cmdId = argv[2];
if (cmdId) {
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(atoi(cmdId), "");
}
}
}
static void PerfRequestEx(int32_t argc, char *argv[])
{
if (argc == PARAMETERS_NUM_WITH_EX) {
char* cmdId = argv[2];
char* onOffTag = argv[3];
if (cmdId && onOffTag) {
if (strcmp(onOffTag, "true") == 0) {
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(atoi(cmdId), true, "");
} else if (strcmp(onOffTag, "false") == 0) {
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(atoi(cmdId), false, "");
}
}
}
}
static void PowerLimitBoost(int32_t argc, char *argv[])
{
if (argc == PARAMETERS_NUM_WITHOUT_EX) {
char* onOffTag = argv[2];
if (onOffTag) {
if (strcmp(onOffTag, "true") == 0) {
OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(true, "");
} else if (strcmp(onOffTag, "false") == 0) {
OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(false, "");
}
}
}
}
static void ThermalLimitBoost(int32_t argc, char *argv[])
{
if (argc == PARAMETERS_NUM_WITHOUT_EX) {
char* onOffTag = argv[2];
if (onOffTag) {
if (strcmp(onOffTag, "true") == 0) {
OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(true, "");
} else if (strcmp(onOffTag, "false") == 0) {
OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(false, "");
}
}
}
}
static void LimitRequest(int32_t argc, char *argv[])
{
if (argc == PARAMETERS_NUM_LIMIT) {
char* clientId = argv[2];
char* tags = argv[3];
char* configs = argv[4];
std::vector<int32_t> tagsVector = { atoi(tags) };
std::vector<int64_t> configsVector = { atoll(configs) };
OHOS::SOCPERF::SocPerfClient::GetInstance().LimitRequest(atoi(clientId), tagsVector, configsVector, "");
}
}
int32_t main(int32_t argc, char *argv[])
{
if (argc >= PARAMETERS_NUM_MIN && argv) {
char* function = argv[1];
if (strcmp(function, "PerfRequest") == 0) {
PerfRequest(argc, argv);
} else if (strcmp(function, "PerfRequestEx") == 0) {
PerfRequestEx(argc, argv);
} else if (strcmp(function, "PowerLimitBoost") == 0) {
PowerLimitBoost(argc, argv);
} else if (strcmp(function, "ThermalLimitBoost") == 0) {
ThermalLimitBoost(argc, argv);
} else if (strcmp(function, "LimitRequest") == 0) {
LimitRequest(argc, argv);
}
}
return 0;
}
+55
View File
@@ -0,0 +1,55 @@
# Copyright (c) 2022-2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
import("../../soc_perf.gni")
module_output_path = "soc_perf/socperftest"
config("module_private_config") {
visibility = [ ":*" ]
include_dirs = [
"${socperf_common}/include",
"${socperf_interfaces}/inner_api/socperf_client/include",
"${socperf_services}/core/include",
]
}
ohos_unittest("SocPerfSubTest") {
module_out_path = module_output_path
sources = [ "socperf_sub_test.cpp" ]
configs = [ ":module_private_config" ]
deps = [
"${socperf_interfaces}/inner_api/socperf_client:socperf_client",
"//third_party/googletest:gtest_main",
"//third_party/libxml2:xml2",
]
external_deps = [
"c_utils:utils",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_single",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
}
group("unittest") {
testonly = true
deps = [ ":SocPerfSubTest" ]
}
+358
View File
@@ -0,0 +1,358 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define private public
#define protected public
#undef private
#undef protected
#include <gtest/gtest.h>
#include "socperf_client.h"
#include "socperf.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
using namespace testing::ext;
namespace OHOS {
namespace SOCPERF {
class SocPerfSubTest : public testing::Test {
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
void TearDown();
};
void SocPerfSubTest::SetUpTestCase(void)
{
}
void SocPerfSubTest::TearDownTestCase(void)
{
}
void SocPerfSubTest::SetUp(void)
{
}
void SocPerfSubTest::TearDown(void)
{
}
/*
* @tc.name: SocPerfSubTest_ActionType_001
* @tc.desc: action type perf
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH38A
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_ActionType_001, Function | MediumTest | Level0)
{
EXPECT_EQ(OHOS::SOCPERF::ActionType::ACTION_TYPE_PERF, 0);
}
/*
* @tc.name: SocPerfSubTest_ActionType_002
* @tc.desc: action type power
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH38A
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_ActionType_002, Function | MediumTest | Level0)
{
EXPECT_EQ(OHOS::SOCPERF::ActionType::ACTION_TYPE_POWER, 1);
}
/*
* @tc.name: SocPerfSubTest_ActionType_003
* @tc.desc: action type THERMAL
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH38A
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_ActionType_003, Function | MediumTest | Level0)
{
EXPECT_EQ(OHOS::SOCPERF::ActionType::ACTION_TYPE_THERMAL, 2);
}
/*
* @tc.name: SocPerfSubTest_ActionType_004
* @tc.desc: action type max
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH38A
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_ActionType_004, Function | MediumTest | Level0)
{
EXPECT_EQ(OHOS::SOCPERF::ActionType::ACTION_TYPE_MAX, 3);
}
/*
* @tc.name: SocPerfSubTest_EventType_001
* @tc.desc: event type off
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH38A
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_EventType_001, Function | MediumTest | Level0)
{
EXPECT_EQ(OHOS::SOCPERF::EventType::EVENT_OFF, 0);
}
/*
* @tc.name: SocPerfSubTest_EventType_002
* @tc.desc: event type on
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH38A
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_EventType_002, Function | MediumTest | Level0)
{
EXPECT_EQ(OHOS::SOCPERF::EventType::EVENT_ON, 1);
}
/*
* @tc.name: SocPerfSubTest_EventType_003
* @tc.desc: event type invalid
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH38A
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_EventType_003, Function | MediumTest | Level0)
{
EXPECT_EQ(OHOS::SOCPERF::EventType::EVENT_INVALID, -1);
}
/*
* @tc.name: SocPerfSubTest_InnerEventId_001
* @tc.desc: init res node info
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH37V
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_001, Function | MediumTest | Level0)
{
EXPECT_EQ(INNER_EVENT_ID_INIT_RES_NODE_INFO, 0);
}
/*
* @tc.name: SocPerfSubTest_InnerEventId_002
* @tc.desc: init gov res node info
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH37V
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_002, Function | MediumTest | Level0)
{
EXPECT_EQ(INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO, 1);
}
/*
* @tc.name: SocPerfSubTest_InnerEventId_003
* @tc.desc: do freq action
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH380
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_003, Function | MediumTest | Level0)
{
EXPECT_EQ(INNER_EVENT_ID_DO_FREQ_ACTION, 2);
}
/*
* @tc.name: SocPerfSubTest_InnerEventId_004
* @tc.desc: do freq action delayed
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH380
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_004, Function | MediumTest | Level0)
{
EXPECT_EQ(INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED, 4);
}
/*
* @tc.name: SocPerfSubTest_InnerEventId_005
* @tc.desc: power limit boost freq
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH380
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_005, Function | MediumTest | Level0)
{
EXPECT_EQ(INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ, 5);
}
/*
* @tc.name: SocPerfSubTest_InnerEventId_006
* @tc.desc: thermal limit boost freq
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH380
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_006, Function | MediumTest | Level0)
{
EXPECT_EQ(INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ, 6);
}
/*
* @tc.name: SocPerfSubTest_GetService_001
* @tc.desc: get socperf service
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH384 AR000GH385
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_GetService_001, Function | MediumTest | Level0)
{
sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
EXPECT_NE(samgr, nullptr);
sptr<IRemoteObject> object = samgr->GetSystemAbility(SOC_PERF_SERVICE_SA_ID);
EXPECT_NE(object, nullptr);
}
/*
* @tc.name: SocPerfSubTest_GetService_002
* @tc.desc: get socperf service
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH38B AR000GH38C AR000GH38D AR000GH38E AR000GH38F AR000GH386 AR000GH387 AR000GH388
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_GetService_002, Function | MediumTest | Level0)
{
sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
EXPECT_NE(samgr, nullptr);
sptr<IRemoteObject> object = samgr->GetSystemAbility(RES_SCHED_SYS_ABILITY_ID);
EXPECT_NE(object, nullptr);
}
/*
* @tc.name: SocPerfSubTest_PerfRequest_001
* @tc.desc: PerfRequest
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH381 AR000GH382 AR000GH389 AR000GH37U
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_001, Function | MediumTest | Level0)
{
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(10000, "");
}
/*
* @tc.name: SocPerfSubTest_PerfRequest_002
* @tc.desc: PerfRequestEx ON
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH381 AR000GH382 AR000GH389 AR000GH37U
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_002, Function | MediumTest | Level0)
{
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, true, "");
}
/*
* @tc.name: SocPerfSubTest_PerfRequest_003
* @tc.desc: PerfRequestEx OFF
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH381 AR000GH382 AR000GH389 AR000GH37U
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_003, Function | MediumTest | Level0)
{
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, false, "");
}
/*
* @tc.name: SocPerfSubTest_PowerLimitBoost_001
* @tc.desc: PowerLimitBoost ON
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH381 AR000GH382 AR000GH389 AR000GH37U
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_PowerLimitBoost_001, Function | MediumTest | Level0)
{
OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(true, "");
}
/*
* @tc.name: SocPerfSubTest_PowerLimitBoost_001
* @tc.desc: PowerLimitBoost OFF
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH381 AR000GH382 AR000GH389 AR000GH37U
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_PowerLimitBoost_002, Function | MediumTest | Level0)
{
OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(false, "");
}
/*
* @tc.name: SocPerfSubTest_ThermalLimitBoost_001
* @tc.desc: ThermalLimitBoost ON
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH381 AR000GH382 AR000GH389 AR000GH37U
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_ThermalLimitBoost_001, Function | MediumTest | Level0)
{
OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(true, "");
}
/*
* @tc.name: SocPerfSubTest_ThermalLimitBoost_002
* @tc.desc: ThermalLimitBoost OFF
* @tc.type FUNC
* @tc.require SR000GGTLG AR000GH381 AR000GH382 AR000GH389 AR000GH37U
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_ThermalLimitBoost_002, Function | MediumTest | Level0)
{
OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(false, "");
}
/*
* @tc.name: SocPerfSubTest_LimitRequest_001
* @tc.desc: LimitRequest thermal
* @tc.type FUNC
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_LimitRequest_001, Function | MediumTest | Level0)
{
int32_t clientId_power = ACTION_TYPE_POWER;
std::vector<int32_t> tags;
tags.push_back(1001);
std::vector<int64_t> configs;
EXPECT_NE(tags.size(), configs.size());
configs.push_back(1608000);
EXPECT_EQ(tags.size(), configs.size());
OHOS::SOCPERF::SocPerfClient::GetInstance().LimitRequest(clientId_power, tags, configs, "");
}
/*
* @tc.name: SocPerfSubTest_LimitRequest_002
* @tc.desc: LimitRequest thermal
* @tc.type FUNC
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_LimitRequest_002, Function | MediumTest | Level0)
{
int32_t clientId_thermal = ACTION_TYPE_THERMAL;
std::vector<int32_t> tags;
tags.push_back(1000);
tags.push_back(1001);
std::vector<int64_t> configs;
EXPECT_NE(tags.size(), configs.size());
configs.push_back(1800000);
configs.push_back(1992000);
EXPECT_EQ(tags.size(), configs.size());
OHOS::SOCPERF::SocPerfClient::GetInstance().LimitRequest(clientId_thermal, tags, configs, "");
}
/*
* @tc.name: SocPerfSubTest_ResetClient_001
* @tc.desc: ResetClient
* @tc.type FUNC
*/
HWTEST_F(SocPerfSubTest, SocPerfSubTest_ResetClient_001, Function | MediumTest | Level0)
{
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(10000, "");
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, true, "");
OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, false, "");
OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(true, "");
OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(false, "");
OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(true, "");
OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(false, "");
OHOS::SOCPERF::SocPerfClient::GetInstance().ResetClient();
}
} // namespace SOCPERF
} // namespace OHOS