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 <cinttypes>
16 #include <thread>
17 #include "distributed_test_sysinfo.h"
18 #include "distributeddb_data_generator.h"
19 #include "securec.h"
20 
21 const uint64_t PERCENTAGE_FACTOR = 100;
22 const float FLOAT_RET_ERROR = -1.0f;
23 
DistributedTestSysInfo()24 DistributedTestSysInfo::DistributedTestSysInfo()
25 {
26 #if defined(RUNNING_ON_LINUX)
27     if ((memset_s(&memStatFirst_, sizeof(memStatFirst_), 0, sizeof(memStatFirst_)) != EOK) &&
28         (memset_s(&memStatSecond_, sizeof(memStatSecond_), 0, sizeof(memStatSecond_)) != EOK) &&
29         (memset_s(&cpuStatFirst_, sizeof(cpuStatFirst_), 0, sizeof(cpuStatFirst_)) != EOK) &&
30         (memset_s(&cpuStatSecond_, sizeof(cpuStatSecond_), 0, sizeof(cpuStatSecond_)) != EOK)) {
31         MST_LOG("distribute info set 0 failed!");
32     }
33 #elif defined RUNNING_ON_WIN
34 #endif
35     cpuStatFirstUsage_ = 0.0f;
36     cpuStatSecondUsage_ = 0.0f;
37     powerStatFirst_ = 0.0f;
38     powerStatSecond_ = 0.0f;
39     val_ = 0.0f;
40 }
41 
42 #if defined(RUNNING_ON_LINUX)
GetSysMemOccpy(SeqNo seqNo)43 void DistributedTestSysInfo::GetSysMemOccpy(SeqNo seqNo)
44 {
45     MemOccupy* memOccupy = nullptr;
46     if (seqNo == FIRST) {
47         memOccupy = &memStatFirst_;
48     } else {
49         memOccupy = &memStatSecond_;
50     }
51 
52     FILE *fp = nullptr;
53     char buff[PROC_BUFFER_LENGTH] = { 0 };
54 
55     fp = fopen(SYS_MEM_FILE.c_str(), FILE_READ_PERMISSION.c_str());
56     if (fp == nullptr) {
57         perror("fopen:");
58         return;
59     }
60 
61     fgets(buff, sizeof(buff), fp);
62     int result1 = sscanf_s(buff, "%s %llu ",
63         memOccupy->memTotalName_, sizeof(memOccupy->memTotalName_), &memOccupy->memTotal_);
64     fgets(buff, sizeof(buff), fp);
65     int result2 = sscanf_s(buff, "%s %llu ",
66         memOccupy->memFreeName_, sizeof(memOccupy->memFreeName_), &memOccupy->memFree_);
67     fgets(buff, sizeof(buff), fp);
68     int result3 = sscanf_s(buff, "%s %llu ",
69         memOccupy->buffersName_, sizeof(memOccupy->buffersName_), &memOccupy->buffers_);
70     fgets(buff, sizeof(buff), fp);
71     int result4 = sscanf_s(buff, "%s %llu ",
72         memOccupy->cachedName_, sizeof(memOccupy->cachedName_), &memOccupy->cached_);
73     fgets(buff, sizeof(buff), fp);
74     int result5 = sscanf_s(buff, "%s %llu",
75         memOccupy->swapCachedName_, sizeof(memOccupy->swapCachedName_), &memOccupy->swapCached_);
76     if (result1 != 2 || result2 != 2) { // there are 2 incoming param.
77         MST_LOG("get mem1 info failed.");
78     }
79     if (result3 != 2 || result4 != 2 || result5 != 2) { // there are 2 incoming param.
80         MST_LOG("get mem2 info failed.");
81     }
82     MST_LOG(" [MemTotal] = %" PRIu64 " \n [MemFree] = %" PRIu64 " \n [Buffers] = %" PRIu64 " \n [Cached] = %" PRIu64 \
83         " \n [SwapCached] = %" PRIu64, memOccupy->memTotal_, memOccupy->memFree_, memOccupy->buffers_,
84         memOccupy->cached_, memOccupy->swapCached_);
85     fclose(fp);
86     fp = nullptr;
87 }
88 
GetSysCpuInfo(CpuOccupy & cpuStatFirst_,CpuOccupy & cpuStatSecond_,uint64_t microSeconds,float * & cpuStatUsage)89 void GetSysCpuInfo(CpuOccupy &cpuStatFirst_, CpuOccupy &cpuStatSecond_, uint64_t microSeconds, float *&cpuStatUsage)
90 {
91     FILE *fp = nullptr;
92     char buff[PROC_BUFFER_LENGTH] = { 0 };
93     uint64_t allFirst, allSecond, idleFirst, idleSecond;
94     fp = fopen(SYS_CPU_FILE.c_str(), FILE_READ_PERMISSION.c_str());
95     if (fp == nullptr) {
96         perror("fopen:");
97         exit(0);
98     }
99     fgets(buff, sizeof(buff), fp);
100     int result = sscanf_s(buff, "%s %llu %llu %llu %llu %llu %llu %llu",
101         cpuStatFirst_.name_, sizeof(cpuStatFirst_.name_),
102         &cpuStatFirst_.user_, &cpuStatFirst_.nice_,
103         &cpuStatFirst_.system_, &cpuStatFirst_.idle_, &cpuStatFirst_.iowait_,
104         &cpuStatFirst_.irq_, &cpuStatFirst_.softirq_);
105     if (result != 8) { // there are 8 incoming param.
106         fclose(fp);
107         return;
108     }
109     allFirst = cpuStatFirst_.user_ + cpuStatFirst_.nice_ + cpuStatFirst_.system_ + cpuStatFirst_.idle_ +
110         cpuStatFirst_.iowait_ + cpuStatFirst_.irq_ + cpuStatFirst_.softirq_;
111     idleFirst = cpuStatFirst_.idle_;
112     rewind(fp);
113     std::this_thread::sleep_for(std::chrono::microseconds(microSeconds));
114     if (memset_s(buff, sizeof(buff), 0, sizeof(buff)) != EOK) {
115         MST_LOG("set buffer to 0 failed!");
116         fclose(fp);
117         return;
118     }
119     fgets(buff, sizeof(buff), fp);
120     result = sscanf_s(buff, "%s %llu %llu %llu %llu %llu %llu %llu",
121         cpuStatSecond_.name_, sizeof(cpuStatSecond_.name_),
122         &cpuStatSecond_.user_, &cpuStatSecond_.nice_,
123         &cpuStatSecond_.system_, &cpuStatSecond_.idle_, &cpuStatSecond_.iowait_,
124         &cpuStatSecond_.irq_, &cpuStatSecond_.softirq_);
125     if (result < 0) {
126         fclose(fp);
127         return;
128     }
129 
130     allSecond = cpuStatSecond_.user_ + cpuStatSecond_.nice_ + cpuStatSecond_.system_ + cpuStatSecond_.idle_ +
131         cpuStatSecond_.iowait_ + cpuStatSecond_.irq_ + cpuStatSecond_.softirq_;
132     idleSecond = cpuStatSecond_.idle_;
133     *cpuStatUsage = (static_cast<float>(allSecond - allFirst - (idleSecond - idleFirst)))
134         / (allSecond - allFirst) * PERCENTAGE_FACTOR;
135     MST_LOG(" [CpuUsage] = %.2f%%", *cpuStatUsage);
136     fclose(fp);
137     fp = nullptr;
138     return;
139 }
GetSysCpuUsage(SeqNo seqNo,uint64_t microSeconds)140 void DistributedTestSysInfo::GetSysCpuUsage(SeqNo seqNo, uint64_t microSeconds)
141 {
142     float *cpuStatUsage = nullptr;
143     if (seqNo == FIRST) {
144         cpuStatUsage = &cpuStatFirstUsage_;
145     } else {
146         cpuStatUsage = &cpuStatSecondUsage_;
147     }
148     GetSysCpuInfo(cpuStatFirst_, cpuStatSecond_, microSeconds, cpuStatUsage);
149     if ((memset_s(&cpuStatFirst_, sizeof(cpuStatFirst_), 0, sizeof(cpuStatFirst_)) != EOK) &&
150         (memset_s(&cpuStatSecond_, sizeof(cpuStatSecond_), 0, sizeof(cpuStatSecond_)) != EOK)) {
151         MST_LOG("set cpu to 0 failed!");
152     }
153 }
154 
ReadSysValFromFile(const std::string & filePath)155 float DistributedTestSysInfo::ReadSysValFromFile(const std::string &filePath)
156 {
157     FILE *fp = nullptr;
158     char buff[SYSTEM_INFO_BUFFER_SIZE] = { 0 };
159 
160     char path[PATH_MAX] = { 0 };
161     if (realpath(filePath.c_str(), path) == nullptr) {
162         MST_LOG("path error.");
163         return FLOAT_RET_ERROR;
164     }
165 
166     fp = fopen(filePath.c_str(), FILE_READ_PERMISSION.c_str());
167     if (fp == nullptr) {
168         perror("fopen:");
169         return FLOAT_RET_ERROR;
170     }
171 
172     fgets(buff, sizeof(buff), fp);
173     if (sscanf_s(buff, "%f", &val_) != 1) {
174         fclose(fp);
175         return FLOAT_RET_ERROR;
176     }
177     fclose(fp);
178     return val_;
179 }
180 
GetSysMeanCurrentVal(const std::string & filePath,int totalCount,uint64_t microSeconds)181 float DistributedTestSysInfo::GetSysMeanCurrentVal(
182     const std::string &filePath, int totalCount, uint64_t microSeconds)
183 {
184     float meanVal = 0.0f;
185     if (totalCount <= 0 || microSeconds <= 0) {
186         return 0.0f;
187     }
188 
189     for (int cnt = 0; cnt < totalCount; cnt++) {
190         float val = ReadSysValFromFile(filePath.c_str());
191         if (val < 1e-4) {
192             continue;
193         }
194         meanVal += val;
195         std::this_thread::sleep_for(std::chrono::microseconds(microSeconds));
196     }
197     return meanVal / totalCount;
198 }
199 
GetSysCurrentPower(SeqNo seqNo,int totalCount,uint64_t microSeconds)200 void DistributedTestSysInfo::GetSysCurrentPower(SeqNo seqNo, int totalCount, uint64_t microSeconds)
201 {
202     float* powerCons = nullptr;
203     if (seqNo == FIRST) {
204         powerCons = &powerStatFirst_;
205     } else {
206         powerCons = &powerStatSecond_;
207     }
208 
209     *powerCons = GetSysMeanCurrentVal(POWER_FOLLOW_FILE, totalCount, microSeconds) \
210         * GetSysMeanCurrentVal(VOLTAGE_FILE, totalCount, microSeconds);
211     MST_LOG(" [Power] = %.2f", *powerCons);
212 }
213 
GetFirstMemFree() const214 uint64_t DistributedTestSysInfo::GetFirstMemFree() const
215 {
216     return memStatFirst_.memFree_;
217 }
218 
GetSecondMemFree() const219 uint64_t DistributedTestSysInfo::GetSecondMemFree() const
220 {
221     return memStatSecond_.memFree_;
222 }
223 
224 #elif defined RUNNING_ON_WIN
GetSysMemOccpy(SeqNo seqNo)225 void DistributedTestSysInfo::GetSysMemOccpy(SeqNo seqNo)
226 {
227     (void)seqNo;
228 }
229 
GetSysCpuUsage(SeqNo seqNo,uint64_t microSeconds)230 void DistributedTestSysInfo::GetSysCpuUsage(SeqNo seqNo, uint64_t microSeconds)
231 {
232     (void)seqNo;
233     (void)microSeconds;
234 }
235 
ReadSysValFromFile(const std::string & filePath)236 float DistributedTestSysInfo::ReadSysValFromFile(const std::string &filePath)
237 {
238     (void)filePath;
239     return 0.0f;
240 }
241 
GetSysMeanCurrentVal(const std::string & filePath,int totalCount,uint64_t microSeconds)242 float DistributedTestSysInfo::GetSysMeanCurrentVal(
243     const std::string &filePath, int totalCount, uint64_t microSeconds)
244 {
245     (void)filePath;
246     (void)totalCount;
247     (void)microSeconds;
248     return 0.0f;
249 }
GetSysCurrentPower(SeqNo seqNo,int totalCount,uint64_t microSeconds)250 void DistributedTestSysInfo::GetSysCurrentPower(SeqNo seqNo, int totalCount, uint64_t microSeconds)
251 {
252     (void)seqNo;
253     (void)totalCount;
254     (void)microSeconds;
255 }
256 
GetFirstMemFree() const257 uint64_t DistributedTestSysInfo::GetFirstMemFree() const
258 {
259     return 0;
260 }
261 
GetSecondMemFree() const262 uint64_t DistributedTestSysInfo::GetSecondMemFree() const
263 {
264     return 0;
265 }
266 #endif
267 
GetFirstCpuUsage() const268 float DistributedTestSysInfo::GetFirstCpuUsage() const
269 {
270     return cpuStatFirstUsage_;
271 }
272 
GetSecondCpuUsage() const273 float DistributedTestSysInfo::GetSecondCpuUsage() const
274 {
275     return cpuStatSecondUsage_;
276 }
277 
GetFirstPower() const278 float DistributedTestSysInfo::GetFirstPower() const
279 {
280     return powerStatFirst_;
281 }
282 
GetSecondPower() const283 float DistributedTestSysInfo::GetSecondPower() const
284 {
285     return powerStatSecond_;
286 }
287 
288 #if defined(RUNNING_ON_LINUX)
SaveSecondToFirst()289 void DistributedTestSysInfo::SaveSecondToFirst()
290 {
291     if ((memcpy_s(&memStatFirst_, sizeof(memStatFirst_), &memStatSecond_, sizeof(struct MemOccupy)) != EOK) &&
292         memcpy_s(&cpuStatFirst_, sizeof(cpuStatFirst_), &cpuStatSecond_, sizeof(struct CpuOccupy)) != EOK) {
293         MST_LOG("set mem or cpu state failed.");
294     }
295     cpuStatFirstUsage_ = cpuStatSecondUsage_;
296     powerStatFirst_ = powerStatSecond_;
297 }
298 #elif defined RUNNING_ON_WIN
SaveSecondToFirst()299 void DistributedTestSysInfo::SaveSecondToFirst()
300 {
301 }
302 #endif
303