1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.app.tracing.benchmark 17 18 import android.os.Trace 19 import android.perftests.utils.BenchmarkState 20 import android.perftests.utils.PerfStatusReporter 21 import android.platform.test.annotations.EnableFlags 22 import android.platform.test.flag.junit.SetFlagsRule 23 import android.platform.test.rule.EnsureDeviceSettingsRule 24 import androidx.test.ext.junit.runners.AndroidJUnit4 25 import androidx.test.filters.SmallTest 26 import com.android.app.tracing.coroutines.createCoroutineTracingContext 27 import com.android.app.tracing.coroutines.launchTraced 28 import com.android.app.tracing.coroutines.traceCoroutine 29 import com.android.systemui.Flags.FLAG_COROUTINE_TRACING 30 import kotlinx.coroutines.delay 31 import kotlinx.coroutines.runBlocking 32 import kotlinx.coroutines.withContext 33 import kotlinx.coroutines.yield 34 import org.junit.After 35 import org.junit.Assert 36 import org.junit.Before 37 import org.junit.Rule 38 import org.junit.Test 39 import org.junit.runner.RunWith 40 41 @SmallTest 42 @RunWith(AndroidJUnit4::class) 43 @EnableFlags(FLAG_COROUTINE_TRACING) 44 class TraceContextMicroBenchmark { 45 46 @get:Rule val setFlagsRule = SetFlagsRule() 47 48 @get:Rule val ensureDeviceSettingsRule = EnsureDeviceSettingsRule() 49 50 @get:Rule val perfStatusReporter = PerfStatusReporter() 51 52 @Before beforenull53 fun before() { 54 Assert.assertTrue(Trace.isEnabled()) 55 } 56 57 @After afternull58 fun after() { 59 Assert.assertTrue(Trace.isEnabled()) 60 } 61 ensureSuspendnull62 private suspend fun ensureSuspend(state: BenchmarkState) { 63 state.pauseTiming() 64 delay(1) 65 state.resumeTiming() 66 } 67 68 @Test testSingleTraceSectionnull69 fun testSingleTraceSection() { 70 val state = perfStatusReporter.benchmarkState 71 runBlocking(createCoroutineTracingContext("root")) { 72 while (state.keepRunning()) { 73 traceCoroutine("hello-world") { ensureSuspend(state) } 74 } 75 } 76 } 77 78 @Test testNestedContextnull79 fun testNestedContext() { 80 val state = perfStatusReporter.benchmarkState 81 82 val context1 = createCoroutineTracingContext("scope1") 83 val context2 = createCoroutineTracingContext("scope2") 84 runBlocking { 85 while (state.keepRunning()) { 86 withContext(context1) { 87 traceCoroutine("hello") { 88 traceCoroutine("world") { 89 withContext(context2) { 90 traceCoroutine("hallo") { 91 traceCoroutine("welt") { ensureSuspend(state) } 92 ensureSuspend(state) 93 } 94 } 95 ensureSuspend(state) 96 } 97 ensureSuspend(state) 98 } 99 } 100 } 101 } 102 } 103 104 @Test testInterleavedLaunchnull105 fun testInterleavedLaunch() { 106 val state = perfStatusReporter.benchmarkState 107 108 runBlocking(createCoroutineTracingContext("root")) { 109 val job1 = 110 launchTraced("scope1") { 111 while (true) { 112 traceCoroutine("hello") { 113 traceCoroutine("world") { yield() } 114 yield() 115 } 116 } 117 } 118 val job2 = 119 launchTraced("scope2") { 120 while (true) { 121 traceCoroutine("hallo") { 122 traceCoroutine("welt") { yield() } 123 yield() 124 } 125 } 126 } 127 while (state.keepRunning()) { 128 repeat(10_000) { traceCoroutine("main-loop") { yield() } } 129 } 130 job1.cancel() 131 job2.cancel() 132 } 133 } 134 } 135