summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2018-07-16 10:42:35 -0700
committerMichael Wright <michaelwr@google.com>2018-07-17 14:35:01 +0000
commitd5a9dc06be523d3414a8a3103304357228e53072 (patch)
treeac8de24ec11f6f23517f6907e2fd01325c831f40
parent71fa53f8a548993d30d91343caee0e6269e8c0c5 (diff)
Expose async & counter publicly
Also add some go-faster to the JNI Before: android.os.TracePerfTest:INSTRUMENTATION_STATUS: enabled_mean=13 INSTRUMENTATION_STATUS: enabled_median=13 INSTRUMENTATION_STATUS: enabled_min=13 INSTRUMENTATION_STATUS: enabled_standardDeviation=0 INSTRUMENTATION_STATUS_CODE: -1 .INSTRUMENTATION_STATUS: beginEndSection_mean=3849 INSTRUMENTATION_STATUS: beginEndSection_median=3850 INSTRUMENTATION_STATUS: beginEndSection_min=3829 INSTRUMENTATION_STATUS: beginEndSection_standardDeviation=14 INSTRUMENTATION_STATUS_CODE: -1 .INSTRUMENTATION_STATUS: counter_mean=1836 INSTRUMENTATION_STATUS: counter_median=1837 INSTRUMENTATION_STATUS: counter_min=1832 INSTRUMENTATION_STATUS: counter_standardDeviation=2 INSTRUMENTATION_STATUS_CODE: -1 .INSTRUMENTATION_STATUS: asyncBeginEnd_mean=4992 INSTRUMENTATION_STATUS: asyncBeginEnd_median=4988 INSTRUMENTATION_STATUS: asyncBeginEnd_min=4964 INSTRUMENTATION_STATUS: asyncBeginEnd_standardDeviation=21 INSTRUMENTATION_STATUS_CODE: -1 After: android.os.TracePerfTest:INSTRUMENTATION_STATUS: enabled_mean=13 INSTRUMENTATION_STATUS: enabled_median=13 INSTRUMENTATION_STATUS: enabled_min=13 INSTRUMENTATION_STATUS: enabled_standardDeviation=0 INSTRUMENTATION_STATUS_CODE: -1 .INSTRUMENTATION_STATUS: beginEndSection_mean=2974 INSTRUMENTATION_STATUS: beginEndSection_median=2971 INSTRUMENTATION_STATUS: beginEndSection_min=2958 INSTRUMENTATION_STATUS: beginEndSection_standardDeviation=15 INSTRUMENTATION_STATUS_CODE: -1 .INSTRUMENTATION_STATUS: counter_mean=1737 INSTRUMENTATION_STATUS: counter_median=1739 INSTRUMENTATION_STATUS: counter_min=1732 INSTRUMENTATION_STATUS: counter_standardDeviation=3 INSTRUMENTATION_STATUS_CODE: -1 .INSTRUMENTATION_STATUS: asyncBeginEnd_mean=3677 INSTRUMENTATION_STATUS: asyncBeginEnd_median=3679 INSTRUMENTATION_STATUS: asyncBeginEnd_min=3663 INSTRUMENTATION_STATUS: asyncBeginEnd_standardDeviation=11 INSTRUMENTATION_STATUS_CODE: -1 Test: builds, benchmarks, verified tracing still works Bug: 111503982 Change-Id: I71cb026d034bf9b9f97427d10d5ff9ce3d103561
-rw-r--r--apct-tests/perftests/core/src/android/os/TracePerfTest.java86
-rw-r--r--apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java8
-rw-r--r--api/current.txt4
-rw-r--r--core/java/android/os/Trace.java51
-rw-r--r--core/jni/android_os_Trace.cpp89
5 files changed, 187 insertions, 51 deletions
diff --git a/apct-tests/perftests/core/src/android/os/TracePerfTest.java b/apct-tests/perftests/core/src/android/os/TracePerfTest.java
new file mode 100644
index 000000000000..8e5cfaafde52
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/TracePerfTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+
+package android.os;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.perftests.utils.ShellHelper;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class TracePerfTest {
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @BeforeClass
+ public static void startTracing() {
+ ShellHelper.runShellCommandRaw("atrace -c --async_start -a *");
+ }
+
+ @AfterClass
+ public static void endTracing() {
+ ShellHelper.runShellCommandRaw("atrace --async_stop");
+ }
+
+ @Before
+ public void verifyTracingEnabled() {
+ Assert.assertTrue(Trace.isEnabled());
+ }
+
+ @Test
+ public void testEnabled() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ Trace.isEnabled();
+ }
+ }
+
+ @Test
+ public void testBeginEndSection() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ Trace.beginSection("testBeginEndSection");
+ Trace.endSection();
+ }
+ }
+
+ @Test
+ public void testAsyncBeginEnd() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ Trace.beginAsyncSection("testAsyncBeginEnd", 42);
+ Trace.endAsyncSection("testAsyncBeginEnd", 42);
+ }
+ }
+
+ @Test
+ public void testCounter() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ Trace.setCounter("testCounter", 123);
+ }
+ }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java b/apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java
index cae87fb9c6e4..895547df0393 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/ShellHelper.java
@@ -37,6 +37,14 @@ public final class ShellHelper {
@NonNull
public static String runShellCommand(@NonNull String template, Object...args) {
String command = String.format(template, args);
+ return runShellCommandRaw(command);
+ }
+
+ /**
+ * Runs a Shell command, returning a trimmed response.
+ */
+ @NonNull
+ public static String runShellCommandRaw(@NonNull String command) {
UiAutomation automan = InstrumentationRegistry.getInstrumentation()
.getUiAutomation();
ParcelFileDescriptor pfd = automan.executeShellCommand(command);
diff --git a/api/current.txt b/api/current.txt
index aff03095844e..9c9d8c55c6b0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33278,8 +33278,12 @@ package android.os {
}
public final class Trace {
+ method public static void beginAsyncSection(java.lang.String, int);
method public static void beginSection(java.lang.String);
+ method public static void endAsyncSection(java.lang.String, int);
method public static void endSection();
+ method public static boolean isEnabled();
+ method public static void setCounter(java.lang.String, int);
}
public class TransactionTooLargeException extends android.os.RemoteException {
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 583f060f2e0c..a967b3da339e 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -288,6 +288,19 @@ public final class Trace {
}
/**
+ * Checks whether or not tracing is currently enabled. This is useful to avoid intermediate
+ * string creation for trace sections that require formatting. It is not necessary
+ * to guard all Trace method calls as they internally already check this. However it is
+ * recommended to use this to prevent creating any temporary objects that would then be
+ * passed to those methods to reduce runtime cost when tracing isn't enabled.
+ *
+ * @return true if tracing is currently enabled, false otherwise
+ */
+ public static boolean isEnabled() {
+ return isTagEnabled(TRACE_TAG_APP);
+ }
+
+ /**
* Writes a trace message to indicate that a given section of code has begun. This call must
* be followed by a corresponding call to {@link #endSection()} on the same thread.
*
@@ -319,4 +332,42 @@ public final class Trace {
nativeTraceEnd(TRACE_TAG_APP);
}
}
+
+ /**
+ * Writes a trace message to indicate that a given section of code has
+ * begun. Must be followed by a call to {@link #endAsyncSection(String, int)} with the same
+ * methodName and cookie. Unlike {@link #beginSection(String)} and {@link #endSection()},
+ * asynchronous events do not need to be nested. The name and cookie used to
+ * begin an event must be used to end it.
+ *
+ * @param methodName The method name to appear in the trace.
+ * @param cookie Unique identifier for distinguishing simultaneous events
+ */
+ public static void beginAsyncSection(String methodName, int cookie) {
+ asyncTraceBegin(TRACE_TAG_APP, methodName, cookie);
+ }
+
+ /**
+ * Writes a trace message to indicate that the current method has ended.
+ * Must be called exactly once for each call to {@link #beginAsyncSection(String, int)}
+ * using the same name and cookie.
+ *
+ * @param methodName The method name to appear in the trace.
+ * @param cookie Unique identifier for distinguishing simultaneous events
+ */
+ public static void endAsyncSection(String methodName, int cookie) {
+ asyncTraceEnd(TRACE_TAG_APP, methodName, cookie);
+ }
+
+ /**
+ * Writes trace message to indicate the value of a given counter.
+ *
+ * @param counterName The counter name to appear in the trace.
+ * @param counterValue The counter value.
+ */
+ public static void setCounter(String counterName, int counterValue) {
+ if (isTagEnabled(TRACE_TAG_APP)) {
+ nativeTraceCounter(TRACE_TAG_APP, counterName, counterValue);
+ }
+ }
}
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index 4f4e5da22c8d..f7dab428abe7 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -14,93 +14,80 @@
* limitations under the License.
*/
-#define LOG_TAG "Trace"
-// #define LOG_NDEBUG 0
-
-#include <inttypes.h>
+#include <jni.h>
#include <cutils/trace.h>
-#include <utils/String8.h>
#include <log/log.h>
-
#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <nativehelper/ScopedStringChars.h>
+
+#include <array>
namespace android {
-static void sanitizeString(String8& utf8Chars) {
- size_t size = utf8Chars.size();
- char* str = utf8Chars.lockBuffer(size);
+inline static void sanitizeString(char* str, size_t size) {
for (size_t i = 0; i < size; i++) {
char c = str[i];
if (c == '\0' || c == '\n' || c == '|') {
str[i] = ' ';
}
}
- utf8Chars.unlockBuffer();
}
-static jlong android_os_Trace_nativeGetEnabledTags(JNIEnv* env, jclass clazz) {
+inline static void getString(JNIEnv* env, jstring jstring, char* outBuffer, jsize maxSize) {
+ jsize size = std::min(env->GetStringLength(jstring), maxSize);
+ env->GetStringUTFRegion(jstring, 0, size, outBuffer);
+ sanitizeString(outBuffer, size);
+ outBuffer[size] = '\0';
+}
+
+template<typename F>
+inline static void withString(JNIEnv* env, jstring jstr, F callback) {
+ std::array<char, 1024> buffer;
+ getString(env, jstr, buffer.data(), buffer.size());
+ callback(buffer.data());
+}
+
+static jlong android_os_Trace_nativeGetEnabledTags(JNIEnv*, jclass) {
return atrace_get_enabled_tags();
}
-static void android_os_Trace_nativeTraceCounter(JNIEnv* env, jclass clazz,
+static void android_os_Trace_nativeTraceCounter(JNIEnv* env, jclass,
jlong tag, jstring nameStr, jint value) {
- ScopedUtfChars name(env, nameStr);
-
- ALOGV("%s: %" PRId64 " %s %d", __FUNCTION__, tag, name.c_str(), value);
- atrace_int(tag, name.c_str(), value);
+ withString(env, nameStr, [tag, value](char* str) {
+ atrace_int(tag, str, value);
+ });
}
-static void android_os_Trace_nativeTraceBegin(JNIEnv* env, jclass clazz,
+static void android_os_Trace_nativeTraceBegin(JNIEnv* env, jclass,
jlong tag, jstring nameStr) {
- ScopedStringChars jchars(env, nameStr);
- String8 utf8Chars(reinterpret_cast<const char16_t*>(jchars.get()), jchars.size());
- sanitizeString(utf8Chars);
-
- ALOGV("%s: %" PRId64 " %s", __FUNCTION__, tag, utf8Chars.string());
- atrace_begin(tag, utf8Chars.string());
+ withString(env, nameStr, [tag](char* str) {
+ atrace_begin(tag, str);
+ });
}
-static void android_os_Trace_nativeTraceEnd(JNIEnv* env, jclass clazz,
- jlong tag) {
-
- ALOGV("%s: %" PRId64, __FUNCTION__, tag);
+static void android_os_Trace_nativeTraceEnd(JNIEnv*, jclass, jlong tag) {
atrace_end(tag);
}
-static void android_os_Trace_nativeAsyncTraceBegin(JNIEnv* env, jclass clazz,
+static void android_os_Trace_nativeAsyncTraceBegin(JNIEnv* env, jclass,
jlong tag, jstring nameStr, jint cookie) {
- ScopedStringChars jchars(env, nameStr);
- String8 utf8Chars(reinterpret_cast<const char16_t*>(jchars.get()), jchars.size());
- sanitizeString(utf8Chars);
-
- ALOGV("%s: %" PRId64 " %s %d", __FUNCTION__, tag, utf8Chars.string(), cookie);
- atrace_async_begin(tag, utf8Chars.string(), cookie);
+ withString(env, nameStr, [tag, cookie](char* str) {
+ atrace_async_begin(tag, str, cookie);
+ });
}
-static void android_os_Trace_nativeAsyncTraceEnd(JNIEnv* env, jclass clazz,
+static void android_os_Trace_nativeAsyncTraceEnd(JNIEnv* env, jclass,
jlong tag, jstring nameStr, jint cookie) {
- ScopedStringChars jchars(env, nameStr);
- String8 utf8Chars(reinterpret_cast<const char16_t*>(jchars.get()), jchars.size());
- sanitizeString(utf8Chars);
-
- ALOGV("%s: %" PRId64 " %s %d", __FUNCTION__, tag, utf8Chars.string(), cookie);
- atrace_async_end(tag, utf8Chars.string(), cookie);
+ withString(env, nameStr, [tag, cookie](char* str) {
+ atrace_async_end(tag, str, cookie);
+ });
}
-static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv* env,
- jclass clazz, jboolean allowed) {
- ALOGV("%s: %d", __FUNCTION__, allowed);
-
+static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv*, jclass, jboolean allowed) {
atrace_set_debuggable(allowed);
}
-static void android_os_Trace_nativeSetTracingEnabled(JNIEnv* env,
- jclass clazz, jboolean enabled) {
- ALOGV("%s: %d", __FUNCTION__, enabled);
-
+static void android_os_Trace_nativeSetTracingEnabled(JNIEnv*, jclass, jboolean enabled) {
atrace_set_tracing_enabled(enabled);
}