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

Commit 89fb0138 authored by Peter Kalauskas's avatar Peter Kalauskas Committed by Android (Google) Code Review
Browse files

Merge "tracinglib: query aflag instead of sysprop" into main

parents db48957f ec7e31d9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ import android.platform.test.flag.junit.SetFlagsRule
import android.platform.test.rule.EnsureDeviceSettingsRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.Flags.FLAG_COROUTINE_TRACING
import java.util.concurrent.atomic.AtomicInteger
import org.junit.After
import org.junit.Assert
@@ -33,7 +33,7 @@ import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableFlags(Flags.FLAG_COROUTINE_TRACING)
@EnableFlags(FLAG_COROUTINE_TRACING)
class ThreadLocalMicroBenchmark {

    @get:Rule val setFlagsRule = SetFlagsRule()
+2 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import androidx.test.filters.SmallTest
import com.android.app.tracing.coroutines.createCoroutineTracingContext
import com.android.app.tracing.coroutines.nameCoroutine
import com.android.app.tracing.coroutines.traceCoroutine
import com.android.systemui.Flags
import com.android.systemui.Flags.FLAG_COROUTINE_TRACING
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
@@ -41,7 +41,7 @@ import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableFlags(Flags.FLAG_COROUTINE_TRACING)
@EnableFlags(FLAG_COROUTINE_TRACING)
class TraceContextMicroBenchmark {

