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

Commit d5a9dc06 authored by John Reck's avatar John Reck Committed by Michael Wright
Browse files

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
parent 71fa53f8
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
/*
 * 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);
        }
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -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 {
+51 −0
Original line number Diff line number Diff line
@@ -287,6 +287,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);
        }
    }
}
+38 −51
Original line number Diff line number Diff line
@@ -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);
}