15a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#!/usr/bin/env python
25a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
35a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# Copyright (C) 2015 The Android Open Source Project
45a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#
55a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# Licensed under the Apache License, Version 2.0 (the 'License');
65a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# you may not use this file except in compliance with the License.
75a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# You may obtain a copy of the License at
85a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#
95a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#      http://www.apache.org/licenses/LICENSE-2.0
105a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#
115a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# Unless required by applicable law or agreed to in writing, software
125a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# distributed under the License is distributed on an 'AS IS' BASIS,
135a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# See the License for the specific language governing permissions and
155a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey# limitations under the License.
165a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
175a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey"""
185a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff SharkeyGenerates storage benchmark from captured strace output.
195a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
205a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff SharkeyCurrently assumes that all mmap'ed regions are resource accesses, and emulates as pread().
215a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
225a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff SharkeyUsage:
235a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey$ adb shell strace -p `pid zygote` -o /data/local/tmp/trace -f -ff -y -ttt -e trace=file,desc,munmap
245a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey$ adb pull /data/local/tmp/trace*
255a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey$ python benchgen.py trace.*
265a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
275a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey"""
285a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
295a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyimport re, sys, collections, traceback, argparse
305a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
315a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyfrom operator import itemgetter
325a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyfrom collections import defaultdict
335a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
345a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyclass Event:
355a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    def __init__(self, thread, time, call, args, ret):
365a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        self.thread = thread
375a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        self.time = time
385a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        self.call = call
395a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        self.args = args
405a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        self.ret = ret
415a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
425a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    def __repr__(self):
435a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        return "%s(%s)=%s" % (self.call, repr(self.args), self.ret)
445a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
455a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
465a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyclass File:
475a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    def __init__(self, name, ident):
485a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        self.name = name
495a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        self.ident = ident
505a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        self.size = 0
515a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
525a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    def __repr__(self):
535a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        return self.name
545a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
555a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
565a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyevents = []
575a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyfiles = {}
585a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
595a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeydef find_file(name):
605a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    name = name.strip('<>"')
615a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    if name not in files:
625a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        files[name] = File(name, len(files))
635a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    return files[name]
645a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
655a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeydef extract_file(e, arg):
665a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    if "<" in arg:
675a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        fd, path = arg.split("<")
685a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        path = path.strip(">")
695a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        handle = "t%sf%s" % (e.thread, fd)
705a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        return (fd, find_file(path), handle)
715a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    else:
725a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        return (None, None, None)
735a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
745a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeydef parse_args(s):
755a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    args = []
765a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    arg = ""
775a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    esc = False
785a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    quot = False
795a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    for c in s:
805a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        if esc:
815a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            esc = False
825a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            arg += c
835a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            continue
845a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
855a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        if c == '"':
865a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if quot:
875a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                quot = False
885a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                continue
895a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            else:
905a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                quot = True
915a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                continue
925a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
935a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        if c == '\\':
945a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            esc = True
955a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            continue
965a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
975a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        if c == ',' and not quot:
985a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            args.append(arg.strip())
995a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            arg = ""
1005a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        else:
1015a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            arg += c
1025a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1035a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    args.append(arg.strip())
1045a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    return args
1055a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1065a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1075a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeybufsize = 1048576
1085a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyinteresting = ["mmap2","read","write","pread64","pwrite64","fsync","fdatasync","openat","close","lseek","_llseek"]
1095a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1105a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyre_event = re.compile(r"^([\d\.]+) (.+?)\((.+?)\) = (.+?)$")
1115a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyre_arg = re.compile(r'''((?:[^,"']|"[^"]*"|'[^']*')+)''')
1125a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyfor fn in sys.argv[1:]:
1135a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    with open(fn) as f:
1145a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        thread = int(fn.split(".")[-1])
1155a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        for line in f:
1165a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            line = re_event.match(line)
1175a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if not line: continue
1185a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1195a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            time, call, args, ret = line.groups()
1205a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if call not in interesting: continue
1215a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if "/data/" not in args: continue
1225a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1235a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            time = float(time)
1245a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            args = parse_args(args)
1255a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            events.append(Event(thread, time, call, args, ret))
1265a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1275a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1285a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeywith open("BenchmarkGen.h", 'w') as bench:
1295a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    print >>bench, """/*
1305a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * Copyright (C) 2015 The Android Open Source Project
1315a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey *
1325a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
1335a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * you may not use this file except in compliance with the License.
1345a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * You may obtain a copy of the License at
1355a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey *
1365a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
1375a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey *
1385a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
1395a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
1405a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1415a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * See the License for the specific language governing permissions and
1425a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * limitations under the License.
1435a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey */
1445a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1455a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1465a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey/******************************************************************
1475a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey * THIS CODE WAS GENERATED BY benchgen.py, DO NOT MODIFY DIRECTLY *
1485a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey ******************************************************************/
1495a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1505a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1517e128fbe212c64492afa98bfd6d7fab6f1956831Elliott Hughes#include <android-base/logging.h>
1525a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1535a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <stdlib.h>
1545a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <sys/types.h>
1555a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <sys/stat.h>
1565a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <sys/sendfile.h>
1575a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <fcntl.h>
1585a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1595a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <algorithm>
1605a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey#include <string>
1615a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
162d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey#include <Utils.h>
163d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey
1645a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeynamespace android {
1655a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeynamespace vold {
1665a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1675a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeystatic status_t BenchmarkRun() {
1685a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey"""
1695a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1705a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    print >>bench, "char* buf = (char*) malloc(%d);" % (bufsize)
1715a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1725a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    nread = 0
1735a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    nwrite = 0
1745a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    nsync = 0
1755a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    events = sorted(events, key=lambda e: e.time)
1765a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    active = set()
1775a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    defined = set()
1785a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    for e in events:
1795a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        if e.call == "openat":
1805a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.ret)
1815a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if f:
1825a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                active.add(handle)
1835a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                if handle not in defined:
1845a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                    print >>bench, "int ",
1855a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                    defined.add(handle)
1865a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, '%s = TEMP_FAILURE_RETRY(open("file%s", %s));' % (handle, f.ident, e.args[2])
1875a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1885a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "close":
1895a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
1905a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
1915a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                active.remove(handle)
1924e378be81e7775a7084983cb5dcc69189f7e1b11Elliott Hughes                print >>bench, 'close(%s);' % (handle)
1935a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1945a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "lseek":
1955a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
1965a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
1975a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(lseek(%s, %s, %s));' % (handle, e.args[1], e.args[2])
1985a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
1995a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "_llseek":
2005a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
2015a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
2025a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(lseek(%s, %s, %s));' % (handle, e.args[1], e.args[3])
2035a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2045a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "read":
2055a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
2065a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
2075a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                # TODO: track actual file size instead of guessing
2085a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                count = min(int(e.args[2]), bufsize)
2095a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                f.size += count
2105a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(read(%s, buf, %d));' % (handle, count)
2115a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                nread += 1
2125a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2135a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "write":
2145a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
2155a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
2165a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                # TODO: track actual file size instead of guessing
2175a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                count = min(int(e.args[2]), bufsize)
2185a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                f.size += count
219f09a89a7d642699044802e6957b88073240674d2Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(write(%s, buf, %d));' % (handle, count)
2205a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                nwrite += 1
2215a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2225a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "pread64":
2235a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
2245a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
2255a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                f.size = max(f.size, int(e.args[2]) + int(e.args[3]))
2265a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                count = min(int(e.args[2]), bufsize)
2275a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(pread(%s, buf, %d, %s));' % (handle, count, e.args[3])
2285a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                nread += 1
2295a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2305a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "pwrite64":
2315a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
2325a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
2335a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                f.size = max(f.size, int(e.args[2]) + int(e.args[3]))
2345a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                count = min(int(e.args[2]), bufsize)
2355a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(pwrite(%s, buf, %d, %s));' % (handle, count, e.args[3])
2365a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                nwrite += 1
2375a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2385a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "fsync":
2395a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
2405a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
2415a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(fsync(%s));' % (handle)
2425a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                nsync += 1
2435a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2445a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "fdatasync":
2455a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[0])
2465a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
2475a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(fdatasync(%s));' % (handle)
2485a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                nsync += 1
2495a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2505a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        elif e.call == "mmap2":
2515a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            fd, f, handle = extract_file(e, e.args[4])
2525a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            if handle in active:
2535a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                count = min(int(e.args[1]), bufsize)
2545a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                offset = int(e.args[5], 0)
2555a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                f.size = max(f.size, count + offset)
2565a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                print >>bench, 'TEMP_FAILURE_RETRY(pread(%s, buf, %s, %s)); // mmap2' % (handle, count, offset)
2575a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey                nread += 1
2585a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2595a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    for handle in active:
2604e378be81e7775a7084983cb5dcc69189f7e1b11Elliott Hughes        print >>bench, 'close(%s);' % (handle)
2615a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2625a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    print >>bench, """
2635a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyfree(buf);
2645a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyreturn 0;
2655a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey}
2665a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
267d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkeystatic status_t CreateFile(const char* name, int len) {
268d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey    int chunk = std::min(len, 65536);
2695a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    int out = -1;
270d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey    std::string buf;
2715a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
272d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey    if (android::vold::ReadRandomBytes(chunk, buf) != OK) {
273d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey        LOG(ERROR) << "Failed to read random data";
274d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey        return -EIO;
2755a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    }
2765a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    if ((out = TEMP_FAILURE_RETRY(open(name, O_WRONLY|O_CREAT|O_TRUNC))) < 0) {
2775a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        PLOG(ERROR) << "Failed to open " << name;
278d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey        return -errno;
2795a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    }
2805a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2815a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    while (len > 0) {
282d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey        int n = write(out, buf.c_str(), std::min(len, chunk));
283d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey        if (n < 0) {
2845a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey            PLOG(ERROR) << "Failed to write";
285d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey            close(out);
286d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey            return -errno;
2875a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        }
2885a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        len -= n;
2895a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    }
2905a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2915a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    close(out);
292d46687ee5da7c9847c6188241ccc699d3a0826c2Jeff Sharkey    return OK;
2935a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey}
2945a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
2955a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeystatic status_t BenchmarkCreate() {
2965a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeystatus_t res = 0;
2975a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyres |= CreateFile("stub", 0);
2985a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey"""
2995a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    for f in files.values():
3005a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        print >>bench, 'res |= CreateFile("file%s", %d);' % (f.ident, f.size)
3015a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3025a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    print >>bench, """
3035a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyreturn res;
3045a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey}
3055a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3065a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeystatic status_t BenchmarkDestroy() {
3075a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeystatus_t res = 0;
3085a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyres |= unlink("stub");
3095a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey"""
3105a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    for f in files.values():
3115a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey        print >>bench, 'res |= unlink("file%s");' % (f.ident)
3125a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3135a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    print >>bench, """
3145a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyreturn res;
3155a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey}
3165a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3175a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeystatic std::string BenchmarkIdent() {"""
3185a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    print >>bench, """return "r%d:w%d:s%d";""" % (nread, nwrite, nsync)
3195a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    print >>bench, """}
3205a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3215a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey}  // namespace vold
3225a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey}  // namespace android
3235a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey"""
3245a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3255a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3265a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeysize = sum([ f.size for f in files.values() ])
3275a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyprint "Found", len(files), "data files accessed, total size", (size/1024), "kB"
3285a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3295a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeytypes = defaultdict(int)
3305a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyfor e in events:
3315a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    types[e.call] += 1
3325a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3335a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyprint "Found syscalls:"
3345a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyfor t, n in types.iteritems():
3355a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey    print str(n).rjust(8), t
3365a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkey
3375a6bfca1638760b87cf64c5ffb48ff3557cc0563Jeff Sharkeyprint
338