Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31faf3f1 authored by Tim Murray's avatar Tim Murray
Browse files

Compact system processes.

Compact system processes soon after boot and during idle maintenance. This
will help keep the pagecache in a more consistent state.

Test: boots, works
bug 119988524

Change-Id: I7207d6ba3a2047278b767718dbc532e06f5516fd
parent bf3f369e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -5121,6 +5121,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                                String data, Bundle extras, boolean ordered,
                                boolean sticky, int sendingUser) {
                            synchronized (ActivityManagerService.this) {
                                mOomAdjuster.mAppCompact.compactAllSystem();
                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
                            }
                        }
@@ -8614,6 +8615,10 @@ public class ActivityManagerService extends IActivityManager.Stub
        synchronized (this) {
            final long now = SystemClock.uptimeMillis();
            final long timeSinceLastIdle = now - mLastIdleTime;
            // Compact all non-zygote processes to freshen up the page cache.
            mOomAdjuster.mAppCompact.compactAllSystem();
            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
            mLastIdleTime = now;
            mLowRamTimeSinceLastIdle = 0;
+18 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ public final class AppCompactor {
    static final int COMPACT_PROCESS_PERSISTENT = 3;
    static final int COMPACT_PROCESS_BFGS = 4;
    static final int COMPACT_PROCESS_MSG = 1;
    static final int COMPACT_SYSTEM_MSG = 2;

    /**
     * This thread must be moved to the system background cpuset.
@@ -264,6 +265,16 @@ public final class AppCompactor {
                || (now - app.lastCompactTime) > mCompactThrottleBFGS);
    }

    @GuardedBy("mAm")
    void compactAllSystem() {
        if (mUseCompaction) {
            mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage(
                                              COMPACT_SYSTEM_MSG));
        }
    }

    private native void compactSystem();

    /**
     * Reads the flag value from DeviceConfig to determine whether app compaction
     * should be enabled, and starts/stops the compaction thread as needed.
@@ -497,6 +508,13 @@ public final class AppCompactor {
                        // nothing to do, presumably the process died
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    }
                    break;
                }
                case COMPACT_SYSTEM_MSG: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactSystem");
                    compactSystem();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                }
            }
        }
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ cc_library_static {
        "com_android_server_VibratorService.cpp",
        "com_android_server_PersistentDataBlockService.cpp",
        "com_android_server_GraphicsStatsService.cpp",
        "com_android_server_am_AppCompactor.cpp",
        "onload.cpp",
    ],

+88 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "AppCompactor"
//#define LOG_NDEBUG 0

#include <dirent.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <android-base/stringprintf.h>
#include <android-base/file.h>

#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include <jni.h>

using android::base::StringPrintf;
using android::base::WriteStringToFile;

namespace android {

// This performs per-process reclaim on all processes belonging to non-app UIDs.
// For the most part, these are non-zygote processes like Treble HALs, but it
// also includes zygote-derived processes that run in system UIDs, like bluetooth
// or potentially some mainline modules. The only process that should definitely
// not be compacted is system_server, since compacting system_server around the
// time of BOOT_COMPLETE could result in perceptible issues.
static void com_android_server_am_AppCompactor_compactSystem(JNIEnv *, jobject) {
    std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir);
    struct dirent* current;
    while ((current = readdir(proc.get()))) {
        if (current->d_type != DT_DIR) {
            continue;
        }

        // don't compact system_server, rely on persistent compaction during screen off
        // in order to avoid mmap_sem-related stalls
        if (atoi(current->d_name) == getpid()) {
            continue;
        }

        std::string status_name = StringPrintf("/proc/%s/status", current->d_name);
        struct stat status_info;

        if (stat(status_name.c_str(), &status_info) != 0) {
            // must be some other directory that isn't a pid
            continue;
        }

        // android.os.Process.FIRST_APPLICATION_UID
        if (status_info.st_uid >= 10000) {
            continue;
        }

        std::string reclaim_path = StringPrintf("/proc/%s/reclaim", current->d_name);
        WriteStringToFile(std::string("all"), reclaim_path);
    }
}

static const JNINativeMethod sMethods[] = {
    /* name, signature, funcPtr */
    {"compactSystem", "()V", (void*)com_android_server_am_AppCompactor_compactSystem},
};

int register_android_server_am_AppCompactor(JNIEnv* env)
{
    return jniRegisterNativeMethods(env, "com/android/server/am/AppCompactor",
                                    sMethods, NELEM(sMethods));
}

}
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ int register_android_server_GraphicsStatsService(JNIEnv* env);
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
int register_android_server_net_NetworkStatsService(JNIEnv* env);
int register_android_server_security_VerityUtils(JNIEnv* env);
int register_android_server_am_AppCompactor(JNIEnv* env);
};

using namespace android;
@@ -101,5 +102,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
    register_android_hardware_display_DisplayViewport(env);
    register_android_server_net_NetworkStatsService(env);
    register_android_server_security_VerityUtils(env);
    register_android_server_am_AppCompactor(env);
    return JNI_VERSION_1_4;
}