14d6c458bSopenharmony_ci/*
24d6c458bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License.
54d6c458bSopenharmony_ci * You may obtain a copy of the License at
64d6c458bSopenharmony_ci *
74d6c458bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84d6c458bSopenharmony_ci *
94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and
134d6c458bSopenharmony_ci * limitations under the License.
144d6c458bSopenharmony_ci */
154d6c458bSopenharmony_ci
164d6c458bSopenharmony_ci#include "concurrent_helper.h"
174d6c458bSopenharmony_ci#include "tools/log.h"
184d6c458bSopenharmony_ci
194d6c458bSopenharmony_cinamespace Commonlibrary::Concurrent::Common::Helper {
204d6c458bSopenharmony_ciusing SystemMemoryLevel = ConcurrentHelper::SystemMemoryLevel;
214d6c458bSopenharmony_ci
224d6c458bSopenharmony_cistatic constexpr double LOW_MEMORY_RATIO = 0.2;
234d6c458bSopenharmony_cistatic constexpr double MODERATE_MEMORY_RATIO = 0.5;
244d6c458bSopenharmony_cistatic const char* AVAILABLE_MEM = "MemAvailable:";
254d6c458bSopenharmony_cistatic const char* MEM_INFO = "/proc/meminfo";
264d6c458bSopenharmony_cistatic const char* TOTAL_MEM = "MemTotal:";
274d6c458bSopenharmony_ci
284d6c458bSopenharmony_ci#if defined(OHOS_PLATFORM)
294d6c458bSopenharmony_ciuint64_t ConcurrentHelper::ParseLine(const std::string& line)
304d6c458bSopenharmony_ci{
314d6c458bSopenharmony_ci    std::istringstream iss(line);
324d6c458bSopenharmony_ci    std::string key;
334d6c458bSopenharmony_ci    uint64_t value;
344d6c458bSopenharmony_ci    std::string unit;
354d6c458bSopenharmony_ci    if (iss >> key >> value >> unit) {
364d6c458bSopenharmony_ci        return value;
374d6c458bSopenharmony_ci    }
384d6c458bSopenharmony_ci    return 0;
394d6c458bSopenharmony_ci}
404d6c458bSopenharmony_ci
414d6c458bSopenharmony_cistd::optional<double> ConcurrentHelper::GetSystemMemoryRatio()
424d6c458bSopenharmony_ci{
434d6c458bSopenharmony_ci    uint64_t totalMemory = 0;
444d6c458bSopenharmony_ci    uint64_t availableMemory = 0;
454d6c458bSopenharmony_ci    std::ifstream meminfo(MEM_INFO);
464d6c458bSopenharmony_ci    if (!meminfo.is_open()) {
474d6c458bSopenharmony_ci        HILOG_ERROR("ConcurrentHelper:: Open %{public}s failed", MEM_INFO);
484d6c458bSopenharmony_ci        return std::nullopt;
494d6c458bSopenharmony_ci    }
504d6c458bSopenharmony_ci    std::string line;
514d6c458bSopenharmony_ci    while (std::getline(meminfo, line)) {
524d6c458bSopenharmony_ci        if (line.find(TOTAL_MEM) == 0) {
534d6c458bSopenharmony_ci            totalMemory = ParseLine(line);
544d6c458bSopenharmony_ci        } else if (line.find(AVAILABLE_MEM) == 0) {
554d6c458bSopenharmony_ci            availableMemory = ParseLine(line);
564d6c458bSopenharmony_ci        }
574d6c458bSopenharmony_ci    }
584d6c458bSopenharmony_ci    if (totalMemory == 0) {
594d6c458bSopenharmony_ci        HILOG_ERROR("ConcurrentHelper:: Failed to read the MemTotal.");
604d6c458bSopenharmony_ci        return std::nullopt;
614d6c458bSopenharmony_ci    }
624d6c458bSopenharmony_ci    return static_cast<double>(availableMemory) / static_cast<double>(totalMemory);
634d6c458bSopenharmony_ci}
644d6c458bSopenharmony_ci
654d6c458bSopenharmony_ciSystemMemoryLevel ConcurrentHelper::GetMemoryLevel()
664d6c458bSopenharmony_ci{
674d6c458bSopenharmony_ci    const auto ratio = GetSystemMemoryRatio();
684d6c458bSopenharmony_ci    if (!ratio.has_value()) { // error happens when read memory info, just return the MEMORY_LEVEL_LOW
694d6c458bSopenharmony_ci        return SystemMemoryLevel::MEMORY_LEVEL_LOW;
704d6c458bSopenharmony_ci    }
714d6c458bSopenharmony_ci    if (ratio.value() > MODERATE_MEMORY_RATIO) {
724d6c458bSopenharmony_ci        return SystemMemoryLevel::MEMORY_LEVEL_NORMAL;
734d6c458bSopenharmony_ci    } else if (ratio.value() > LOW_MEMORY_RATIO) {
744d6c458bSopenharmony_ci        return SystemMemoryLevel::MEMORY_LEVEL_MODERATE;
754d6c458bSopenharmony_ci    } else {
764d6c458bSopenharmony_ci        return SystemMemoryLevel::MEMORY_LEVEL_LOW;
774d6c458bSopenharmony_ci    }
784d6c458bSopenharmony_ci}
794d6c458bSopenharmony_ci#endif
804d6c458bSopenharmony_ci
814d6c458bSopenharmony_cibool ConcurrentHelper::IsLowMemory()
824d6c458bSopenharmony_ci{
834d6c458bSopenharmony_ci#if defined(OHOS_PLATFORM)
844d6c458bSopenharmony_ci    return GetMemoryLevel() == SystemMemoryLevel::MEMORY_LEVEL_LOW;
854d6c458bSopenharmony_ci#else
864d6c458bSopenharmony_ci    return false;
874d6c458bSopenharmony_ci#endif
884d6c458bSopenharmony_ci}
894d6c458bSopenharmony_ci
904d6c458bSopenharmony_cibool ConcurrentHelper::IsModerateMemory()
914d6c458bSopenharmony_ci{
924d6c458bSopenharmony_ci#if defined(OHOS_PLATFORM)
934d6c458bSopenharmony_ci    return GetMemoryLevel() == SystemMemoryLevel::MEMORY_LEVEL_MODERATE;
944d6c458bSopenharmony_ci#else
954d6c458bSopenharmony_ci    return false;
964d6c458bSopenharmony_ci#endif
974d6c458bSopenharmony_ci}
984d6c458bSopenharmony_ci} // namespace Commonlibrary::Concurrent::TaskPoolModule