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

Commit 887f355f authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Propagate background scheduling class across processes.

This is a very simply implementation: upon receiving an IPC, if the handling
thread is at a background priority (the driver will have taken care of
propagating this from the calling thread), then stick it in to the background
scheduling group.  Plus an API to turn this off for the process, which is
used by the system process.

This also pulls some of the code for managing scheduling classes out of
the Process JNI wrappers and in to some convenience methods in thread.h.
parent 259e3384
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -76,6 +76,13 @@ public class BinderInternal {
     */
    public static final native IBinder getContextObject();
    
    /**
     * Special for system process to not allow incoming calls to run at
     * background scheduling priority.
     * @hide
     */
    public static final native void disableBackgroundScheduling(boolean disable);
    
    static native final void handleGc();
    
    public static void forceGc(String reason) {
+7 −0
Original line number Diff line number Diff line
@@ -670,6 +670,12 @@ static void android_os_BinderInternal_joinThreadPool(JNIEnv* env, jobject clazz)
    android::IPCThreadState::self()->joinThreadPool();
}

static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
        jobject clazz, jboolean disable)
{
    IPCThreadState::disableBackgroundScheduling(disable ? true : false);
}

static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
{
    LOGV("Gc has executed, clearing binder ops");
@@ -682,6 +688,7 @@ static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};

+12 −27
Original line number Diff line number Diff line
@@ -120,11 +120,7 @@ jint android_os_Process_myUid(JNIEnv* env, jobject clazz)

jint android_os_Process_myTid(JNIEnv* env, jobject clazz)
{
#ifdef HAVE_GETTID
    return gettid();
#else
    return getpid();
#endif
    return androidGetTid();
}

jint android_os_Process_getUidForName(JNIEnv* env, jobject clazz, jstring name)
@@ -191,15 +187,11 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name)

void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
{
    if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
        signalExceptionForGroupError(env, clazz, EINVAL);
    int res = androidSetThreadSchedulingGroup(pid, grp);
    if (res != NO_ERROR) {
        signalExceptionForGroupError(env, clazz, res == BAD_VALUE ? EINVAL : errno);
        return;
    }

    if (set_sched_policy(pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
                                      SP_BACKGROUND : SP_FOREGROUND)) {
        signalExceptionForGroupError(env, clazz, errno);
    }
}

void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp) 
@@ -275,22 +267,15 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
                                              jint pid, jint pri)
{
    int rc = 0;

    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
        rc = set_sched_policy(pid, SP_BACKGROUND);
    } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
        rc = set_sched_policy(pid, SP_FOREGROUND);
    }

    if (rc) {
    int rc = androidSetThreadPriority(pid, pri);
    if (rc != 0) {
        if (rc == INVALID_OPERATION) {
            signalExceptionForPriorityError(env, clazz, errno);
        } else {
            signalExceptionForGroupError(env, clazz, errno);
        return;
        }

    if (setpriority(PRIO_PROCESS, pid, pri) < 0) {
        signalExceptionForPriorityError(env, clazz, errno);
    }
    
    //LOGI("Setting priority of %d: %d, getpriority returns %d\n",
    //     pid, pri, getpriority(PRIO_PROCESS, pid));
}
+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ public:
        DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),
        INTERFACE_TRANSACTION   = B_PACK_CHARS('_', 'N', 'T', 'F'),

        // Corresponds to tfOneWay -- an asynchronous call.
        // Corresponds to TF_ONE_WAY -- an asynchronous call.
        FLAG_ONEWAY             = 0x00000001
    };

+9 −1
Original line number Diff line number Diff line
@@ -68,6 +68,13 @@ public:

    static  void                shutdown();
    
    // Call this to disable switching threads to background scheduling when
    // receiving incoming IPC calls.  This is specifically here for the
    // Android system process, since it expects to have background apps calling
    // in to it but doesn't want to acquire locks in its services while in
    // the background.
    static  void                disableBackgroundScheduling(bool disable);
    
private:
                                IPCThreadState();
                                ~IPCThreadState();
@@ -93,6 +100,7 @@ private:
                                           void* cookie);
    
    const   sp<ProcessState>    mProcess;
    const   pid_t               mMyThreadId;
            Vector<BBinder*>    mPendingStrongDerefs;
            Vector<RefBase::weakref_type*> mPendingWeakDerefs;
            
Loading