1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.am; 18 19 import com.android.internal.annotations.GuardedBy; 20 21 /** 22 * Detects low memory using PSI. 23 * 24 * If the kernel doesn't support PSI, then this class is not available. 25 */ 26 public final class LowMemDetector { 27 private static final String TAG = "LowMemDetector"; 28 private final ActivityManagerService mAm; 29 private final LowMemThread mLowMemThread; 30 private boolean mAvailable; 31 32 private final Object mPressureStateLock = new Object(); 33 34 @GuardedBy("mPressureStateLock") 35 private int mPressureState = MEM_PRESSURE_NONE; 36 37 /* getPressureState return values */ 38 public static final int MEM_PRESSURE_NONE = 0; 39 public static final int MEM_PRESSURE_LOW = 1; 40 public static final int MEM_PRESSURE_MEDIUM = 2; 41 public static final int MEM_PRESSURE_HIGH = 3; 42 LowMemDetector(ActivityManagerService am)43 LowMemDetector(ActivityManagerService am) { 44 mAm = am; 45 mLowMemThread = new LowMemThread(); 46 if (init() != 0) { 47 mAvailable = false; 48 } else { 49 mAvailable = true; 50 mLowMemThread.start(); 51 } 52 } 53 isAvailable()54 public boolean isAvailable() { 55 return mAvailable; 56 } 57 58 /** 59 * Returns the current mem factor. 60 * Note that getMemFactor returns LowMemDetector.MEM_PRESSURE_XXX 61 * which match ProcessStats.ADJ_MEM_FACTOR_XXX values. If they deviate 62 * there should be conversion performed here to translate pressure state 63 * into memFactor. 64 */ getMemFactor()65 public int getMemFactor() { 66 synchronized (mPressureStateLock) { 67 return mPressureState; 68 } 69 } 70 init()71 private native int init(); waitForPressure()72 private native int waitForPressure(); 73 74 private final class LowMemThread extends Thread { run()75 public void run() { 76 77 while (true) { 78 // sleep waiting for a PSI event 79 int newPressureState = waitForPressure(); 80 if (newPressureState == -1) { 81 // epoll broke, tear this down 82 mAvailable = false; 83 break; 84 } 85 // got a PSI event? let's update lowmem info 86 synchronized (mPressureStateLock) { 87 mPressureState = newPressureState; 88 } 89 } 90 } 91 } 92 } 93