1 /*
2 * Copyright (c) 2021 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_manager.h"
16 #include <cerrno>
17 #include <cinttypes>
18 #include <cstdlib>
19 #include <cstdio>
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <sys/eventfd.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include "app_log_wrapper.h"
26 #include "event_handler.h"
27 #include "securec.h"
28
29 constexpr std::string_view CG_CPUSET_DEFAULT_TASKS_PATH("/dev/cpuset/tasks");
30 constexpr std::string_view CG_CPUSET_BACKGROUND_TASKS_PATH("/dev/cpuset/background/tasks");
31 constexpr std::string_view CG_CPUCTL_DEFAULT_TASKS_PATH("/dev/cpuctl/tasks");
32 constexpr std::string_view CG_CPUCTL_BACKGROUND_TASKS_PATH("/dev/cpuctl/background/tasks");
33 constexpr std::string_view CG_FREEZER_FROZEN_TASKS_PATH("/dev/freezer/frozen/tasks");
34 constexpr std::string_view CG_FREEZER_THAWED_TASKS_PATH("/dev/freezer/thawed/tasks");
35 [[maybe_unused]] constexpr std::string_view CG_MEM_OOMCTL_PATH("/dev/memcg/memory.oom_control");
36 constexpr std::string_view CG_MEM_EVTCTL_PATH("/dev/memcg/cgroup.event_control");
37 constexpr std::string_view CG_MEM_PRESSURE_LEVEL_PATH("/dev/memcg/memory.pressure_level");
38
39 namespace OHOS {
40 namespace AppExecFwk {
41 namespace {
42 class ScopeGuard final {
43 public:
44 using Function = std::function<void()>;
45
46 public:
ScopeGuard(Function fn)47 explicit ScopeGuard(Function fn) : fn_(fn), dismissed_(false)
48 {}
49
~ScopeGuard()50 ~ScopeGuard()
51 {
52 if (!dismissed_) {
53 fn_();
54 }
55 }
56
57 public:
Dismiss()58 void Dismiss()
59 {
60 dismissed_ = true;
61 }
62
63 private:
64 Function fn_;
65 bool dismissed_ = false;
66 };
67
WriteValue(int fd,std::string_view v)68 int WriteValue(int fd, std::string_view v)
69 {
70 if (fd < 0) {
71 errno = EINVAL;
72 return -1;
73 }
74
75 int ret = TEMP_FAILURE_RETRY(write(fd, v.data(), v.size()));
76 if (ret != 0) {
77 APP_LOGE("%{public}s(%{public}d) err: %{public}s.", __func__, __LINE__, strerror(errno));
78 }
79 fsync(fd);
80
81 return ret;
82 }
83
WriteValue(int fd,int v,bool newLine=true)84 int WriteValue(int fd, int v, bool newLine = true)
85 {
86 if (fd < 0) {
87 errno = EINVAL;
88 return -1;
89 }
90
91 char str[32] = {0};
92
93 int len = snprintf_s(str, sizeof(str), sizeof(str) - 1, newLine ? "%d\n" : "%d", v);
94 if (len < 1) {
95 return -1;
96 }
97
98 return WriteValue(fd, str);
99 }
100
101 } // namespace
102
CgroupManager()103 CgroupManager::CgroupManager()
104 {}
105
~CgroupManager()106 CgroupManager::~CgroupManager()
107 {
108 for (int i = 0; i < LOW_MEMORY_LEVEL_MAX; ++i) {
109 if (memoryEventFds_[i] >= 0) {
110 if (eventHandler_) {
111 eventHandler_->RemoveFileDescriptorListener(memoryEventFds_[i]);
112 }
113 close(memoryEventFds_[i]);
114 }
115 if (memoryPressureFds_[i] >= 0) {
116 close(memoryPressureFds_[i]);
117 }
118 }
119
120 if (memoryEventControlFd_ >= 0) {
121 close(memoryEventControlFd_);
122 }
123
124 for (int i = 0; i < SCHED_POLICY_CPU_MAX; ++i) {
125 if (cpusetTasksFds_[i] >= 0) {
126 close(cpusetTasksFds_[i]);
127 }
128 }
129 }
130
Init()131 bool CgroupManager::Init()
132 {
133 APP_LOGE("%{public}s(%{public}d) Init enter.", __func__, __LINE__);
134 if (IsInited()) {
135 APP_LOGE("%{public}s(%{public}d) already inited.", __func__, __LINE__);
136 return false;
137 }
138
139 auto eventHandler = std::make_shared<EventHandler>(EventRunner::Create());
140 if (!eventHandler) {
141 APP_LOGE("%{public}s(%{public}d) failed to get event handler.", __func__, __LINE__);
142 return false;
143 }
144
145 if(!InitCheck()){
146 return false;
147 }
148
149 if (!RegisterLowMemoryMonitor(
150 memoryEventFds_, memoryPressureFds_, memoryEventControlFd_, LOW_MEMORY_LEVEL_LOW, eventHandler)) {
151 return false;
152 }
153
154 ScopeGuard lowLevelListenerGuard(
155 [&]() { eventHandler->RemoveFileDescriptorListener(memoryEventFds_[LOW_MEMORY_LEVEL_LOW]); });
156
157 if (!RegisterLowMemoryMonitor(
158 memoryEventFds_, memoryPressureFds_, memoryEventControlFd_, LOW_MEMORY_LEVEL_MEDIUM, eventHandler)) {
159 return false;
160 }
161
162 ScopeGuard mediumLevelListenerGuard(
163 [&]() { eventHandler->RemoveFileDescriptorListener(memoryEventFds_[LOW_MEMORY_LEVEL_MEDIUM]); });
164
165 if (!RegisterLowMemoryMonitor(
166 memoryEventFds_, memoryPressureFds_, memoryEventControlFd_, LOW_MEMORY_LEVEL_CRITICAL, eventHandler)) {
167 return false;
168 }
169
170 ScopeGuard criticalLevelListenerGuard(
171 [&]() { eventHandler->RemoveFileDescriptorListener(memoryEventFds_[LOW_MEMORY_LEVEL_CRITICAL]); });
172
173 eventHandler_ = eventHandler;
174 lowLevelListenerGuard.Dismiss();
175 mediumLevelListenerGuard.Dismiss();
176 criticalLevelListenerGuard.Dismiss();
177
178 return true;
179 }
180
InitCheck()181 bool CgroupManager::InitCheck()
182 {
183 UniqueFd cpusetTasksFds[SCHED_POLICY_CPU_MAX];
184 if (!InitCpusetTasksFds(cpusetTasksFds)) {
185 return false;
186 }
187
188 UniqueFd cpuctlTasksFds[SCHED_POLICY_CPU_MAX];
189 if (!InitCpuctlTasksFds(cpuctlTasksFds)) {
190 return false;
191 }
192
193 UniqueFd freezerTasksFds[SCHED_POLICY_FREEZER_MAX];
194 if (!InitFreezerTasksFds(freezerTasksFds)) {
195 return false;
196 }
197
198 UniqueFd memoryEventControlFd;
199 if (!InitMemoryEventControlFd(memoryEventControlFd)) {
200 return false;
201 }
202
203 UniqueFd memoryEventFds[LOW_MEMORY_LEVEL_MAX];
204 if (!InitMemoryEventFds(memoryEventFds)) {
205 return false;
206 }
207
208 UniqueFd memoryPressureFds[LOW_MEMORY_LEVEL_MAX];
209 if (!InitMemoryPressureFds(memoryPressureFds)) {
210 return false;
211 }
212 return true;
213 }
214
IsInited() const215 bool CgroupManager::IsInited() const
216 {
217 return bool(eventHandler_);
218 }
219
SetThreadSchedPolicy(int tid,SchedPolicy schedPolicy)220 bool CgroupManager::SetThreadSchedPolicy(int tid, SchedPolicy schedPolicy)
221 {
222 if (!IsInited()) {
223 APP_LOGE("%{public}s(%{public}d) not inited.", __func__, __LINE__);
224 return false;
225 }
226
227 if (tid < 1) {
228 APP_LOGE("%{public}s(%{public}d) invalid tid %{public}d.", __func__, __LINE__, tid);
229 return false;
230 }
231
232 if (schedPolicy < 0 || schedPolicy >= SchedPolicy::SCHED_POLICY_MAX) {
233 APP_LOGE("%{public}s(%{public}d) invalid sched policy %{public}d.", __func__, __LINE__, schedPolicy);
234 return false;
235 }
236
237 if (schedPolicy == SchedPolicy::SCHED_POLICY_FREEZED) {
238 // set frozen of freezer
239 if (!SetFreezerSubsystem(tid, SchedPolicyFreezer::SCHED_POLICY_FREEZER_FROZEN)) {
240 APP_LOGE("%{public}s(%{public}d) set freezer subsystem failed sched policy %{public}d.",
241 __func__,
242 __LINE__,
243 schedPolicy);
244 return false;
245 }
246 } else {
247 // set cpuset
248 if (!SetCpusetSubsystem(tid, schedPolicy)) {
249 APP_LOGE("%{public}s(%{public}d) set cpuset subsystem failed sched policy %{public}d.",
250 __func__,
251 __LINE__,
252 schedPolicy);
253 return false;
254 }
255 // set cpuctl
256 if (!SetCpuctlSubsystem(tid, schedPolicy)) {
257 APP_LOGE("%{public}s(%{public}d) set cpuctl subsystem failed sched policy %{public}d.",
258 __func__,
259 __LINE__,
260 schedPolicy);
261 return false;
262 }
263
264 // set thawed of freezer
265 if (!SetFreezerSubsystem(tid, SchedPolicyFreezer::SCHED_POLICY_FREEZER_THAWED)) {
266 APP_LOGE("%{public}s(%{public}d) set freezer subsystem failed sched policy %{public}d.",
267 __func__,
268 __LINE__,
269 schedPolicy);
270 return false;
271 }
272 }
273
274 return true;
275 }
276
SetProcessSchedPolicy(int pid,SchedPolicy schedPolicy)277 bool CgroupManager::SetProcessSchedPolicy(int pid, SchedPolicy schedPolicy)
278 {
279 if (!IsInited()) {
280 APP_LOGE("%{public}s(%{public}d) not inited.", __func__, __LINE__);
281 return false;
282 }
283
284 if (pid < 1) {
285 APP_LOGE("%{public}s(%{public}d) invalid pid %{public}d", __func__, __LINE__, pid);
286 return false;
287 }
288
289 if (schedPolicy < 0 && schedPolicy >= SCHED_POLICY_MAX) {
290 APP_LOGE("%{public}s(%{public}d) invalid sched policy %{public}d", __func__, __LINE__, schedPolicy);
291 return false;
292 }
293
294 // Set all threads's sched policy inside this process.
295 char taskDir[64];
296 if (snprintf_s(taskDir, sizeof(taskDir), sizeof(taskDir) - 1, "/proc/%d/task", pid) < 0) {
297 return false;
298 }
299
300 DIR *dir = opendir(taskDir);
301 if (dir == nullptr) {
302 APP_LOGE("%{public}s(%{public}d) failed to opendir invalid pid %{public}d taskDir %{public}s , %{public}s",
303 __func__,
304 __LINE__,
305 pid,
306 taskDir,
307 strerror(errno));
308 return false;
309 }
310
311 struct dirent *dent;
312 while ((dent = readdir(dir))) {
313 // Filter out '.' & '..'
314 if (dent->d_name[0] != '.') {
315 SetThreadSchedPolicy(atoi(dent->d_name), schedPolicy);
316 }
317 }
318
319 closedir(dir);
320
321 return true;
322 }
323
OnReadable(int32_t fd)324 void CgroupManager::OnReadable(int32_t fd)
325 {
326 APP_LOGW("%{public}s(%{public}d) system low memory alert.", __func__, __LINE__);
327
328 if (!LowMemoryAlert) {
329 APP_LOGE("%{public}s(%{public}d) 'LowMemoryAlert' not available.", __func__, __LINE__);
330 return;
331 }
332
333 auto TryToRaiseLowMemoryAlert = [=](LowMemoryLevel level) {
334 if (fd == memoryEventFds_[level]) {
335 APP_LOGW("%{public}s(%{public}d) checking level %{public}d", __func__, __LINE__, level);
336 uint64_t count = 0;
337 int ret = TEMP_FAILURE_RETRY(read(fd, &count, sizeof(uint64_t)));
338 if (ret <= 0) {
339 APP_LOGW("%{public}s(%{public}d) failed to read eventfd %{public}d.", __func__, __LINE__, errno);
340 return false;
341 }
342 if (count < 1) {
343 APP_LOGW(
344 "%{public}s(%{public}d) invalid eventfd count %{public}" PRIu64 ".", __func__, __LINE__, count);
345 return false;
346 }
347 APP_LOGW(
348 "%{public}s(%{public}d) raising low memory alert for level %{public}d...", __func__, __LINE__, level);
349 LowMemoryAlert(level);
350 return true;
351 }
352 return false;
353 };
354
355 if (TryToRaiseLowMemoryAlert(LOW_MEMORY_LEVEL_LOW)) {
356 return;
357 }
358
359 if (TryToRaiseLowMemoryAlert(LOW_MEMORY_LEVEL_MEDIUM)) {
360 return;
361 }
362
363 if (TryToRaiseLowMemoryAlert(LOW_MEMORY_LEVEL_CRITICAL)) {
364 return;
365 }
366
367 // Should not reach here!
368 APP_LOGE("%{public}s(%{public}d) Unknown fd %{public}d.", __func__, __LINE__, fd);
369 }
370
RegisterLowMemoryMonitor(const int memoryEventFds[LOW_MEMORY_LEVEL_MAX],const int memoryPressureFds[LOW_MEMORY_LEVEL_MAX],const int memoryEventControlFd,const LowMemoryLevel level,const std::shared_ptr<EventHandler> & eventHandler)371 bool CgroupManager::RegisterLowMemoryMonitor(const int memoryEventFds[LOW_MEMORY_LEVEL_MAX],
372 const int memoryPressureFds[LOW_MEMORY_LEVEL_MAX], const int memoryEventControlFd, const LowMemoryLevel level,
373 const std::shared_ptr<EventHandler> &eventHandler)
374 {
375 APP_LOGI("RegisterLowMemoryMonitor(%{public}d) registering low memory monitor %{public}d...", __LINE__, level);
376
377 char buf[64] = {0};
378 static const char *levelName[] = {"low", "medium", "critical"};
379
380 if (snprintf_s(buf,
381 sizeof(buf),
382 sizeof(buf) - 1,
383 "%d %d %s",
384 memoryEventFds[level],
385 memoryPressureFds[level],
386 levelName[level]) < 0) {
387 return false;
388 }
389
390 int ret = TEMP_FAILURE_RETRY(write(memoryEventControlFd, buf, strlen(buf) + 1));
391 if (ret < 0) {
392 APP_LOGI("RegisterLowMemoryMonitor(%{public}d) failed to write memory control %{public}d...", __LINE__, errno);
393 return false;
394 }
395
396 eventHandler->AddFileDescriptorListener(memoryEventFds[level], FILE_DESCRIPTOR_INPUT_EVENT, shared_from_this());
397
398 return true;
399 }
400
InitCpusetTasksFds(UniqueFd cpusetTasksFds[SCHED_POLICY_CPU_MAX])401 bool CgroupManager::InitCpusetTasksFds(UniqueFd cpusetTasksFds[SCHED_POLICY_CPU_MAX])
402 {
403 cpusetTasksFds[SCHED_POLICY_CPU_DEFAULT] = UniqueFd(open(CG_CPUSET_DEFAULT_TASKS_PATH.data(), O_RDWR));
404 cpusetTasksFds[SCHED_POLICY_CPU_BACKGROUND] = UniqueFd(open(CG_CPUSET_BACKGROUND_TASKS_PATH.data(), O_RDWR));
405 if (cpusetTasksFds[SCHED_POLICY_CPU_DEFAULT].Get() < 0 || cpusetTasksFds[SCHED_POLICY_CPU_BACKGROUND].Get() < 0) {
406 APP_LOGE("%{public}s(%{public}d) cannot open cpuset cgroups %{public}d.", __func__, __LINE__, errno);
407 return false;
408 }
409
410 cpusetTasksFds_[SCHED_POLICY_CPU_DEFAULT] = cpusetTasksFds[SCHED_POLICY_CPU_DEFAULT].Release();
411 cpusetTasksFds_[SCHED_POLICY_CPU_BACKGROUND] = cpusetTasksFds[SCHED_POLICY_CPU_BACKGROUND].Release();
412 return true;
413 }
414
InitCpuctlTasksFds(UniqueFd cpuctlTasksFds[SCHED_POLICY_CPU_MAX])415 bool CgroupManager::InitCpuctlTasksFds(UniqueFd cpuctlTasksFds[SCHED_POLICY_CPU_MAX])
416 {
417 cpuctlTasksFds[SCHED_POLICY_CPU_DEFAULT] = UniqueFd(open(CG_CPUCTL_DEFAULT_TASKS_PATH.data(), O_RDWR));
418 cpuctlTasksFds[SCHED_POLICY_CPU_BACKGROUND] = UniqueFd(open(CG_CPUCTL_BACKGROUND_TASKS_PATH.data(), O_RDWR));
419 if (cpuctlTasksFds[SCHED_POLICY_CPU_DEFAULT].Get() < 0 || cpuctlTasksFds[SCHED_POLICY_CPU_BACKGROUND].Get() < 0) {
420 APP_LOGE("%{public}s(%{public}d) cannot open cpuctl cgroups %{public}d.", __func__, __LINE__, errno);
421 return false;
422 }
423
424 cpuctlTasksFds_[SCHED_POLICY_CPU_DEFAULT] = cpuctlTasksFds[SCHED_POLICY_CPU_DEFAULT].Release();
425 cpuctlTasksFds_[SCHED_POLICY_CPU_BACKGROUND] = cpuctlTasksFds[SCHED_POLICY_CPU_BACKGROUND].Release();
426 return true;
427 }
428
InitFreezerTasksFds(UniqueFd freezerTasksFds[SCHED_POLICY_FREEZER_MAX])429 bool CgroupManager::InitFreezerTasksFds(UniqueFd freezerTasksFds[SCHED_POLICY_FREEZER_MAX])
430 {
431 freezerTasksFds[SCHED_POLICY_FREEZER_FROZEN] = UniqueFd(open(CG_FREEZER_FROZEN_TASKS_PATH.data(), O_RDWR));
432 freezerTasksFds[SCHED_POLICY_FREEZER_THAWED] = UniqueFd(open(CG_FREEZER_THAWED_TASKS_PATH.data(), O_RDWR));
433 if (freezerTasksFds[SCHED_POLICY_FREEZER_FROZEN].Get() < 0 ||
434 freezerTasksFds[SCHED_POLICY_FREEZER_THAWED].Get() < 0) {
435 APP_LOGE("%{public}s(%{public}d) cannot open freezer cgroups %{public}d.", __func__, __LINE__, errno);
436 return false;
437 }
438
439 freezerTasksFds_[SCHED_POLICY_FREEZER_FROZEN] = freezerTasksFds[SCHED_POLICY_FREEZER_FROZEN].Release();
440 freezerTasksFds_[SCHED_POLICY_FREEZER_THAWED] = freezerTasksFds[SCHED_POLICY_FREEZER_THAWED].Release();
441 return true;
442 }
443
InitMemoryEventControlFd(UniqueFd & memoryEventControlFd)444 bool CgroupManager::InitMemoryEventControlFd(UniqueFd &memoryEventControlFd)
445 {
446 memoryEventControlFd = UniqueFd(open(CG_MEM_EVTCTL_PATH.data(), O_WRONLY));
447 if (memoryEventControlFd.Get() < 0) {
448 APP_LOGE(
449 "%{pubid}s(%{publid}d) failed to open memory event control node %{public}d.", __func__, __LINE__, errno);
450 return false;
451 }
452
453 memoryEventControlFd_ = memoryEventControlFd.Release();
454 return true;
455 }
456
InitMemoryEventFds(UniqueFd memoryEventFds[LOW_MEMORY_LEVEL_MAX])457 bool CgroupManager::InitMemoryEventFds(UniqueFd memoryEventFds[LOW_MEMORY_LEVEL_MAX])
458 {
459 memoryEventFds[LOW_MEMORY_LEVEL_LOW] = UniqueFd(eventfd(0, EFD_NONBLOCK));
460 memoryEventFds[LOW_MEMORY_LEVEL_MEDIUM] = UniqueFd(eventfd(0, EFD_NONBLOCK));
461 memoryEventFds[LOW_MEMORY_LEVEL_CRITICAL] = UniqueFd(eventfd(0, EFD_NONBLOCK));
462 if (memoryEventFds[LOW_MEMORY_LEVEL_LOW].Get() < 0 || memoryEventFds[LOW_MEMORY_LEVEL_MEDIUM].Get() < 0 ||
463 memoryEventFds[LOW_MEMORY_LEVEL_CRITICAL].Get() < 0) {
464 APP_LOGE("%{public}s(${public}d) failed to create memory eventfd %{public}d.", __func__, __LINE__, errno);
465 return false;
466 }
467
468 memoryEventFds_[LOW_MEMORY_LEVEL_LOW] = memoryEventFds[LOW_MEMORY_LEVEL_LOW].Release();
469 memoryEventFds_[LOW_MEMORY_LEVEL_MEDIUM] = memoryEventFds[LOW_MEMORY_LEVEL_MEDIUM].Release();
470 memoryEventFds_[LOW_MEMORY_LEVEL_CRITICAL] = memoryEventFds[LOW_MEMORY_LEVEL_CRITICAL].Release();
471 return true;
472 }
473
InitMemoryPressureFds(UniqueFd memoryPressureFds[LOW_MEMORY_LEVEL_MAX])474 bool CgroupManager::InitMemoryPressureFds(UniqueFd memoryPressureFds[LOW_MEMORY_LEVEL_MAX])
475 {
476 memoryPressureFds[LOW_MEMORY_LEVEL_LOW] = UniqueFd(open(CG_MEM_PRESSURE_LEVEL_PATH.data(), O_RDONLY));
477 memoryPressureFds[LOW_MEMORY_LEVEL_MEDIUM] = UniqueFd(open(CG_MEM_PRESSURE_LEVEL_PATH.data(), O_RDONLY));
478 memoryPressureFds[LOW_MEMORY_LEVEL_CRITICAL] = UniqueFd(open(CG_MEM_PRESSURE_LEVEL_PATH.data(), O_RDONLY));
479 if (memoryPressureFds[LOW_MEMORY_LEVEL_LOW].Get() < 0 || memoryPressureFds[LOW_MEMORY_LEVEL_MEDIUM].Get() < 0 ||
480 memoryPressureFds[LOW_MEMORY_LEVEL_CRITICAL].Get() < 0) {
481 APP_LOGE("%{public}s(${public}d) failed to open memory pressure fd %{public}d.", __func__, __LINE__, errno);
482 return false;
483 }
484
485 memoryPressureFds_[LOW_MEMORY_LEVEL_LOW] = memoryPressureFds[LOW_MEMORY_LEVEL_LOW].Release();
486 memoryPressureFds_[LOW_MEMORY_LEVEL_MEDIUM] = memoryPressureFds[LOW_MEMORY_LEVEL_MEDIUM].Release();
487 memoryPressureFds_[LOW_MEMORY_LEVEL_CRITICAL] = memoryPressureFds[LOW_MEMORY_LEVEL_CRITICAL].Release();
488 return true;
489 }
490
SetCpusetSubsystem(const int tid,const SchedPolicy schedPolicy)491 bool CgroupManager::SetCpusetSubsystem(const int tid, const SchedPolicy schedPolicy)
492 {
493 int fd = cpusetTasksFds_[schedPolicy];
494 if (fd < 0) {
495 APP_LOGE("%{public}s(%{public}d) invalid cpuset fd for policy %{public}d.", __func__, __LINE__, schedPolicy);
496 return false;
497 }
498
499 int ret = WriteValue(fd, tid);
500 if (ret < 0) {
501 APP_LOGE("%{public}s(%{public}d) write cpuset tid failed %{public}d.", __func__, __LINE__, errno);
502 return false;
503 }
504
505 return true;
506 }
507
SetCpuctlSubsystem(const int tid,const SchedPolicy schedPolicy)508 bool CgroupManager::SetCpuctlSubsystem(const int tid, const SchedPolicy schedPolicy)
509 {
510 int fd = cpuctlTasksFds_[schedPolicy];
511 if (fd < 0) {
512 APP_LOGE("%{public}s(%{public}d) invalid cpuctl fd for policy %{public}d.", __func__, __LINE__, schedPolicy);
513 return false;
514 }
515
516 int ret = WriteValue(fd, tid);
517 if (ret < 0) {
518 APP_LOGE("%{public}s(%{public}d) write cpuctl tid failed %{public}d.", __func__, __LINE__, errno);
519 return false;
520 }
521
522 return true;
523 }
524
SetFreezerSubsystem(const int tid,const SchedPolicyFreezer state)525 bool CgroupManager::SetFreezerSubsystem(const int tid, const SchedPolicyFreezer state)
526 {
527 int fd = freezerTasksFds_[state];
528 if (fd < 0) {
529 APP_LOGE("%{public}s(%{public}d) invalid freezer fd for state %{public}d.", __func__, __LINE__, state);
530 return false;
531 }
532
533 int ret = WriteValue(fd, tid);
534 if (ret < 0) {
535 APP_LOGE("%{public}s(%{public}d) write freezer tid failed %{public}d.", __func__, __LINE__, errno);
536 return false;
537 }
538
539 return true;
540 }
541 } // namespace AppExecFwk
542 } // namespace OHOS
543