Framework-side support for Dalvik "isSensitiveThread" hook.
Used in lock contention stats.
Bug: 3226270
Change-Id: Ie6f58d130a29079a59bdefad40b80304d9bc3623
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 07505a5..2dfebe5 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -20,6 +20,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <binder/IBinder.h>
+#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <utils/misc.h>
@@ -431,6 +432,20 @@
LOG_PRI_VA(ANDROID_LOG_INFO, "vm-printf", format, ap);
}
+/**
+ * The VM calls this when mutex contention debugging is enabled to
+ * determine whether or not the blocked thread was a "sensitive thread"
+ * for user responsiveness/smoothess.
+ *
+ * Our policy for this is whether or not we're tracing any StrictMode
+ * events on this thread (which we might've inherited via Binder calls
+ * into us)
+ */
+static bool runtime_isSensitiveThread() {
+ IPCThreadState* state = IPCThreadState::selfOrNull();
+ return state && state->getStrictModePolicy() != 0;
+}
+
/**
* Add VM arguments to the to-be-executed VM
@@ -618,6 +633,11 @@
opt.optionString = "vfprintf";
mOptions.add(opt);
+ /* register the framework-specific "is sensitive thread" hook */
+ opt.extraInfo = (void*) runtime_isSensitiveThread;
+ opt.optionString = "sensitiveThread";
+ mOptions.add(opt);
+
opt.extraInfo = NULL;
/* enable verbose; standard options are { jni, gc, class } */
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index b54718f..3378d97 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -33,6 +33,7 @@
{
public:
static IPCThreadState* self();
+ static IPCThreadState* selfOrNull(); // self(), but won't instantiate
sp<ProcessState> process();
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 13c58f0..95cfddf 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -318,6 +318,16 @@
goto restart;
}
+IPCThreadState* IPCThreadState::selfOrNull()
+{
+ if (gHaveTLS) {
+ const pthread_key_t k = gTLS;
+ IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
+ return st;
+ }
+ return NULL;
+}
+
void IPCThreadState::shutdown()
{
gShutdown = true;