12cf561722c2661cc0d4db502a44a3021609f307eRobin Lee/* 22cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * Copyright (C) 2016 The Android Open Source Project 32cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * 42cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * Licensed under the Apache License, Version 2.0 (the "License"); 52cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * you may not use this file except in compliance with the License. 62cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * You may obtain a copy of the License at 72cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * 82cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * http://www.apache.org/licenses/LICENSE-2.0 92cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * 102cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * Unless required by applicable law or agreed to in writing, software 112cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * distributed under the License is distributed on an "AS IS" BASIS, 122cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * See the License for the specific language governing permissions and 142cf561722c2661cc0d4db502a44a3021609f307eRobin Lee * limitations under the License. 152cf561722c2661cc0d4db502a44a3021609f307eRobin Lee */ 162cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 172cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#define LOG_TAG "connect_benchmark" 182cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 19711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee/* 20711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * See README.md for general notes. 21711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 22711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * This set of benchmarks measures the throughput of connect() calls on a single thread for IPv4 and 23711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * IPv6 under the following scenarios: 24711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 25711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * - FWmark disabled (::ANDROID_NO_USE_FWMARK_CLIENT). 26711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 27711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * The control case for other high load benchmarks. Essentially just testing performance of 28711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * the kernel connect call. In real world use fwmark should stay on in order for traffic to 29711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * be routed properly. 30711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 31711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * - FWmark enabled only for metrics (::ANDROID_FWMARK_METRICS_ONLY). 32711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 33711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * The default mode up to and including 7.1. Every time connect() is called on an AF_INET or 34711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * AF_INET6 socket, netdclient sends a synchronous message to fwmarkserver to get the socket 35711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * marked. Only the fields that are useful for marking or for metrics are sent in this mode; 36711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * other fields are set to null for the RPC and ignored. 37711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 38711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * - FWmark enabled for all events. 39711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 40711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * The default mode starting from 7.1.2. As well as the normal connect() reporting, extra 41711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * fields are filled in to log the IP and port of the connection. 42711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 43711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * A second synchronous message is sent to fwmarkserver after the connection completes, to 44711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * record latency. This message is forwarded to the system server over a oneway binder call. 45711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 46711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * Realtime timed tests 47711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * ==================== 48711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 49711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * The tests named *_high_load record the following useful information: 50711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 51711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * - real_time: the mean roundtrip time for one connect() call under load 52711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 53711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * - iterations: the number of times the test was run within the timelimit --- approximately 54711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * MinTime / real_time 55711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 56711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * Manually timed tests 57711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * ==================== 58711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 59711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * All other sets of tests apart from *_high_load run with manual timing. The purpose of these is to 60711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * measure 90th-percentile latency for connect() calls compared to mean latency. 61711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 62711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * (TODO: ideally this should be against median latency, but google-benchmark only supports one 63711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * custom 'label' output for graphing. Stddev isn't appropriate because the latency 64711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * distribution is usually spiky, not in a nice neat normal-like distribution.) 65711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 66711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * The manually timed tests record the following useful information: 67711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 68711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * - real_time: the average time taken to complete a test run. Unlike the real_time used in high 69711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * load tests, this is calculated from before-and-after values of the realtime clock 70711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * over many iterations so may be less accurate than the under-load times. 71711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 72711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * - iterations: the number of times the test was run within the timelimit --- approximately 73711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * MinTime / real_time, although as explained, may not be as meaningful because of 74711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * overhead from timing. 75711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 76711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * - label: a manually-recorded time giving the 90th-percentile value of real_time over all 77711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * individual runs. Should be compared to real_time. 78711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee * 79711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee */ 80711237cfb696a1a2fd91c34f0bd01711e08cd70fRobin Lee 812cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <arpa/inet.h> 822cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <cutils/sockets.h> 832cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <errno.h> 842cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <netinet/in.h> 852cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <time.h> 862cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 872cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <map> 882cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <functional> 892cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <thread> 902cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 912cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <android-base/stringprintf.h> 922cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <benchmark/benchmark.h> 932cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <log/log.h> 942cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include <utils/StrongPointer.h> 952cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 962cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include "FwmarkClient.h" 972cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include "SockDiag.h" 982cf561722c2661cc0d4db502a44a3021609f307eRobin Lee#include "Stopwatch.h" 99d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski#include "android/net/metrics/INetdEventListener.h" 1002cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1012cf561722c2661cc0d4db502a44a3021609f307eRobin Leeusing android::base::StringPrintf; 102d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinskiusing android::net::metrics::INetdEventListener; 1032cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1042cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic int bindAndListen(int s) { 1052cf561722c2661cc0d4db502a44a3021609f307eRobin Lee sockaddr_in6 sin6 = { .sin6_family = AF_INET6 }; 1062cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (bind(s, (sockaddr*) &sin6, sizeof(sin6)) == 0) { 1072cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (listen(s, 1)) { 1082cf561722c2661cc0d4db502a44a3021609f307eRobin Lee return -1; 1092cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1102cf561722c2661cc0d4db502a44a3021609f307eRobin Lee sockaddr_in sin = {}; 1112cf561722c2661cc0d4db502a44a3021609f307eRobin Lee socklen_t len = sizeof(sin); 1122cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (getsockname(s, (sockaddr*) &sin, &len)) { 1132cf561722c2661cc0d4db502a44a3021609f307eRobin Lee return -1; 1142cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1152cf561722c2661cc0d4db502a44a3021609f307eRobin Lee return ntohs(sin.sin_port); 1162cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } else { 1172cf561722c2661cc0d4db502a44a3021609f307eRobin Lee return -1; 1182cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1192cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 1202cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1212cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_loopback(benchmark::State& state, const bool waitBetweenRuns) { 1222cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const int listensocket = socket(AF_INET6, SOCK_STREAM, 0); 1232cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const int port = bindAndListen(listensocket); 1242cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (port == -1) { 1252cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SkipWithError("Unable to bind server socket"); 1262cf561722c2661cc0d4db502a44a3021609f307eRobin Lee return; 1272cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1282cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1292cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // ALOGW("Listening on port = %d", port); 1302cf561722c2661cc0d4db502a44a3021609f307eRobin Lee std::vector<uint64_t> latencies(state.max_iterations); 1312cf561722c2661cc0d4db502a44a3021609f307eRobin Lee uint64_t iterations = 0; 1322cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1332cf561722c2661cc0d4db502a44a3021609f307eRobin Lee while (state.KeepRunning()) { 1342cf561722c2661cc0d4db502a44a3021609f307eRobin Lee int sock = socket(AF_INET, SOCK_STREAM, 0); 1352cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (sock < 0) { 1362cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SkipWithError(StringPrintf("socket() failed with errno=%d", errno).c_str()); 1372cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 1382cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1392cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1402cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const Stopwatch stopwatch; 1412cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1422cf561722c2661cc0d4db502a44a3021609f307eRobin Lee sockaddr_in server = { .sin_family = AF_INET, .sin_port = htons(port) }; 143e65244b5a149fc8be8063ee0872f31b829bfa020Robin Lee if (connect(sock, (sockaddr*) &server, sizeof(server))) { 1442cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SkipWithError(StringPrintf("connect() failed with errno=%d", errno).c_str()); 1452cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(sock); 1462cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 1472cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1482cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1492cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (waitBetweenRuns) { 1502cf561722c2661cc0d4db502a44a3021609f307eRobin Lee latencies[iterations] = stopwatch.timeTaken() * 1e6L; 1512cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SetIterationTime(latencies[iterations] / 1e9L); 1522cf561722c2661cc0d4db502a44a3021609f307eRobin Lee std::this_thread::sleep_for(std::chrono::milliseconds(10)); 1532cf561722c2661cc0d4db502a44a3021609f307eRobin Lee ++iterations; 1542cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1552cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1562cf561722c2661cc0d4db502a44a3021609f307eRobin Lee sockaddr_in6 client; 1572cf561722c2661cc0d4db502a44a3021609f307eRobin Lee socklen_t clientlen = sizeof(client); 1582cf561722c2661cc0d4db502a44a3021609f307eRobin Lee int accepted = accept(listensocket, (sockaddr *) &client, &clientlen); 1592cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (accepted < 0) { 1602cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SkipWithError(StringPrintf("accept() failed with errno=%d", errno).c_str()); 1612cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(sock); 1622cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 1632cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1642cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1652cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(accepted); 1662cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(sock); 1672cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1682cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(listensocket); 1692cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // ALOGI("Finished test on port = %d", port); 1702cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1712cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (iterations > 0) { 1722cf561722c2661cc0d4db502a44a3021609f307eRobin Lee latencies.resize(iterations); 1732cf561722c2661cc0d4db502a44a3021609f307eRobin Lee sort(latencies.begin(), latencies.end()); 17403d6f38a0cb947f1576df3a73338852de00ea6cdChih-hung Hsieh state.SetLabel(StringPrintf("%lld", (long long) latencies[iterations * 9 / 10])); 1752cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1762cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 1772cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1782cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_loopback(benchmark::State& state, const bool waitBetweenRuns) { 1792cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const int listensocket = socket(AF_INET6, SOCK_STREAM, 0); 1802cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const int port = bindAndListen(listensocket); 1812cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (port == -1) { 1822cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SkipWithError("Unable to bind server socket"); 1832cf561722c2661cc0d4db502a44a3021609f307eRobin Lee return; 1842cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1852cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1862cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // ALOGW("Listening on port = %d", port); 1872cf561722c2661cc0d4db502a44a3021609f307eRobin Lee std::vector<uint64_t> latencies(state.max_iterations); 1882cf561722c2661cc0d4db502a44a3021609f307eRobin Lee uint64_t iterations = 0; 1892cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1902cf561722c2661cc0d4db502a44a3021609f307eRobin Lee while (state.KeepRunning()) { 1912cf561722c2661cc0d4db502a44a3021609f307eRobin Lee int sock = socket(AF_INET6, SOCK_STREAM, 0); 1922cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (sock < 0) { 1932cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SkipWithError(StringPrintf("socket() failed with errno=%d", errno).c_str()); 1942cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 1952cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 1962cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1972cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const Stopwatch stopwatch; 1982cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 1992cf561722c2661cc0d4db502a44a3021609f307eRobin Lee sockaddr_in6 server = { .sin6_family = AF_INET6, .sin6_port = htons(port) }; 200e65244b5a149fc8be8063ee0872f31b829bfa020Robin Lee if (connect(sock, (sockaddr*) &server, sizeof(server))) { 2012cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SkipWithError(StringPrintf("connect() failed with errno=%d", errno).c_str()); 2022cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(sock); 2032cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 2042cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2052cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2062cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (waitBetweenRuns) { 2072cf561722c2661cc0d4db502a44a3021609f307eRobin Lee latencies[iterations] = stopwatch.timeTaken() * 1e6L; 2082cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SetIterationTime(latencies[iterations] / 1e9L); 2092cf561722c2661cc0d4db502a44a3021609f307eRobin Lee std::this_thread::sleep_for(std::chrono::milliseconds(10)); 2102cf561722c2661cc0d4db502a44a3021609f307eRobin Lee ++iterations; 2112cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2122cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2132cf561722c2661cc0d4db502a44a3021609f307eRobin Lee sockaddr_in6 client; 2142cf561722c2661cc0d4db502a44a3021609f307eRobin Lee socklen_t clientlen = sizeof(client); 2152cf561722c2661cc0d4db502a44a3021609f307eRobin Lee int accepted = accept(listensocket, (sockaddr *) &client, &clientlen); 2162cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (accepted < 0) { 2172cf561722c2661cc0d4db502a44a3021609f307eRobin Lee state.SkipWithError(StringPrintf("accept() failed with errno=%d", errno).c_str()); 2182cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(sock); 2192cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 2202cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2212cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2222cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(accepted); 2232cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(sock); 2242cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2252cf561722c2661cc0d4db502a44a3021609f307eRobin Lee close(listensocket); 2262cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // ALOGI("Finished test on port = %d", port); 2272cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2282cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (iterations > 0) { 2292cf561722c2661cc0d4db502a44a3021609f307eRobin Lee latencies.resize(iterations); 2302cf561722c2661cc0d4db502a44a3021609f307eRobin Lee sort(latencies.begin(), latencies.end()); 23103d6f38a0cb947f1576df3a73338852de00ea6cdChih-hung Hsieh state.SetLabel(StringPrintf("%lld", (long long) latencies[iterations * 9 / 10])); 2322cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2332cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 2342cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2352cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void run_at_reporting_level(decltype(ipv4_loopback) benchmarkFunction, 236d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski ::benchmark::State& state, const int reportingLevel, 2372cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const bool waitBetweenRuns) { 2382cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // Our master thread (thread_index == 0) will control setup and teardown for other threads. 2392cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const bool isMaster = (state.thread_index == 0); 2402cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2412cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // Previous values of env variables used by fwmarkclient (only read/written by master thread) 2422cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const std::string savedSettings[] = { 2432cf561722c2661cc0d4db502a44a3021609f307eRobin Lee FwmarkClient::ANDROID_NO_USE_FWMARK_CLIENT, 2442cf561722c2661cc0d4db502a44a3021609f307eRobin Lee FwmarkClient::ANDROID_FWMARK_METRICS_ONLY 2452cf561722c2661cc0d4db502a44a3021609f307eRobin Lee }; 2462cf561722c2661cc0d4db502a44a3021609f307eRobin Lee std::map<std::string, std::string> prevSettings; 2472cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2482cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // SETUP 2492cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (isMaster) { 2502cf561722c2661cc0d4db502a44a3021609f307eRobin Lee for (const auto setting : savedSettings) { 2512cf561722c2661cc0d4db502a44a3021609f307eRobin Lee const char* prevEnvStr = getenv(setting.c_str()); 2522cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (prevEnvStr != nullptr) { 2532cf561722c2661cc0d4db502a44a3021609f307eRobin Lee prevSettings[setting.c_str()] = prevEnvStr; 2542cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2552cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2562cf561722c2661cc0d4db502a44a3021609f307eRobin Lee switch (reportingLevel) { 257d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski case INetdEventListener::REPORTING_LEVEL_NONE: 2582cf561722c2661cc0d4db502a44a3021609f307eRobin Lee setenv(FwmarkClient::ANDROID_NO_USE_FWMARK_CLIENT, "", 1); 2592cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 260d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski case INetdEventListener::REPORTING_LEVEL_METRICS: 2612cf561722c2661cc0d4db502a44a3021609f307eRobin Lee unsetenv(FwmarkClient::ANDROID_NO_USE_FWMARK_CLIENT); 2622cf561722c2661cc0d4db502a44a3021609f307eRobin Lee setenv(FwmarkClient::ANDROID_FWMARK_METRICS_ONLY, "", 1); 2632cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 264d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski case INetdEventListener::REPORTING_LEVEL_FULL: 2652cf561722c2661cc0d4db502a44a3021609f307eRobin Lee unsetenv(FwmarkClient::ANDROID_NO_USE_FWMARK_CLIENT); 2662cf561722c2661cc0d4db502a44a3021609f307eRobin Lee unsetenv(FwmarkClient::ANDROID_FWMARK_METRICS_ONLY); 2672cf561722c2661cc0d4db502a44a3021609f307eRobin Lee break; 2682cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2692cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2702cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2712cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // TEST 2722cf561722c2661cc0d4db502a44a3021609f307eRobin Lee benchmarkFunction(state, waitBetweenRuns); 2732cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2742cf561722c2661cc0d4db502a44a3021609f307eRobin Lee // TEARDOWN 2752cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (isMaster) { 2762cf561722c2661cc0d4db502a44a3021609f307eRobin Lee for (const auto setting : savedSettings) { 2772cf561722c2661cc0d4db502a44a3021609f307eRobin Lee if (prevSettings.count(setting)) { 2782cf561722c2661cc0d4db502a44a3021609f307eRobin Lee setenv(setting.c_str(), prevSettings[setting].c_str(), 1); 2792cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } else { 2802cf561722c2661cc0d4db502a44a3021609f307eRobin Lee unsetenv(setting.c_str()); 2812cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2822cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2832cf561722c2661cc0d4db502a44a3021609f307eRobin Lee } 2842cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 2852cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2862cf561722c2661cc0d4db502a44a3021609f307eRobin Leeconstexpr int MIN_THREADS = 1; 2872cf561722c2661cc0d4db502a44a3021609f307eRobin Leeconstexpr int MAX_THREADS = 1; 2882cf561722c2661cc0d4db502a44a3021609f307eRobin Leeconstexpr double MIN_TIME = 0.5 /* seconds */; 2892cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2902cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_metrics_reporting_no_fwmark(::benchmark::State& state) { 291d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_NONE, true); 2922cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 2932cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_metrics_reporting_no_fwmark)->MinTime(MIN_TIME)->UseManualTime(); 2942cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 2952cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv4 metrics under low load 2962cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_metrics_reporting_no_load(::benchmark::State& state) { 297d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_METRICS, true); 2982cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 2992cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_metrics_reporting_no_load)->MinTime(MIN_TIME)->UseManualTime(); 3002cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 3012cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_full_reporting_no_load(::benchmark::State& state) { 302d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_FULL, true); 3032cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 3042cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_full_reporting_no_load)->MinTime(MIN_TIME)->UseManualTime(); 3052cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 3062cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv4 benchmarks under high load 3072cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_metrics_reporting_high_load(::benchmark::State& state) { 308d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_METRICS, 309d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski false); 3102cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 3112cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_metrics_reporting_high_load) 3122cf561722c2661cc0d4db502a44a3021609f307eRobin Lee ->ThreadRange(MIN_THREADS, MAX_THREADS)->MinTime(MIN_TIME)->UseRealTime(); 3132cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 3142cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv4_full_reporting_high_load(::benchmark::State& state) { 315d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv4_loopback, state, INetdEventListener::REPORTING_LEVEL_FULL, false); 3162cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 3172cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv4_full_reporting_high_load) 3182cf561722c2661cc0d4db502a44a3021609f307eRobin Lee ->ThreadRange(MIN_THREADS, MAX_THREADS)->MinTime(MIN_TIME)->UseRealTime(); 3192cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 3202cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv6 raw connect() without using fwmark 3212cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_metrics_reporting_no_fwmark(::benchmark::State& state) { 322d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_NONE, true); 3232cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 3242cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_metrics_reporting_no_fwmark)->MinTime(MIN_TIME)->UseManualTime(); 3252cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 3262cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv6 metrics under low load 3272cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_metrics_reporting_no_load(::benchmark::State& state) { 328d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_METRICS, true); 3292cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 3302cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_metrics_reporting_no_load)->MinTime(MIN_TIME)->UseManualTime(); 3312cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 3322cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_full_reporting_no_load(::benchmark::State& state) { 333d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_FULL, true); 3342cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 3352cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_full_reporting_no_load)->MinTime(MIN_TIME)->UseManualTime(); 3362cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 3372cf561722c2661cc0d4db502a44a3021609f307eRobin Lee// IPv6 benchmarks under high load 3382cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_metrics_reporting_high_load(::benchmark::State& state) { 339d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_METRICS, 340d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski false); 3412cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 3422cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_metrics_reporting_high_load) 3432cf561722c2661cc0d4db502a44a3021609f307eRobin Lee ->ThreadRange(MIN_THREADS, MAX_THREADS)->MinTime(MIN_TIME)->UseRealTime(); 3442cf561722c2661cc0d4db502a44a3021609f307eRobin Lee 3452cf561722c2661cc0d4db502a44a3021609f307eRobin Leestatic void ipv6_full_reporting_high_load(::benchmark::State& state) { 346d46aa71fdad655f9dc2e33e0fbb96a776a55d095Michal Karpinski run_at_reporting_level(ipv6_loopback, state, INetdEventListener::REPORTING_LEVEL_FULL, false); 3472cf561722c2661cc0d4db502a44a3021609f307eRobin Lee} 3482cf561722c2661cc0d4db502a44a3021609f307eRobin LeeBENCHMARK(ipv6_full_reporting_high_load) 3492cf561722c2661cc0d4db502a44a3021609f307eRobin Lee ->ThreadRange(MIN_THREADS, MAX_THREADS)->MinTime(MIN_TIME)->UseRealTime(); 350