release-request-513a9883-0d18-4c2f-80ce-cadb234b4e89-for-git_nyc-mr2-pixel-monthly-release-3938523 snap-temp-L39300000065258774
Change-Id: I7a78c6e34ffa32907d81f5e19af217421745c2ca
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 7b826d6..1853cff 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -115,6 +115,7 @@
void* cookie);
const sp<ProcessState> mProcess;
+ const pid_t mMyThreadId;
Vector<BBinder*> mPendingStrongDerefs;
Vector<RefBase::weakref_type*> mPendingWeakDerefs;
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index eccc400..d90798f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -46,7 +46,6 @@
#define IF_LOG_COMMANDS() if (false)
#define LOG_REMOTEREFS(...)
#define IF_LOG_REMOTEREFS() if (false)
-
#define LOG_THREADPOOL(...)
#define LOG_ONEWAY(...)
@@ -153,7 +152,7 @@
return cmd;
}
out << kReturnStrings[cmdIndex];
-
+
switch (code) {
case BR_TRANSACTION:
case BR_REPLY: {
@@ -161,12 +160,12 @@
cmd = (const int32_t *)printBinderTransactionData(out, cmd);
out << dedent;
} break;
-
+
case BR_ACQUIRE_RESULT: {
const int32_t res = *cmd++;
out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
} break;
-
+
case BR_INCREFS:
case BR_ACQUIRE:
case BR_RELEASE:
@@ -175,7 +174,7 @@
const int32_t c = *cmd++;
out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
} break;
-
+
case BR_ATTEMPT_ACQUIRE: {
const int32_t p = *cmd++;
const int32_t b = *cmd++;
@@ -195,7 +194,7 @@
// BR_TRANSACTION_COMPLETE, BR_FINISHED
break;
}
-
+
out << endl;
return cmd;
}
@@ -220,17 +219,17 @@
cmd = (const int32_t *)printBinderTransactionData(out, cmd);
out << dedent;
} break;
-
+
case BC_ACQUIRE_RESULT: {
const int32_t res = *cmd++;
out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
} break;
-
+
case BC_FREE_BUFFER: {
const int32_t buf = *cmd++;
out << ": buffer=" << (void*)(long)buf;
} break;
-
+
case BC_INCREFS:
case BC_ACQUIRE:
case BC_RELEASE:
@@ -238,20 +237,20 @@
const int32_t d = *cmd++;
out << ": desc=" << d;
} break;
-
+
case BC_INCREFS_DONE:
case BC_ACQUIRE_DONE: {
const int32_t b = *cmd++;
const int32_t c = *cmd++;
out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
} break;
-
+
case BC_ATTEMPT_ACQUIRE: {
const int32_t p = *cmd++;
const int32_t d = *cmd++;
out << ": desc=" << d << ", pri=" << p;
} break;
-
+
case BC_REQUEST_DEATH_NOTIFICATION:
case BC_CLEAR_DEATH_NOTIFICATION: {
const int32_t h = *cmd++;
@@ -269,7 +268,7 @@
// BC_EXIT_LOOPER
break;
}
-
+
out << endl;
return cmd;
}
@@ -289,12 +288,12 @@
if (st) return st;
return new IPCThreadState;
}
-
+
if (gShutdown) {
ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
return NULL;
}
-
+
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS) {
int key_create_value = pthread_key_create(&gTLS, threadDestructor);
@@ -323,7 +322,7 @@
void IPCThreadState::shutdown()
{
gShutdown = true;
-
+
if (gHaveTLS) {
// XXX Need to wait for all thread pool threads to exit!
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
@@ -458,6 +457,15 @@
}
pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
pthread_mutex_unlock(&mProcess->mThreadCountLock);
+
+ // After executing the command, ensure that the thread is returned to the
+ // foreground cgroup before rejoining the pool. The driver takes care of
+ // restoring the priority, but doesn't do anything with cgroups so we
+ // need to take care of that here in userspace. Note that we do make
+ // sure to go in the foreground after executing a transaction, but
+ // there are other callbacks into user code that could have changed
+ // our group so we want to make absolutely sure it is put back.
+ set_sched_policy(mMyThreadId, SP_FOREGROUND);
}
return result;
@@ -492,7 +500,12 @@
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
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 foreground
+ // one to avoid performing an initial transaction in the background.
+ set_sched_policy(mMyThreadId, SP_FOREGROUND);
+
status_t result;
do {
processPendingDerefs();
@@ -504,7 +517,7 @@
mProcess->mDriverFD, result);
abort();
}
-
+
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
if(result == TIMED_OUT && !isMain) {
@@ -567,18 +580,18 @@
<< handle << " / code " << TypeCode(code) << ": "
<< indent << data << dedent << endl;
}
-
+
if (err == NO_ERROR) {
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
-
+
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
-
+
if ((flags & TF_ONE_WAY) == 0) {
#if 0
if (code == 4) { // relayout
@@ -600,7 +613,7 @@
ALOGI("<<<<<< RETURNING transaction %d", code);
}
#endif
-
+
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
@@ -611,7 +624,7 @@
} else {
err = waitForResponse(NULL, NULL);
}
-
+
return err;
}
@@ -651,14 +664,14 @@
mOut.writeInt32(0); // xxx was thread priority
mOut.writeInt32(handle);
status_t result = UNKNOWN_ERROR;
-
+
waitForResponse(NULL, &result);
-
+
#if LOG_REFCOUNTS
printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
#endif
-
+
return result;
#else
(void)handle;
@@ -693,6 +706,7 @@
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
+ mMyThreadId(gettid()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
@@ -712,7 +726,7 @@
status_t statusBuffer;
err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
if (err < NO_ERROR) return err;
-
+
return waitForResponse(NULL, NULL);
}
@@ -726,9 +740,9 @@
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
-
+
cmd = (uint32_t)mIn.readInt32();
-
+
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
@@ -738,7 +752,7 @@
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
-
+
case BR_DEAD_REPLY:
err = DEAD_OBJECT;
goto finish;
@@ -746,7 +760,7 @@
case BR_FAILED_REPLY:
err = FAILED_TRANSACTION;
goto finish;
-
+
case BR_ACQUIRE_RESULT:
{
ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
@@ -755,7 +769,7 @@
*acquireResult = result ? NO_ERROR : INVALID_OPERATION;
}
goto finish;
-
+
case BR_REPLY:
{
binder_transaction_data tr;
@@ -803,7 +817,7 @@
if (reply) reply->setError(err);
mLastError = err;
}
-
+
return err;
}
@@ -812,17 +826,17 @@
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}
-
+
binder_write_read bwr;
-
+
// Is the read buffer empty?
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
-
+
// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
-
+
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
@@ -848,7 +862,7 @@
alog << "Size of receive buffer: " << bwr.read_size
<< ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
}
-
+
// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
@@ -904,7 +918,7 @@
}
return NO_ERROR;
}
-
+
return err;
}
@@ -920,7 +934,7 @@
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
-
+
const status_t err = data.errorCheck();
if (err == NO_ERROR) {
tr.data_size = data.ipcDataSize();
@@ -937,10 +951,10 @@
} else {
return (mLastError = err);
}
-
+
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr));
-
+
return NO_ERROR;
}
@@ -956,15 +970,15 @@
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
-
+
switch ((uint32_t)cmd) {
case BR_ERROR:
result = mIn.readInt32();
break;
-
+
case BR_OK:
break;
-
+
case BR_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
@@ -980,7 +994,7 @@
mOut.writePointer((uintptr_t)refs);
mOut.writePointer((uintptr_t)obj);
break;
-
+
case BR_RELEASE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
@@ -993,7 +1007,7 @@
}
mPendingStrongDerefs.push(obj);
break;
-
+
case BR_INCREFS:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
@@ -1002,7 +1016,7 @@
mOut.writePointer((uintptr_t)refs);
mOut.writePointer((uintptr_t)obj);
break;
-
+
case BR_DECREFS:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
@@ -1014,22 +1028,22 @@
// refs, obj, refs->refBase());
mPendingWeakDerefs.push(refs);
break;
-
+
case BR_ATTEMPT_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readPointer();
obj = (BBinder*)mIn.readPointer();
-
+
{
const bool success = refs->attemptIncStrong(mProcess.get());
ALOG_ASSERT(success && refs->refBase() == obj,
"BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
-
+
mOut.writeInt32(BC_ACQUIRE_RESULT);
mOut.writeInt32((int32_t)success);
}
break;
-
+
case BR_TRANSACTION:
{
binder_transaction_data tr;
@@ -1037,14 +1051,14 @@
ALOG_ASSERT(result == NO_ERROR,
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
-
+
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
-
+
const pid_t origPid = mCallingPid;
const uid_t origUid = mCallingUid;
const int32_t origStrictModePolicy = mStrictModePolicy;
@@ -1054,6 +1068,26 @@
mCallingUid = tr.sender_euid;
mLastTransactionBinderFlags = tr.flags;
+ int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
+ if (gDisableBackgroundScheduling) {
+ if (curPrio > ANDROID_PRIORITY_NORMAL) {
+ // We have inherited a reduced priority from the caller, but do not
+ // want to run in that state in this process. The driver set our
+ // priority already (though not our scheduling class), so bounce
+ // it back to the default before invoking the transaction.
+ setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
+ }
+ } else {
+ if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
+ // We want to use the inherited priority from the caller.
+ // Ensure this thread is in the background scheduling class,
+ // since the driver won't modify scheduling classes for us.
+ // The scheduling group is reset to default by the caller
+ // once this method returns after the transaction is complete.
+ set_sched_policy(mMyThreadId, SP_BACKGROUND);
+ }
+ }
+
//ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
Parcel reply;
@@ -1087,7 +1121,7 @@
//ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
// mCallingPid, origPid, origUid);
-
+
if ((tr.flags & TF_ONE_WAY) == 0) {
LOG_ONEWAY("Sending reply to %d!", mCallingPid);
if (error < NO_ERROR) reply.setError(error);
@@ -1095,7 +1129,7 @@
} else {
LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
}
-
+
mCallingPid = origPid;
mCallingUid = origUid;
mStrictModePolicy = origStrictModePolicy;
@@ -1106,10 +1140,10 @@
alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
<< tr.target.ptr << ": " << indent << reply << dedent << endl;
}
-
+
}
break;
-
+
case BR_DEAD_BINDER:
{
BpBinder *proxy = (BpBinder*)mIn.readPointer();
@@ -1117,24 +1151,24 @@
mOut.writeInt32(BC_DEAD_BINDER_DONE);
mOut.writePointer((uintptr_t)proxy);
} break;
-
+
case BR_CLEAR_DEATH_NOTIFICATION_DONE:
{
BpBinder *proxy = (BpBinder*)mIn.readPointer();
proxy->getWeakRefs()->decWeak(proxy);
} break;
-
+
case BR_FINISHED:
result = TIMED_OUT;
break;
-
+
case BR_NOOP:
break;
-
+
case BR_SPAWN_LOOPER:
mProcess->spawnPooledThread(false);
break;
-
+
default:
printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
result = UNKNOWN_ERROR;
@@ -1144,7 +1178,7 @@
if (result != NO_ERROR) {
mLastError = result;
}
-
+
return result;
}