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 */