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 "policy/memory_policy.h"
16 
17 #include <fstream>
18 #include <securec.h>
19 #include "work_sched_hilog.h"
20 
21 using namespace std;
22 
23 namespace OHOS {
24 namespace WorkScheduler {
25 const int32_t BUF_LIMIT = 128;
26 const int32_t NAME_SIZE = 128;
27 const int32_t INVALID_MEM = -1;
28 const int32_t MEM_CRUCIAL = 1 * 1024 * 1024;
29 const int32_t MEM_LOW = 2 * 1024 * 1024;
30 const int32_t COUNT_MEMORY_CRUCIAL = 1;
31 const int32_t COUNT_MEMORY_LOW = 2;
32 const int32_t COUNT_MEMORY_NORMAL = 3;
33 
MemoryPolicy(shared_ptr<WorkPolicyManager> workPolicyManager)34 MemoryPolicy::MemoryPolicy(shared_ptr<WorkPolicyManager> workPolicyManager)
35 {
36     workPolicyManager_ = workPolicyManager;
37 }
38 
~MemoryPolicy()39 MemoryPolicy::~MemoryPolicy()
40 {
41 }
42 
GetMemAvailable()43 int32_t MemoryPolicy::GetMemAvailable()
44 {
45     if (workPolicyManager_ != nullptr) {
46         int32_t dumpSetMemory = workPolicyManager_->GetDumpSetMemory();
47         if (dumpSetMemory != -1) {
48             WS_HILOGD("dump set memory:%{public}d", dumpSetMemory);
49             return dumpSetMemory;
50         }
51     }
52     int32_t memAvailable = INVALID_MEM;
53     FILE *fp = fopen("/proc/meminfo", "r");
54     if (fp == nullptr) {
55         WS_HILOGE("GetMemAvailable file open failed.");
56         return memAvailable;
57     }
58     char buf[BUF_LIMIT];
59     int32_t buff_len = BUF_LIMIT;
60     const char mem_name[] = "MemAvailable";
61     char name[NAME_SIZE];
62     int32_t value = -1;
63     while (fgets(buf, buff_len, fp) != nullptr) {
64         int32_t res = sscanf_s(buf, "%s%d", name, sizeof(name), &value);
65         if (res < 0) {
66             WS_HILOGE("sscanf_s failed");
67             break;
68         }
69         string sname = name;
70         if (sname.find(mem_name) != string::npos) {
71             memAvailable = value;
72             break;
73         }
74     }
75     fclose(fp);
76     fp = nullptr;
77     return memAvailable;
78 }
79 
GetPolicyMaxRunning()80 int32_t MemoryPolicy::GetPolicyMaxRunning()
81 {
82     int32_t memAvailable = GetMemAvailable();
83     WS_HILOGD("mem_available: %{public}d", memAvailable);
84     if (memAvailable <= MEM_CRUCIAL) {
85         return COUNT_MEMORY_CRUCIAL;
86     }
87     if (memAvailable <= MEM_LOW) {
88         return COUNT_MEMORY_LOW;
89     }
90     WS_HILOGD("memory left normal");
91     return COUNT_MEMORY_NORMAL;
92 }
93 
GetPolicyName()94 std::string MemoryPolicy::GetPolicyName()
95 {
96     return "MEMORY_POLICY";
97 }
98 } // namespace WorkScheduler
99 } // namespace OHOS