blob: 387e45d431bd1df54352ebe644bf823e87a035ec (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
#!/bin/bash
#
# Copyright 2019, 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.
DIR_IORAP_COMMON="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
APP_STARTUP_DIR="$DIR_IORAP_COMMON/../app_startup/"
source "$APP_STARTUP_DIR/lib/common"
IORAPD_DATA_PATH="/data/misc/iorapd"
iorapd_start() {
verbose_print 'iorapd_start'
adb shell start iorapd
sleep 1
# TODO: block until logcat prints successfully connecting
}
iorapd_stop() {
verbose_print 'iorapd_stop'
adb shell stop iorapd
}
iorapd_reset() {
iorapd_stop
iorapd_start
}
# Enable perfetto tracing.
# Subsequent launches of an application will record a perfetto trace protobuf.
iorapd_perfetto_enable() {
verbose_print 'enable perfetto'
adb shell setprop iorapd.perfetto.enable true
iorapd_reset # iorapd only reads this flag when initializing
}
# Disable perfetto tracing.
# Subsequent launches of applications will no longer record perfetto trace protobufs.
iorapd_perfetto_disable() {
verbose_print 'disable perfetto'
adb shell setprop iorapd.perfetto.enable false
iorapd_reset # iorapd only reads this flag when initializing
}
# Enable readahead
# Subsequent launches of an application will be sped up by iorapd readahead prefetching
# (Provided an appropriate compiled trace exists for that application)
iorapd_readahead_enable() {
if [[ "$(adb shell getprop iorapd.readahead.enable)" == true ]]; then
verbose_print 'enable readahead [already enabled]'
return 0
fi
verbose_print 'enable readahead [reset iorapd]'
adb shell setprop iorapd.readahead.enable true
iorapd_reset # iorapd only reads this flag when initializing
}
# Disable readahead
# Subsequent launches of an application will be not be sped up by iorapd readahead prefetching.
iorapd_readahead_disable() {
if [[ "$(adb shell getprop iorapd.readahead.enable)" == false ]]; then
verbose_print 'disable readahead [already disabled]'
return 0
fi
verbose_print 'disable readahead [reset iorapd]'
adb shell setprop iorapd.readahead.enable false
iorapd_reset # iorapd only reads this flag when initializing
}
_iorapd_path_to_data_file() {
local package="$1"
local activity="$2"
local suffix="$3"
# Match logic of 'AppComponentName' in iorap::compiler C++ code.
echo "${IORAPD_DATA_PATH}/${package}%2F${activity}.${suffix}"
}
iorapd_perfetto_wait_for_app_trace() {
local package="$1"
local activity="$2"
local timeout="$3"
local timestamp="$4"
local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
verbose_print "iorapd_perfetto_wait_for_app_trace on file '$remote_path'"
# see event_manager.cc
local pattern="Perfetto TraceBuffer saved to file: $remote_path"
logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
}
# Purge all perfetto traces for a given application.
iorapd_perfetto_purge_app_trace() {
local package="$1"
local activity="$2"
local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
verbose_print 'iorapd-perfetto: purge app trace in ' "$remote_path"
adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
}
# Pull the remote perfetto trace file into a local file.
iorapd_perfetto_pull_trace_file() {
local package="$1"
local activity="$2"
local output_file="$3" # local path
local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
if ! adb shell "[[ -f '$compiled_path' ]]"; then
echo "Error: Remote path '$compiled_path' invalid" >&2
return 1
fi
if ! mkdir -p "$(dirname "$output_file")"; then
echo "Error: Fail to make output directory for '$output_file'" >&2
return 1
fi
verbose_print adb pull "$compiled_path" "$output_file"
adb pull "$compiled_path" "$output_file"
}
# Compile a perfetto trace for a given application.
# This requires the app has run at least once with perfetto tracing enabled.
iorapd_compiler_for_app_trace() {
local package="$1"
local activity="$2"
local inodes="$3" # local path
# remote path calculations
local input_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.tmp.pb")"
local compiled_path_final="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
if ! adb shell "[[ -f '$input_path' ]]"; then
echo "Error: Missing perfetto traces; nothing to compile. Expected: '$input_path'" >&2
return 1
fi
if ! [[ -f $inodes ]]; then
# We could compile using 'diskscan' but it's non-deterministic, so refuse instead.
echo "Error: Missing inodes textcache at '$inodes'; refusing to compile." >&2
return 1
fi
# inodes file needs to be on the device for iorap.cmd.compiler to access it
local remote_inodes=/data/local/tmp/prefetch/inodes.txt
adb shell "mkdir -p \"$(dirname "$remote_inodes")\"" || return 1
verbose_print adb push "$inodes" "$remote_inodes"
adb push "$inodes" "$remote_inodes"
verbose_print 'iorapd-compiler: compile app trace in ' "$input_path"
verbose_print adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
retcode=$?
# Don't overwrite the true 'compiled_trace.pb' unless the compiler completed without error.
# TODO: The native compiler code should be handling its own transaction-safety.
if [[ $retcode -eq 0 ]]; then
adb shell "mv '$compiled_path' '$compiled_path_final'"
else
adb shell "[[ -f '$compiled_path' ]] && rm -f '$compiled_path'"
fi
# Clean up inodes file we just pushed.
# adb shell "[[ -f '$remote_inodes' ]] && rm -f '$remote_inodes'"
return $retcode
}
# Pull the remote compiled trace file into a local file.
iorapd_compiler_pull_trace_file() {
local package="$1"
local activity="$2"
local output_file="$3" # local path
local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
if ! adb shell "[[ -f '$compiled_path' ]]"; then
echo "Error: Remote path '$compiled_path' invalid" >&2
return 1
fi
if ! mkdir -p "$(dirname "$output_file")"; then
echo "Error: Fail to make output directory for '$output_file'" >&2
return 1
fi
verbose_print adb pull "$compiled_path" "$output_file"
adb pull "$compiled_path" "$output_file"
}
# Install a compiled trace file.
iorapd_compiler_install_trace_file() {
local package="$1"
local activity="$2"
local input_file="$3" # local path
# remote path calculations
local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
if ! [[ -f $input_file ]]; then
echo "Error: File '$input_file' does not exist." >&2
return 1
fi
adb shell "mkdir -p \"$(dirname "$compiled_path")\"" || return 1
verbose_print adb push "$input_file" "$compiled_path"
adb push "$input_file" "$compiled_path"
}
iorapd_compiler_purge_trace_file() {
local package="$1"
local activity="$2"
local input_file="$3" # local path
local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
}
# Blocks until the readahead for the requested package/activity has finished.
# This assumes that the trace file was already installed, and also that
# the application launched but not completed yet.
iorapd_readahead_wait_until_finished() {
local package="$1"
local activity="$2"
local timestamp="$3"
local timeout="$4"
if [[ $# -lt 4 ]]; then
echo "FATAL: Expected 4 arguments (actual $# $@)" >&2
exit 1
fi
local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
# See 'read_ahead.cc' LOG(INFO).
local pattern="Description = $remote_path"
logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
}
|