Modify CPUBoostingController
[platform/core/appfw/launchpad.git] / src / lib / launchpad-common / procfs.cc
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "launchpad-common/procfs.hh"
18
19 #include <unistd.h>
20
21 #include <cstdint>
22 #include <filesystem>
23 #include <fstream>
24 #include <iomanip>
25 #include <iostream>
26 #include <sstream>
27 #include <string>
28
29 #include "launchpad-common/log_private.hh"
30
31 namespace launchpad {
32
33 void Procfs::GetMemoryUsage(uint32_t* usage) {
34   if (usage == nullptr) {
35     _E("Invalid argument");
36     return;
37   }
38
39   uint64_t mem_total = 0;
40   uint64_t mem_free = 0;
41   uint64_t mem_available = 0;
42   uint64_t mem_cached = 0;
43
44   std::ifstream stream("/proc/meminfo");
45   std::string line;
46   while (getline(stream, line)) {
47     std::istringstream iss(line);
48     std::string key;
49     uint64_t value;
50
51     if (iss >> key >> value) {
52       if (key == "MemTotal:")
53         mem_total = value;
54       else if (key == "MemAvailable:")
55         mem_available = value;
56       else if (key == "MemFree:")
57         mem_free = value;
58       else if (key == "Cached:")
59         mem_cached = value;
60     }
61   }
62
63   if (mem_total == 0) {
64     _E("Failed to get total memory size");
65     return;
66   }
67
68   if (mem_available == 0)
69     mem_available = mem_free + mem_cached;
70
71   *usage = (mem_total - mem_available) * 100 / mem_total;
72 }
73
74 void Procfs::GetPssMemory(pid_t pid, uint64_t* mem_pss) {
75   if (pid < 1 || mem_pss == nullptr) {
76     _E("Invalid parameter");
77     return;
78   }
79
80   std::filesystem::path smaps_path = "/proc/" + std::to_string(pid) + "/smaps";
81   if (!std::filesystem::exists(smaps_path)) {
82     _E("%s does not exist", smaps_path.c_str());
83     return;
84   }
85
86   std::ifstream file(smaps_path);
87   if (!file) {
88     _E("Failed to open %s", smaps_path.c_str());
89     return;
90   }
91
92   uint64_t total_pss = 0;
93   std::string line;
94   while (std::getline(file, line)) {
95     std::stringstream stream(line);
96     std::string pss_str;
97     if (stream >> pss_str && pss_str == "Pss:") {
98       uint64_t pss = 0;
99       if (stream >> pss) {
100         total_pss += pss;
101       }
102     }
103   }
104
105   *mem_pss = total_pss;
106 }
107
108 std::string Procfs::GetAttrCurrent(pid_t pid) {
109   const std::string path = "/proc/" + std::to_string(pid) + "/attr/current";
110   std::ifstream file(path);
111   if (!file.is_open()) {
112     _E("%s is not opened", path.c_str());
113     return {};
114   }
115
116   std::stringstream buffer;
117   buffer << file.rdbuf();
118   file.close();
119
120   const std::string result = buffer.str();
121   if (result.empty()) {
122     _E("file is empty");
123     return {};
124   }
125
126   return result;
127 }
128
129 void Procfs::SetComm(pid_t pid, const std::string& comm) {
130   const std::string path = "/proc/" + std::to_string(pid) + "/comm";
131   std::ofstream comm_file;
132   comm_file.open(path);
133   if (!comm_file.is_open()) {
134     _E("Failed to open %s", path.c_str());
135     return;
136   }
137
138   comm_file << comm;
139   comm_file.close();
140 }
141
142 }  // namespace launchpad