    @get:Rule val setFlagsRule = SetFlagsRule()
+21 −9
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
package com.android.app.tracing.coroutines

import com.android.app.tracing.traceSection
import com.android.systemui.Flags
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@@ -223,10 +222,14 @@ public inline fun <T, R> R.traceCoroutine(crossinline spanName: () -> String, bl
    // tracing is not active (i.e. when TRACE_TAG_APP is disabled). Otherwise, when the
    // coroutine resumes when tracing is active, we won't know its name.
    try {
        if (Flags.coroutineTracing()) traceThreadLocal.get()?.beginCoroutineTrace(spanName())
        if (com.android.systemui.Flags.coroutineTracing()) {
            traceThreadLocal.get()?.beginCoroutineTrace(spanName())
        }
        return block()
    } finally {
        if (Flags.coroutineTracing()) traceThreadLocal.get()?.endCoroutineTrace()
        if (com.android.systemui.Flags.coroutineTracing()) {
            traceThreadLocal.get()?.endCoroutineTrace()
        }
    }
}

@@ -239,10 +242,14 @@ public inline fun <T> traceCoroutine(crossinline spanName: () -> String, block:
    // tracing is not active (i.e. when TRACE_TAG_APP is disabled). Otherwise, when the
    // coroutine resumes when tracing is active, we won't know its name.
    try {
        if (Flags.coroutineTracing()) traceThreadLocal.get()?.beginCoroutineTrace(spanName())
        if (com.android.systemui.Flags.coroutineTracing()) {
            traceThreadLocal.get()?.beginCoroutineTrace(spanName())
        }
        return block()
    } finally {
        if (Flags.coroutineTracing()) traceThreadLocal.get()?.endCoroutineTrace()
        if (com.android.systemui.Flags.coroutineTracing()) {
            traceThreadLocal.get()?.endCoroutineTrace()
        }
    }
}

@@ -259,9 +266,10 @@ public inline fun <T> traceCoroutine(spanName: String, block: () -> T): T {
}

/**
 * Returns the passed context if [Flags.coroutineTracing] is false. Otherwise, returns a new context
 * by adding [CoroutineTraceName] to the given context. The [CoroutineTraceName] in the passed
 * context will take precedence over the new [CoroutineTraceName].
 * Returns the passed context if [com.android.systemui.Flags.coroutineTracing] is false. Otherwise,
 * returns a new context by adding [CoroutineTraceName] to the given context. The
 * [CoroutineTraceName] in the passed context will take precedence over the new
 * [CoroutineTraceName].
 */
@PublishedApi
internal inline fun addName(
@@ -269,7 +277,11 @@ internal inline fun addName(
    context: CoroutineContext,
): CoroutineContext {
    contract { callsInPlace(spanName, InvocationKind.AT_MOST_ONCE) }
    return if (Flags.coroutineTracing()) CoroutineTraceName(spanName()) + context else context
    return if (com.android.systemui.Flags.coroutineTracing()) {
        CoroutineTraceName(spanName()) + context
    } else {
        context
    }
}

@PublishedApi
+9 −9
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.os.PerfettoTrace
import android.os.SystemProperties
import android.os.Trace
import android.util.Log
import com.android.systemui.Flags
import java.lang.StackWalker.StackFrame
import java.util.concurrent.ThreadLocalRandom
import java.util.concurrent.atomic.AtomicInteger
@@ -60,10 +59,6 @@ internal object DebugSysProps {
    @JvmField
    val alwaysEnableContinuationCounting =
        SystemProperties.getBoolean("debug.coroutine_tracing.count_continuations_override", false)

    @JvmField
    val UsePerfettoSdk =
        SystemProperties.getBoolean("debug.coroutine_tracing.use_perfetto_sdk", false)
}

/**
@@ -125,7 +120,7 @@ public fun createCoroutineTracingContext(
    walkStackForDefaultNames: Boolean = false,
    shouldIgnoreClassName: ((String) -> Boolean)? = null,
): CoroutineContext {
    return if (Flags.coroutineTracing()) {
    return if (com.android.systemui.Flags.coroutineTracing()) {
        TraceContextElement(
            name = name,
            isRoot = true,
@@ -166,7 +161,11 @@ public fun nameCoroutine(name: String): CoroutineContext = nameCoroutine { name
@Deprecated("Use .launchInTraced, .launchTraced, .shareInTraced, etc.")
public inline fun nameCoroutine(name: () -> String): CoroutineContext {
    contract { callsInPlace(name, InvocationKind.AT_MOST_ONCE) }
    return if (Flags.coroutineTracing()) CoroutineTraceName(name()) else EmptyCoroutineContext
    return if (com.android.systemui.Flags.coroutineTracing()) {
        CoroutineTraceName(name())
    } else {
        EmptyCoroutineContext
    }
}

private object PerfettoTraceConfig {
@@ -174,7 +173,7 @@ private object PerfettoTraceConfig {
    @JvmField val COROUTINE_CATEGORY: PerfettoTrace.Category = PerfettoTrace.Category("cc")

    init {
        if (DebugSysProps.UsePerfettoSdk) {
        if (android.os.Flags.perfettoSdkTracingV2()) {
            COROUTINE_CATEGORY.register()
        }
    }
@@ -275,7 +274,8 @@ internal class TraceContextElement(

    // Don't use Perfetto SDK when inherited trace prefixes are used since it is a feature only
    // intended for testing, and only the `android.os.Trace` APIs currently have test shadows:
    private val usePerfettoSdk = DebugSysProps.UsePerfettoSdk && inheritedTracePrefix == null
    private val usePerfettoSdk =
        android.os.Flags.perfettoSdkTracingV2() && inheritedTracePrefix == null

    private var continuationId = if (usePerfettoSdk) nextRandomInt() else 0

+16 −32
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ package com.android.app.tracing.coroutines
import android.os.Trace
import com.android.app.tracing.beginSlice
import com.android.app.tracing.endSlice
import com.android.systemui.Flags
import java.util.ArrayDeque
import kotlin.contracts.ExperimentalContracts
import kotlin.math.max
@@ -39,7 +38,7 @@ private typealias TraceSection = String
@PublishedApi
internal class TraceDataThreadLocal : ThreadLocal<TraceStorage?>() {
    override fun initialValue(): TraceStorage? {
        return if (Flags.coroutineTracing()) {
        return if (com.android.systemui.Flags.coroutineTracing()) {
            TraceStorage(null)
        } else {
            null
@@ -69,20 +68,7 @@ internal class TraceStorage(internal var data: TraceData?) {
     * * `>1` indicates the current coroutine is resumed inside another coroutine, e.g. due to an
     *   unconfined dispatcher or [UNDISPATCHED] launch.
     */
    internal var contIndex = -1

    internal lateinit var continuationIds: IntArray

    private lateinit var debugCounterTrack: String

    init {
        if (DebugSysProps.UsePerfettoSdk) {
            continuationIds = IntArray(INITIAL_THREAD_LOCAL_STACK_SIZE)
        }
        if (DEBUG) {
            debugCounterTrack = "TCE#${Thread.currentThread().threadId()}"
        }
    }
    private var contIndex = -1

    /**
     * Count of slices opened on the current thread due to current [TraceData] that must be closed
@@ -94,7 +80,14 @@ internal class TraceStorage(internal var data: TraceData?) {
     * it indicates there is already something very wrong with the trace, so we will not waste CPU
     * cycles error checking.
     */
    internal var openSliceCount = ByteArray(INITIAL_THREAD_LOCAL_STACK_SIZE)
    private var openSliceCount = ByteArray(INITIAL_THREAD_LOCAL_STACK_SIZE)

    private var continuationIds: IntArray? =
        if (android.os.Flags.perfettoSdkTracingV2()) IntArray(INITIAL_THREAD_LOCAL_STACK_SIZE)
        else null

    private val debugCounterTrack: String? =
        if (DEBUG) "TCE#${Thread.currentThread().threadId()}" else null

    /**
     * Adds a new trace section to the current trace data. The slice will be traced on the current
@@ -129,32 +122,24 @@ internal class TraceStorage(internal var data: TraceData?) {
    fun updateDataForContinuation(contextTraceData: TraceData?, contId: Int) {
        data = contextTraceData
        val n = ++contIndex
        if (DEBUG) {
            Trace.traceCounter(Trace.TRACE_TAG_APP, debugCounterTrack, n)
        }
        if (DEBUG) Trace.traceCounter(Trace.TRACE_TAG_APP, debugCounterTrack!!, n)
        if (n < 0 || MAX_THREAD_LOCAL_STACK_SIZE <= n) return // fail-safe
        var size = openSliceCount.size
        if (n >= size) {
            size = max(2 * size, MAX_THREAD_LOCAL_STACK_SIZE)
            openSliceCount = openSliceCount.copyInto(ByteArray(size))
            if (::continuationIds.isInitialized) {
                continuationIds = continuationIds.copyInto(IntArray(size))
            }
            continuationIds = continuationIds?.copyInto(IntArray(size))
        }
        openSliceCount[n] = data?.beginAllOnThread() ?: 0
        if (::continuationIds.isInitialized && 0 < contId) {
            continuationIds[n] = contId
        }
        if (0 < contId) continuationIds?.set(n, contId)
    }

    /** Update [data] for suspension */
    fun restoreDataForSuspension(oldState: TraceData?): Int {
        data = oldState
        val n = contIndex--
        if (DEBUG) {
            Trace.traceCounter(Trace.TRACE_TAG_APP, debugCounterTrack, n)
        }
        if (n < 0 || MAX_THREAD_LOCAL_STACK_SIZE <= n) return 0 // fail-safe
        if (DEBUG) Trace.traceCounter(Trace.TRACE_TAG_APP, debugCounterTrack!!, n)
        if (n < 0 || openSliceCount.size <= n) return 0 // fail-safe
        if (Trace.isTagEnabled(Trace.TRACE_TAG_APP)) {
            val lastState = openSliceCount[n]
            var i = 0
@@ -163,8 +148,7 @@ internal class TraceStorage(internal var data: TraceData?) {
                i++
            }
        }
        return if (::continuationIds.isInitialized && n < continuationIds.size) continuationIds[n]
        else 0
        return continuationIds?.let { if (n < it.size) it[n] else null } ?: 0
    }
}

Loading