1484543d1Sopenharmony_ci/* 2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License. 5484543d1Sopenharmony_ci * You may obtain a copy of the License at 6484543d1Sopenharmony_ci * 7484543d1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8484543d1Sopenharmony_ci * 9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and 13484543d1Sopenharmony_ci * limitations under the License. 14484543d1Sopenharmony_ci */ 15484543d1Sopenharmony_ci 16484543d1Sopenharmony_ci#ifndef OS_ATTR_MANAGER_H 17484543d1Sopenharmony_ci#define OS_ATTR_MANAGER_H 18484543d1Sopenharmony_ci#include <array> 19484543d1Sopenharmony_ci#include <cerrno> 20484543d1Sopenharmony_ci#include <cstring> 21484543d1Sopenharmony_ci#include <fcntl.h> 22484543d1Sopenharmony_ci#include "ffrt_inner.h" 23484543d1Sopenharmony_ci#include "qos.h" 24484543d1Sopenharmony_ci#include "dfx/log/ffrt_log_api.h" 25484543d1Sopenharmony_ci 26484543d1Sopenharmony_cinamespace ffrt { 27484543d1Sopenharmony_ciconst std::string cpuctlGroupIvePath = "/dev/cpuctl/cam2stage"; 28484543d1Sopenharmony_ciconst std::string cpusetGroupIvePath = "/dev/cpuset/cam2stage"; 29484543d1Sopenharmony_ciconst std::string cpuThreadNode = "/tasks"; 30484543d1Sopenharmony_ciconst std::string cpuSharesNode = "/cpu.shares"; 31484543d1Sopenharmony_ciconst std::string cpuMapNode = "/cpus"; 32484543d1Sopenharmony_ci#ifdef OHOS_STANDARD_SYSTEM 33484543d1Sopenharmony_ciconst std::string cpuUclampminNode = "/load.min"; 34484543d1Sopenharmony_ciconst std::string cpuUclampmaxNode = "/load.max"; 35484543d1Sopenharmony_ci#else 36484543d1Sopenharmony_ciconst std::string cpuUclampminNode = "/cpu.uclamp.min"; 37484543d1Sopenharmony_ciconst std::string cpuUclampmaxNode = "/cpu.uclamp.max"; 38484543d1Sopenharmony_ciconst std::string cpuLatencyniceNode = "/cpu.latency.nice"; 39484543d1Sopenharmony_ciconst std::string cpuvipprioNode = "/cpu.vip_prio"; 40484543d1Sopenharmony_ci#endif 41484543d1Sopenharmony_ciconstexpr int PATH_MAX_LENS = 4096; 42484543d1Sopenharmony_ciconstexpr int CGROUP_SHARES_MIN = 2; 43484543d1Sopenharmony_ciconstexpr int CGROUP_SHARES_MAX = 262144; 44484543d1Sopenharmony_ciconstexpr int CGROUP_LAT_NICE_MIN = -20; 45484543d1Sopenharmony_ciconstexpr int CGROUP_LAT_NICE_MAX = 19; 46484543d1Sopenharmony_ciconstexpr int CGROUP_UCLAMP_MIN = 0; 47484543d1Sopenharmony_ciconstexpr int CGROUP_UCLAMP_MAX = 100; 48484543d1Sopenharmony_ciconstexpr int CGROUP_VIPPRIO_MIN = 0; 49484543d1Sopenharmony_ciconstexpr int CGROUP_VIPPRIO_MAX = 10; 50484543d1Sopenharmony_ciclass OSAttrManager { 51484543d1Sopenharmony_cipublic: 52484543d1Sopenharmony_ci OSAttrManager() {} 53484543d1Sopenharmony_ci ~OSAttrManager() {} 54484543d1Sopenharmony_ci 55484543d1Sopenharmony_ci static inline OSAttrManager* Instance() 56484543d1Sopenharmony_ci { 57484543d1Sopenharmony_ci static OSAttrManager instance; 58484543d1Sopenharmony_ci return &instance; 59484543d1Sopenharmony_ci } 60484543d1Sopenharmony_ci 61484543d1Sopenharmony_ci bool CheckSchedAttrPara(const std::string &name, int min, int max, int paraValue); 62484543d1Sopenharmony_ci int UpdateSchedAttr(const QoS& qos, ffrt_os_sched_attr *attr); 63484543d1Sopenharmony_ci void SetCGroupCtlPara(const std::string &name, int32_t value); 64484543d1Sopenharmony_ci void SetCGroupSetPara(const std::string &name, const std::string &value); 65484543d1Sopenharmony_ci void SetTidToCGroup(int32_t pid); 66484543d1Sopenharmony_ci void SetTidToCGroupPrivate(const std::string &filename, int32_t pid); 67484543d1Sopenharmony_ci template <typename T> 68484543d1Sopenharmony_ci void SetCGroupPara(const std::string &filename, T& value) 69484543d1Sopenharmony_ci { 70484543d1Sopenharmony_ci char filePath[PATH_MAX_LENS] = {0}; 71484543d1Sopenharmony_ci if (filename.empty()) { 72484543d1Sopenharmony_ci FFRT_LOGE("[cgroup_ctrl] invalid para, filename is empty"); 73484543d1Sopenharmony_ci return; 74484543d1Sopenharmony_ci } 75484543d1Sopenharmony_ci 76484543d1Sopenharmony_ci if ((strlen(filename.c_str()) > PATH_MAX_LENS) || (realpath(filename.c_str(), filePath) == nullptr)) { 77484543d1Sopenharmony_ci FFRT_LOGE("[cgroup_ctrl] invalid file path:%s, error:%s\n", filename.c_str(), strerror(errno)); 78484543d1Sopenharmony_ci return; 79484543d1Sopenharmony_ci } 80484543d1Sopenharmony_ci 81484543d1Sopenharmony_ci int32_t fd = open(filePath, O_RDWR); 82484543d1Sopenharmony_ci if (fd < 0) { 83484543d1Sopenharmony_ci FFRT_LOGE("[cgroup_ctrl] fail to open filePath:%s", filePath); 84484543d1Sopenharmony_ci return; 85484543d1Sopenharmony_ci } 86484543d1Sopenharmony_ci 87484543d1Sopenharmony_ci std::string valueStr; 88484543d1Sopenharmony_ci if constexpr (std::is_same<T, int32_t>::value) { 89484543d1Sopenharmony_ci valueStr = std::to_string(value); 90484543d1Sopenharmony_ci } else if constexpr (std::is_same<T, const std::string>::value) { 91484543d1Sopenharmony_ci valueStr = value; 92484543d1Sopenharmony_ci } else { 93484543d1Sopenharmony_ci FFRT_LOGE("[cgroup_ctrl] invalid value type\n"); 94484543d1Sopenharmony_ci close(fd); 95484543d1Sopenharmony_ci return; 96484543d1Sopenharmony_ci } 97484543d1Sopenharmony_ci 98484543d1Sopenharmony_ci int32_t ret = write(fd, valueStr.c_str(), valueStr.size()); 99484543d1Sopenharmony_ci if (ret < 0) { 100484543d1Sopenharmony_ci FFRT_LOGE("[cgroup_ctrl] fail to write path:%s valueStr:%s to fd:%d, errno:%d", 101484543d1Sopenharmony_ci filePath, valueStr.c_str(), fd, errno); 102484543d1Sopenharmony_ci close(fd); 103484543d1Sopenharmony_ci return; 104484543d1Sopenharmony_ci } 105484543d1Sopenharmony_ci 106484543d1Sopenharmony_ci const uint32_t bufferLen = 20; 107484543d1Sopenharmony_ci std::array<char, bufferLen> buffer {}; 108484543d1Sopenharmony_ci int32_t count = read(fd, buffer.data(), bufferLen); 109484543d1Sopenharmony_ci if (count <= 0) { 110484543d1Sopenharmony_ci FFRT_LOGE("[cgroup_ctrl] fail to read value:%s to fd:%d, errno:%d", buffer.data(), fd, errno); 111484543d1Sopenharmony_ci } else { 112484543d1Sopenharmony_ci FFRT_LOGI("[cgroup_ctrl] success to read %s buffer:%s", filePath, buffer.data()); 113484543d1Sopenharmony_ci } 114484543d1Sopenharmony_ci close(fd); 115484543d1Sopenharmony_ci } 116484543d1Sopenharmony_ci}; 117484543d1Sopenharmony_ci} // namespace ffrt 118484543d1Sopenharmony_ci 119484543d1Sopenharmony_ci#endif /* OS_ATTR_MANAGER_H */