Loading packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/KairosNetwork.kt +4 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.kairos import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.kairos.internal.BuildScopeImpl import com.android.systemui.kairos.internal.EvalScope import com.android.systemui.kairos.internal.Network Loading @@ -31,7 +32,6 @@ import com.android.systemui.kairos.util.toNameData import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Deferred Loading Loading @@ -293,17 +293,19 @@ fun CoroutineScope.launchKairosNetwork( ): RootKairosNetwork { val scope = childScope(context) val network = Network(scope, coalescingPolicy) scope.launch(CoroutineName("launchKairosNetwork scheduler")) { network.runInputScheduler() } scope.launchTraced("launchKairosNetwork scheduler") { network.runInputScheduler() } return RootKairosNetwork(network, scope, scope.coroutineContext.job) } /** Constructs a new [RootKairosNetwork] in the given [CoroutineScope] and [CoalescingPolicy]. */ @ExperimentalKairosApi fun KairosNetwork( scope: CoroutineScope, coalescingPolicy: CoalescingPolicy = CoalescingPolicy.Normal, ): RootKairosNetwork = scope.launchKairosNetwork(coalescingPolicy = coalescingPolicy) /** Configures how multiple input events are processed by the network. */ @ExperimentalKairosApi enum class CoalescingPolicy { /** * Each input event is processed in its own transaction. This policy has the least overhead but Loading packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt +4 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import com.android.systemui.kairos.CoalescingPolicy import com.android.systemui.kairos.internal.util.LogIndent import com.android.systemui.kairos.internal.util.fastForEach import com.android.systemui.kairos.internal.util.logDuration import com.android.systemui.kairos.internal.util.logDurationCoroutine import com.android.systemui.kairos.util.Maybe import com.android.systemui.kairos.util.Maybe.Present import com.android.systemui.kairos.util.maybeOf Loading Loading @@ -126,7 +127,7 @@ internal class Network( } } val e = epoch logDuration(indent = 0, { "Kairos Transaction epoch=$e" }, trace = true) { logDurationCoroutine(indent = 0, { "Kairos Transaction epoch=$e" }, trace = true) { val evalScope = EvalScopeImpl(networkScope = this@Network, deferScope = deferScopeImpl) try { Loading Loading @@ -181,12 +182,12 @@ internal class Network( } logLn { "drained $numNodes nodes" } } while ( logDuration({ "drain outputs" }, trace = true) { logDuration({ "drain sync outputs" }, trace = true) { runThenDrainDeferrals { evalFastOutputs(evalScope) } } ) } evalLaunchedOutputs(coroutineScope) logDuration({ "drain launched outputs" }) { evalLaunchedOutputs(coroutineScope) } // Invalidate caches // Note: this needs to occur before deferred switches logDuration({ "clear store" }) { transactionStore.clear() } Loading packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/util/Logging.kt +41 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.kairos.internal.util import com.android.app.tracing.coroutines.traceCoroutine import com.android.app.tracing.traceSection import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind Loading Loading @@ -44,12 +45,23 @@ internal value class LogIndent(val currentLogIndent: Int) { getPrefix: () -> String, start: Boolean = true, trace: Boolean = false, block: LogIndent.() -> R, crossinline block: LogIndent.() -> R, ): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return logDuration(currentLogIndent, getPrefix, start, trace, block) } @OptIn(ExperimentalContracts::class) suspend inline fun <R> logDurationCoroutine( crossinline getPrefix: () -> String, start: Boolean = true, trace: Boolean = false, block: suspend LogIndent.() -> R, ): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return logDurationCoroutine(currentLogIndent, getPrefix, start, trace, block) } inline fun logLn(getMessage: () -> Any?) = logLn(currentLogIndent, getMessage) } Loading Loading @@ -81,6 +93,34 @@ internal inline fun <R> logDuration( } } @OptIn(ExperimentalContracts::class) internal suspend inline fun <R> logDurationCoroutine( indent: Int, crossinline getPrefix: () -> String, start: Boolean = true, trace: Boolean = false, block: suspend LogIndent.() -> R, ): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) callsInPlace(getPrefix, InvocationKind.AT_MOST_ONCE) } return if (!LoggingEnabled) { if (trace) { traceCoroutine(getPrefix) { LogIndent(0).block() } } else { LogIndent(0).block() } } else { val prefix = getPrefix() if (trace) { traceCoroutine(prefix) { logDurationInternal(start, indent, prefix) { block() } } } else { logDurationInternal(start, indent, prefix) { block() } } } } @OptIn(ExperimentalContracts::class) private inline fun <R> logDurationInternal( start: Boolean, Loading Loading
packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/KairosNetwork.kt +4 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.kairos import com.android.app.tracing.coroutines.launchTraced import com.android.systemui.kairos.internal.BuildScopeImpl import com.android.systemui.kairos.internal.EvalScope import com.android.systemui.kairos.internal.Network Loading @@ -31,7 +32,6 @@ import com.android.systemui.kairos.util.toNameData import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Deferred Loading Loading @@ -293,17 +293,19 @@ fun CoroutineScope.launchKairosNetwork( ): RootKairosNetwork { val scope = childScope(context) val network = Network(scope, coalescingPolicy) scope.launch(CoroutineName("launchKairosNetwork scheduler")) { network.runInputScheduler() } scope.launchTraced("launchKairosNetwork scheduler") { network.runInputScheduler() } return RootKairosNetwork(network, scope, scope.coroutineContext.job) } /** Constructs a new [RootKairosNetwork] in the given [CoroutineScope] and [CoalescingPolicy]. */ @ExperimentalKairosApi fun KairosNetwork( scope: CoroutineScope, coalescingPolicy: CoalescingPolicy = CoalescingPolicy.Normal, ): RootKairosNetwork = scope.launchKairosNetwork(coalescingPolicy = coalescingPolicy) /** Configures how multiple input events are processed by the network. */ @ExperimentalKairosApi enum class CoalescingPolicy { /** * Each input event is processed in its own transaction. This policy has the least overhead but Loading
packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Network.kt +4 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import com.android.systemui.kairos.CoalescingPolicy import com.android.systemui.kairos.internal.util.LogIndent import com.android.systemui.kairos.internal.util.fastForEach import com.android.systemui.kairos.internal.util.logDuration import com.android.systemui.kairos.internal.util.logDurationCoroutine import com.android.systemui.kairos.util.Maybe import com.android.systemui.kairos.util.Maybe.Present import com.android.systemui.kairos.util.maybeOf Loading Loading @@ -126,7 +127,7 @@ internal class Network( } } val e = epoch logDuration(indent = 0, { "Kairos Transaction epoch=$e" }, trace = true) { logDurationCoroutine(indent = 0, { "Kairos Transaction epoch=$e" }, trace = true) { val evalScope = EvalScopeImpl(networkScope = this@Network, deferScope = deferScopeImpl) try { Loading Loading @@ -181,12 +182,12 @@ internal class Network( } logLn { "drained $numNodes nodes" } } while ( logDuration({ "drain outputs" }, trace = true) { logDuration({ "drain sync outputs" }, trace = true) { runThenDrainDeferrals { evalFastOutputs(evalScope) } } ) } evalLaunchedOutputs(coroutineScope) logDuration({ "drain launched outputs" }) { evalLaunchedOutputs(coroutineScope) } // Invalidate caches // Note: this needs to occur before deferred switches logDuration({ "clear store" }) { transactionStore.clear() } Loading
packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/util/Logging.kt +41 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.kairos.internal.util import com.android.app.tracing.coroutines.traceCoroutine import com.android.app.tracing.traceSection import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind Loading Loading @@ -44,12 +45,23 @@ internal value class LogIndent(val currentLogIndent: Int) { getPrefix: () -> String, start: Boolean = true, trace: Boolean = false, block: LogIndent.() -> R, crossinline block: LogIndent.() -> R, ): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return logDuration(currentLogIndent, getPrefix, start, trace, block) } @OptIn(ExperimentalContracts::class) suspend inline fun <R> logDurationCoroutine( crossinline getPrefix: () -> String, start: Boolean = true, trace: Boolean = false, block: suspend LogIndent.() -> R, ): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return logDurationCoroutine(currentLogIndent, getPrefix, start, trace, block) } inline fun logLn(getMessage: () -> Any?) = logLn(currentLogIndent, getMessage) } Loading Loading @@ -81,6 +93,34 @@ internal inline fun <R> logDuration( } } @OptIn(ExperimentalContracts::class) internal suspend inline fun <R> logDurationCoroutine( indent: Int, crossinline getPrefix: () -> String, start: Boolean = true, trace: Boolean = false, block: suspend LogIndent.() -> R, ): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) callsInPlace(getPrefix, InvocationKind.AT_MOST_ONCE) } return if (!LoggingEnabled) { if (trace) { traceCoroutine(getPrefix) { LogIndent(0).block() } } else { LogIndent(0).block() } } else { val prefix = getPrefix() if (trace) { traceCoroutine(prefix) { logDurationInternal(start, indent, prefix) { block() } } } else { logDurationInternal(start, indent, prefix) { block() } } } } @OptIn(ExperimentalContracts::class) private inline fun <R> logDurationInternal( start: Boolean, Loading