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

Commit 4a5ba7dd authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change I887f355f into eclair-mr2

* changes:
  Propagate background scheduling class across processes.
parents b098b6df 8c6cedc9
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -52,7 +52,7 @@ public:
        DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),
        DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),
        INTERFACE_TRANSACTION   = B_PACK_CHARS('_', 'N', 'T', 'F'),
        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
        FLAG_ONEWAY             = 0x00000001
    };
    };


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


    static  void                shutdown();
    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:
private:
                                IPCThreadState();
                                IPCThreadState();
                                ~IPCThreadState();
                                ~IPCThreadState();
@@ -93,6 +100,7 @@ private:
                                           void* cookie);
                                           void* cookie);
    
    
    const   sp<ProcessState>    mProcess;
    const   sp<ProcessState>    mProcess;
    const   pid_t               mMyThreadId;
            Vector<BBinder*>    mPendingStrongDerefs;
            Vector<BBinder*>    mPendingStrongDerefs;
            Vector<RefBase::weakref_type*> mPendingWeakDerefs;
            Vector<RefBase::weakref_type*> mPendingWeakDerefs;
            
            
+18 −0
Original line number Original line Diff line number Diff line
@@ -124,6 +124,24 @@ typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,


extern void androidSetCreateThreadFunc(android_create_thread_fn func);
extern void androidSetCreateThreadFunc(android_create_thread_fn func);


// ------------------------------------------------------------------
// Extra functions working with raw pids.

// Get pid for the current thread.
extern pid_t androidGetTid();

// Change the scheduling group of a particular thread.  The group
// should be one of the ANDROID_TGROUP constants.  Returns BAD_VALUE if
// grp is out of range, else another non-zero value with errno set if
// the operation failed.
extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);

// Change the priority AND scheduling group of a particular thread.  The priority
// should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION
// if the priority set failed, else another value if just the group set failed;
// in either case errno is set.
extern int androidSetThreadPriority(pid_t tid, int prio);

#ifdef __cplusplus
#ifdef __cplusplus
}
}
#endif
#endif
+38 −15
Original line number Original line Diff line number Diff line
@@ -292,6 +292,7 @@ static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
static bool gHaveTLS = false;
static bool gHaveTLS = false;
static pthread_key_t gTLS = 0;
static pthread_key_t gTLS = 0;
static bool gShutdown = false;
static bool gShutdown = false;
static bool gDisableBackgroundScheduling = false;


IPCThreadState* IPCThreadState::self()
IPCThreadState* IPCThreadState::self()
{
{
@@ -332,6 +333,11 @@ void IPCThreadState::shutdown()
    }
    }
}
}


void IPCThreadState::disableBackgroundScheduling(bool disable)
{
    gDisableBackgroundScheduling = disable;
}

sp<ProcessState> IPCThreadState::process()
sp<ProcessState> IPCThreadState::process()
{
{
    return mProcess;
    return mProcess;
@@ -386,6 +392,11 @@ void IPCThreadState::joinThreadPool(bool isMain)


    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
    
    
    // This thread may have been spawned by a thread that was in the background
    // scheduling group, so first we will make sure it is in the default/foreground
    // one to avoid performing an initial transaction in the background.
    androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
        
    status_t result;
    status_t result;
    do {
    do {
        int32_t cmd;
        int32_t cmd;
@@ -427,19 +438,13 @@ void IPCThreadState::joinThreadPool(bool isMain)
        }
        }
        
        
        // After executing the command, ensure that the thread is returned to the
        // After executing the command, ensure that the thread is returned to the
        // default cgroup and priority before rejoining the pool.  This is a failsafe
        // default cgroup before rejoining the pool.  The driver takes care of
        // in case the command implementation failed to properly restore the thread's
        // restoring the priority, but doesn't do anything with cgroups so we
        // scheduling parameters upon completion.
        // need to take care of that here in userspace.  Note that we do make
        int my_id;
        // sure to go in the foreground after executing a transaction, but
#ifdef HAVE_GETTID
        // there are other callbacks into user code that could have changed
        my_id = gettid();
        // our group so we want to make absolutely sure it is put back.
#else
        androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
        my_id = getpid();
#endif
        if (!set_sched_policy(my_id, SP_FOREGROUND)) {
            // success; reset the priority as well
            setpriority(PRIO_PROCESS, my_id, ANDROID_PRIORITY_NORMAL);
        }


        // Let this thread exit the thread pool if it is no longer
        // Let this thread exit the thread pool if it is no longer
        // needed and it is not the main process thread.
        // needed and it is not the main process thread.
@@ -583,7 +588,7 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
}
}


IPCThreadState::IPCThreadState()
IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self())
    : mProcess(ProcessState::self()), mMyThreadId(androidGetTid())
{
{
    pthread_setspecific(gTLS, this);
    pthread_setspecific(gTLS, this);
    clearCaller();
    clearCaller();
@@ -930,6 +935,17 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
            mCallingPid = tr.sender_pid;
            mCallingPid = tr.sender_pid;
            mCallingUid = tr.sender_euid;
            mCallingUid = tr.sender_euid;
            
            
            bool doBackground = !gDisableBackgroundScheduling &&
                    getpriority(PRIO_PROCESS, mMyThreadId)
                            >= ANDROID_PRIORITY_BACKGROUND;
            if (doBackground) {
                // We have inherited a background priority from the caller.
                // Ensure this thread is in the background scheduling class,
                // since the driver won't modify scheduling classes for us.
                androidSetThreadSchedulingGroup(mMyThreadId,
                        ANDROID_TGROUP_BG_NONINTERACT);
            }
            
            //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
            //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
            
            
            Parcel reply;
            Parcel reply;
@@ -967,6 +983,13 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
            mCallingPid = origPid;
            mCallingPid = origPid;
            mCallingUid = origUid;
            mCallingUid = origUid;
            
            
            if (doBackground) {
                // We moved to the background scheduling group to execute
                // this transaction, so now that we are done go back in the
                // foreground.
                androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
            }
            
            IF_LOG_TRANSACTIONS() {
            IF_LOG_TRANSACTIONS() {
                TextOutput::Bundle _b(alog);
                TextOutput::Bundle _b(alog);
                alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
                alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
+49 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,8 @@
#include <utils/threads.h>
#include <utils/threads.h>
#include <utils/Log.h>
#include <utils/Log.h>


#include <cutils/sched_policy.h>

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <memory.h>
#include <memory.h>
@@ -269,6 +271,53 @@ void androidSetCreateThreadFunc(android_create_thread_fn func)
    gCreateThreadFn = func;
    gCreateThreadFn = func;
}
}


pid_t androidGetTid()
{
#ifdef HAVE_GETTID
    return gettid();
#else
    return getpid();
#endif
}

int androidSetThreadSchedulingGroup(pid_t tid, int grp)
{
    if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
        return BAD_VALUE;
    }

    if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
                                      SP_BACKGROUND : SP_FOREGROUND)) {
        return PERMISSION_DENIED;
    }
    
    return NO_ERROR;
}

int androidSetThreadPriority(pid_t tid, int pri)
{
    int rc = 0;
    int lasterr = 0;

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

    if (rc) {
        lasterr = errno;
    }

    if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
        rc = INVALID_OPERATION;
    } else {
        errno = lasterr;
    }
    
    return rc;
}

namespace android {
namespace android {


/*
/*