1c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen/*
2c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * Copyright (C) 2016 The Android Open Source Project
3c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen *
4c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
5c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * you may not use this file except in compliance with the License.
6c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * You may obtain a copy of the License at
7c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen *
8c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
9c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen *
10c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * Unless required by applicable law or agreed to in writing, software
11c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
12c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * See the License for the specific language governing permissions and
14c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen * limitations under the License.
15c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen */
16c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
17c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen#define LOG_TAG "MediaUtils"
18c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen#define LOG_NDEBUG 0
19c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen#include <utils/Log.h>
20c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
21c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen#include <cutils/properties.h>
22c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen#include <sys/resource.h>
23c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen#include <unistd.h>
24c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
25c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen#include "MediaUtils.h"
26c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
27c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissennamespace android {
28c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
29c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissenvoid limitProcessMemory(
30c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    const char *property,
31c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    size_t numberOfBytes,
32c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    size_t percentageOfTotalMem) {
33c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
34c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    long pageSize = sysconf(_SC_PAGESIZE);
35c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    long numPages = sysconf(_SC_PHYS_PAGES);
36c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    size_t maxMem = SIZE_MAX;
37c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
38c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    if (pageSize > 0 && numPages > 0) {
39c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        if (size_t(numPages) < SIZE_MAX / size_t(pageSize)) {
40c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen            maxMem = size_t(numPages) * size_t(pageSize);
41c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        }
42c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        ALOGV("physMem: %zu", maxMem);
43c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        if (percentageOfTotalMem > 100) {
44c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen            ALOGW("requested %zu%% of total memory, using 100%%", percentageOfTotalMem);
45c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen            percentageOfTotalMem = 100;
46c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        }
47c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        maxMem = maxMem / 100 * percentageOfTotalMem;
48c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        if (numberOfBytes < maxMem) {
49c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen            maxMem = numberOfBytes;
50c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        }
51c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        ALOGV("requested limit: %zu", maxMem);
52c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    } else {
53c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        ALOGW("couldn't determine total RAM");
54c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    }
55c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
56c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    int64_t propVal = property_get_int64(property, maxMem);
57c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    if (propVal > 0 && uint64_t(propVal) <= SIZE_MAX) {
58c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen        maxMem = propVal;
59c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    }
60c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    ALOGV("actual limit: %zu", maxMem);
61c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
62c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    struct rlimit limit;
63c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    getrlimit(RLIMIT_AS, &limit);
64c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    ALOGV("original limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max);
65c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    limit.rlim_cur = maxMem;
66c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    setrlimit(RLIMIT_AS, &limit);
67c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    limit.rlim_cur = -1;
68c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    limit.rlim_max = -1;
69c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    getrlimit(RLIMIT_AS, &limit);
70c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen    ALOGV("new limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max);
71c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
72c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen}
73c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen
74c57fe21ebdd6813c5a8954f3fda51b82d26acd07Marco Nelissen} // namespace android
75