• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "cgroup_map.h"
16 #include <cstdint>              // for uint32_t
17 #include <string>               // for basic_string, operator<
18 #include <cstring>              // for strcmp
19 #include <type_traits>          // for remove_reference<>::type, move
20 #include <utility>              // for pair, make_pair
21 #include <vector>               // for vector
22 #include "cgroup_action.h"      // for CgroupAction
23 #include "process_group_log.h"  // for PGCGS_LOGE, PGCGS_LOGD, PGCGS_LOGI
24 
25 namespace OHOS {
26 namespace ResourceSchedule {
27 namespace CgroupSetting {
28 namespace {
29     constexpr const char * const JSON_KEY_CGROUPS = "Cgroups";
30     constexpr const char * const JSON_KEY_CONTROLLER = "controller";
31     constexpr const char * const JSON_KEY_PATH = "path";
32     constexpr const char * const JSON_KEY_SCHED_POLICY = "sched_policy";
33 }
34 
GetInstance()35 CgroupMap& CgroupMap::GetInstance()
36 {
37     static CgroupMap instance;
38     return instance;
39 }
40 
SetThreadSchedPolicy(int tid,SchedPolicy policy,bool isThreadGroup)41 bool CgroupMap::SetThreadSchedPolicy(int tid, SchedPolicy policy, bool isThreadGroup)
42 {
43     for (auto it = controllers_.begin(); it != controllers_.end(); ++it) {
44         CgroupController& controller = it -> second;
45         if (controller.IsEnabled()) {
46             if (!controller.SetThreadSchedPolicy(tid, policy, isThreadGroup)) {
47                 PGCGS_LOGD("%{public}s failed, controller = %{public}s, policy = %{public}d.",
48                     __func__, controller.GetName().c_str(), policy);
49             }
50         }
51     }
52     return true;
53 }
54 
AddCgroupController(const std::string & name,CgroupController & controller)55 void CgroupMap::AddCgroupController(const std::string& name, CgroupController& controller)
56 {
57     controllers_.insert(std::make_pair(name, std::move(controller)));
58 }
59 
LoadConfigFromJsonObj(const nlohmann::json & jsonObj)60 bool CgroupMap::LoadConfigFromJsonObj(const nlohmann::json& jsonObj)
61 {
62     const nlohmann::json& jsonArrObj = jsonObj[JSON_KEY_CGROUPS];
63     // check json format
64     if (!jsonArrObj.is_array()) {
65         PGCGS_LOGE("%{public}s json config format error, CgroupMap: disabled!", __func__);
66         return false;
67     }
68     int count = 0;
69     int32_t objSize = static_cast<int32_t>(jsonArrObj.size());
70     for (int32_t i = 0; i < objSize; ++i) {
71         const nlohmann::json& cgroupObj = jsonArrObj[i];
72         const nlohmann::json& nameObj = cgroupObj[JSON_KEY_CONTROLLER];
73         const nlohmann::json& pathObj = cgroupObj[JSON_KEY_PATH];
74         if (!nameObj.is_string() || !pathObj.is_string()) {
75             PGCGS_LOGE("%{public}s invalid controller config.", __func__);
76             continue;
77         }
78         std::string name = nameObj.get<std::string>();
79         std::string rootPath = pathObj.get<std::string>();
80         if (name.empty() || rootPath.empty()) {
81             PGCGS_LOGE("%{public}s empty controller config.", __func__);
82             continue;
83         }
84 
85         CgroupController controller(name, rootPath);
86         if (LoadSchedPolicyConfig(controller, cgroupObj[JSON_KEY_SCHED_POLICY])) {
87             this->AddCgroupController(name, controller);
88             count++;
89         } else {
90             PGCGS_LOGE("%{public}s no valid policy config item.", __func__);
91         }
92     }
93 
94     if (count == 0) {
95         PGCGS_LOGW("%{public}s The number of valid cgroup config is 0, CgroupMap: disabled!", __func__);
96         return false;
97     }
98     PGCGS_LOGI("%{public}s CgroupMap: enabled!", __func__);
99     return true;
100 }
101 
LoadSchedPolicyConfig(CgroupController & controller,const nlohmann::json & policyObj)102 bool CgroupMap::LoadSchedPolicyConfig(CgroupController& controller, const nlohmann::json& policyObj)
103 {
104     if (!policyObj.is_object()) {
105         PGCGS_LOGE("%{public}s invalid policy config.", __func__);
106         return false;
107     }
108 
109     auto policyList = CgroupAction::GetInstance().GetSchedPolicyList();
110     uint32_t count = 0;
111     for (SchedPolicy policy : policyList) {
112         const char* keyString = GetSchedPolicyFullName(policy);
113         if (!keyString || !strcmp(keyString, "error")) {
114             continue;
115         }
116         const nlohmann::json& obj = policyObj[keyString];
117         if (!obj.is_string()) {
118             PGCGS_LOGE("%{public}s %s is not properly configed.", __func__, keyString);
119             continue;
120         }
121         if (controller.AddSchedPolicy(policy, obj.get<std::string>())) {
122             count++;
123         }
124     }
125     return (count > 0);
126 }
127 
FindFristEnableCgroupController(CgroupController ** p)128 bool CgroupMap::FindFristEnableCgroupController(CgroupController** p)
129 {
130     for (auto it = controllers_.begin(); it != controllers_.end(); ++it) {
131         if (it->second.IsEnabled()) {
132             *p = &(it->second);
133             return true;
134         }
135     }
136     return false;
137 }
138 } // namespace CgroupSetting
139 } // namespace ResourceSchedule
140 } // namespace OHOS
141