1 /*
2 * Copyright (c) 2024 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
16 #include "res_sched_system_util.h"
17
18 #include <sys/statvfs.h>
19 #include <sys/sysinfo.h>
20
21 #include "res_sched_log.h"
22 #include "res_sched_string_util.h"
23 #include "parameters.h"
24
25 namespace OHOS {
26 namespace ResourceSchedule {
27 namespace ResCommonUtil {
28 namespace {
29 constexpr int64_t BYTES_PER_GB = 1024 * 1024 * 1024;
30 constexpr int64_t BYTES_PER_KB = 1024;
31 constexpr int64_t BYTES_PER_MB = 1024 * 1024;
32 const std::string PATH_DATA = "/data";
33 const std::string PATH_ROOT = "/";
34 }
35
GetTotalRamSize(const std::string & ddrSysProp)36 int64_t GetTotalRamSize(const std::string& ddrSysProp)
37 {
38 int64_t totalRamSize = 0;
39 // attempt obtain ram size for system prop
40 if (!ddrSysProp.empty()) {
41 std::string ddrString = GetSystemProperties(ddrSysProp, "");
42 if (StrToInt64(ddrString, totalRamSize)) {
43 totalRamSize *= BYTES_PER_KB;
44 return totalRamSize;
45 }
46 }
47 // not give sys prop or get info from sys info failed, obtain through system call
48 struct sysinfo info;
49 if (sysinfo(&info) != 0) {
50 RESSCHED_LOGE("%{public}s error", __func__);
51 return totalRamSize;
52 }
53 auto totalSizeBytes = static_cast<int64_t>(info.totalram);
54 // convert byte to MB
55 totalRamSize = ceil(totalSizeBytes / BYTES_PER_GB) * BYTES_PER_KB;
56 return totalRamSize;
57 }
58
GetTotalSizeByStatvfs(const std::string & path,int64_t & size)59 inline bool GetTotalSizeByStatvfs(const std::string& path, int64_t& size)
60 {
61 struct statvfs diskInfo;
62 int res = statvfs(path.c_str(), &diskInfo);
63 if (res != 0) {
64 RESSCHED_LOGE("%{public}s get disk info failed", __func__);
65 return false;
66 }
67 size = static_cast<int64_t>(diskInfo.f_bsize) * static_cast<int64_t>(diskInfo.f_blocks);
68 return true;
69 }
70
RoundStorageSize(const int64_t & size)71 int64_t RoundStorageSize(const int64_t& size)
72 {
73 // check input size is vaild
74 if (size < 0) {
75 return size;
76 }
77 uint64_t uSize = static_cast<uint64_t>(size);
78 uint16_t value = 1;
79 uint32_t unit = 1;
80 // value indicate size of unit, when this value of size less than input size
81 while ((value * unit) < uSize) {
82 value <<= 1;
83 if (value >= BYTES_PER_KB) {
84 value = 1;
85 unit *= BYTES_PER_KB;
86 }
87 }
88 return static_cast<int64_t>(value * unit);
89 }
90
GetTotalRomSize()91 int64_t GetTotalRomSize()
92 {
93 int64_t totalRomSize = 0;
94 int64_t dataRomSize = 0;
95 // get /data path's total rom
96 if (!GetTotalSizeByStatvfs(PATH_DATA, dataRomSize)) {
97 RESSCHED_LOGE("%{public}s: get data size error", __func__);
98 return totalRomSize;
99 }
100 // get / path's tatoal rom
101 int64_t rootRomSize = 0;
102 if (!GetTotalSizeByStatvfs(PATH_ROOT, rootRomSize)) {
103 RESSCHED_LOGE("%{public}s: get root size error", __func__);
104 return totalRomSize;
105 }
106 int64_t totalSizeBytes = dataRomSize + rootRomSize;
107 // round up total rom size
108 totalRomSize = RoundStorageSize(totalSizeBytes / BYTES_PER_MB);
109 return totalRomSize;
110 }
111
GetSystemProperties(const std::string & name,const std::string & defaultValue)112 std::string GetSystemProperties(const std::string& name, const std::string &defaultValue)
113 {
114 return system::GetParameter(name, defaultValue);
115 }
116 }
117 } // namespace ResourceSchedule
118 } // namespace OHOS
119