1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OS_ATTR_MANAGER_H
17 #define OS_ATTR_MANAGER_H
18 #include <array>
19 #include <cerrno>
20 #include <cstring>
21 #include <fcntl.h>
22 #include "ffrt_inner.h"
23 #include "qos.h"
24 #include "dfx/log/ffrt_log_api.h"
25 
26 namespace ffrt {
27 const std::string cpuctlGroupIvePath = "/dev/cpuctl/cam2stage";
28 const std::string cpusetGroupIvePath = "/dev/cpuset/cam2stage";
29 const std::string cpuThreadNode = "/tasks";
30 const std::string cpuSharesNode = "/cpu.shares";
31 const std::string cpuMapNode = "/cpus";
32 #ifdef OHOS_STANDARD_SYSTEM
33 const std::string cpuUclampminNode = "/load.min";
34 const std::string cpuUclampmaxNode = "/load.max";
35 #else
36 const std::string cpuUclampminNode = "/cpu.uclamp.min";
37 const std::string cpuUclampmaxNode = "/cpu.uclamp.max";
38 const std::string cpuLatencyniceNode = "/cpu.latency.nice";
39 const std::string cpuvipprioNode = "/cpu.vip_prio";
40 #endif
41 const int PATH_MAX_LENS = 4096;
42 const int CGROUP_SHARES_MIN = 2;
43 const int CGROUP_SHARES_MAX = 262144;
44 const int CGROUP_LAT_NICE_MIN = -20;
45 const int CGROUP_LAT_NICE_MAX = 19;
46 const int CGROUP_UCLAMP_MIN = 0;
47 const int CGROUP_UCLAMP_MAX = 100;
48 const int CGROUP_VIPPRIO_MIN = 0;
49 const int CGROUP_VIPPRIO_MAX = 10;
50 class OSAttrManager {
51 public:
OSAttrManager()52     OSAttrManager() {}
~OSAttrManager()53     ~OSAttrManager() {}
54 
Instance()55     static inline OSAttrManager* Instance()
56     {
57         static OSAttrManager instance;
58         return &instance;
59     }
60 
61     bool CheckSchedAttrPara(const std::string &name, int min, int max, int paraValue);
62     int UpdateSchedAttr(const QoS& qos, ffrt_os_sched_attr *attr);
63     void SetCGroupCtlPara(const std::string &name, int32_t value);
64     void SetCGroupSetPara(const std::string &name, const std::string &value);
65     void SetTidToCGroup(int32_t pid);
66     void SetTidToCGroupPrivate(const std::string &filename, int32_t pid);
67     template <typename T>
SetCGroupPara(const std::string & filename,T & value)68     void SetCGroupPara(const std::string &filename, T& value)
69     {
70         char filePath[PATH_MAX_LENS] = {0};
71         if (filename.empty()) {
72             FFRT_LOGE("[cgroup_ctrl] invalid para, filename is empty");
73             return;
74         }
75 
76         if ((strlen(filename.c_str()) > PATH_MAX_LENS) || (realpath(filename.c_str(), filePath) == nullptr)) {
77             FFRT_LOGE("[cgroup_ctrl] invalid file path:%s, error:%s\n", filename.c_str(), strerror(errno));
78             return;
79         }
80 
81         int32_t fd = open(filePath, O_RDWR);
82         if (fd < 0) {
83             FFRT_LOGE("[cgroup_ctrl] fail to open filePath:%s", filePath);
84             return;
85         }
86 
87         std::string valueStr;
88         if constexpr (std::is_same<T, int32_t>::value) {
89             valueStr = std::to_string(value);
90         } else if constexpr (std::is_same<T, const std::string>::value) {
91             valueStr = value;
92         } else {
93             FFRT_LOGE("[cgroup_ctrl] invalid value type\n");
94             close(fd);
95             return;
96         }
97 
98         int32_t ret = write(fd, valueStr.c_str(), valueStr.size());
99         if (ret < 0) {
100             FFRT_LOGE("[cgroup_ctrl] fail to write path:%s valueStr:%s to fd:%d, errno:%d",
101                 filePath, valueStr.c_str(), fd, errno);
102             close(fd);
103             return;
104         }
105 
106         const uint32_t bufferLen = 20;
107         std::array<char, bufferLen> buffer {};
108         int32_t count = read(fd, buffer.data(), bufferLen);
109         if (count <= 0) {
110             FFRT_LOGE("[cgroup_ctrl] fail to read value:%s to fd:%d, errno:%d", buffer.data(), fd, errno);
111         } else {
112             FFRT_LOGI("[cgroup_ctrl] success to read %s buffer:%s", filePath, buffer.data());
113         }
114         close(fd);
115     }
116 };
117 } // namespace ffrt
118 
119 #endif /* OS_ATTR_MANAGER_H */