From a3d41ee17669084489bbecd3262658834f43541c Mon Sep 17 00:00:00 2001 From: Ryan Prichard Date: Wed, 7 Oct 2020 16:32:27 -0700 Subject: [PATCH] Add __cxa_atexit benchmark The benchmark calls __cxa_atexit 100000 times, then either exits early without calling the destructors (_Exit) or exits normally, calling them (exit). Test: mmma bionic/benchmarks/spawn Change-Id: I41fe702d6ef11acb7a1dec95bf546b5dc693bd4a --- benchmarks/spawn/Android.bp | 28 +++++++---- benchmarks/spawn/bench_cxa_atexit.cpp | 67 +++++++++++++++++++++++++++ benchmarks/spawn/spawn_benchmarks.cpp | 2 + 3 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 benchmarks/spawn/bench_cxa_atexit.cpp diff --git a/benchmarks/spawn/Android.bp b/benchmarks/spawn/Android.bp index 2276d2e01..689e7c924 100644 --- a/benchmarks/spawn/Android.bp +++ b/benchmarks/spawn/Android.bp @@ -68,6 +68,7 @@ cc_benchmark { // Install these binaries in the same directory as the main benchmark binary. data: [ + ":bench_cxa_atexit", ":bench_noop", ":bench_noop_nostl", ":bench_noop_static", @@ -75,7 +76,7 @@ cc_benchmark { } cc_defaults { - name: "noop_binary_defaults", + name: "bionic_spawn_benchmark_binary", defaults: ["bionic_spawn_benchmark_targets"], compile_multilib: "both", @@ -87,16 +88,11 @@ cc_defaults { suffix: "64", }, }, -} - -cc_binary { - defaults: ["noop_binary_defaults"], - name: "bench_noop", - srcs: ["noop.cpp"], // When this binary is installed to host/linux-x86/bin, its runpath is ${ORIGIN}/../lib64, which // is fine for finding host/linux-x86/lib64/libc++.so. When it's installed to - // host/linux-x86/benchmarktest64/bionic-spawn-benchmarks, the runpath needs an extra "..". + // host/linux-x86/benchmarktest64/bionic-spawn-benchmarks, the runpath needs an extra "..". This + // argument has no effect when a static executable is produced. target: { linux_glibc_x86_64: { ldflags: [ @@ -107,14 +103,26 @@ cc_binary { } cc_binary { - defaults: ["noop_binary_defaults"], + defaults: ["bionic_spawn_benchmark_binary"], + name: "bench_cxa_atexit", + srcs: ["bench_cxa_atexit.cpp"], +} + +cc_binary { + defaults: ["bionic_spawn_benchmark_binary"], + name: "bench_noop", + srcs: ["noop.cpp"], +} + +cc_binary { + defaults: ["bionic_spawn_benchmark_binary"], name: "bench_noop_nostl", srcs: ["noop.cpp"], stl: "none", } cc_binary { - defaults: ["noop_binary_defaults"], + defaults: ["bionic_spawn_benchmark_binary"], name: "bench_noop_static", srcs: ["noop.cpp"], static_executable: true, diff --git a/benchmarks/spawn/bench_cxa_atexit.cpp b/benchmarks/spawn/bench_cxa_atexit.cpp new file mode 100644 index 000000000..95849f407 --- /dev/null +++ b/benchmarks/spawn/bench_cxa_atexit.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include + +extern "C" int __cxa_atexit(void (*func)(void*), void* arg, void* dso); + +extern void* __dso_handle; + +static void dtor_func(void*) {} + +// Prevent the compiler from optimizing out the __cxa_atexit call. +void (*volatile g_pdtor_func)(void*) = dtor_func; + +int main(int argc, char* argv[]) { + auto usage = [&argv]() { + fprintf(stderr, "usage: %s COUNT MODE\n", argv[0]); + fprintf(stderr, "MODE is one of '_Exit' or 'exit'.\n"); + exit(1); + }; + + if (argc != 3) usage(); + + int count = atoi(argv[1]); + + // Two modes: "_Exit" ==> exit early w/o calling dtors, "exit" ==> call dtors on exit. + std::string mode = argv[2]; + if (mode != "_Exit" && mode != "exit") usage(); + + for (int i = 0; i < count; ++i) { + __cxa_atexit(g_pdtor_func, nullptr, &__dso_handle); + } + + if (mode == "_Exit") { + _Exit(0); + } else { + exit(0); + } +} diff --git a/benchmarks/spawn/spawn_benchmarks.cpp b/benchmarks/spawn/spawn_benchmarks.cpp index 931a8be5a..18dacf938 100644 --- a/benchmarks/spawn/spawn_benchmarks.cpp +++ b/benchmarks/spawn/spawn_benchmarks.cpp @@ -31,6 +31,8 @@ SPAWN_BENCHMARK(noop, test_program("bench_noop").c_str()); SPAWN_BENCHMARK(noop_nostl, test_program("bench_noop_nostl").c_str()); SPAWN_BENCHMARK(noop_static, test_program("bench_noop_static").c_str()); +SPAWN_BENCHMARK(bench_cxa_atexit, test_program("bench_cxa_atexit").c_str(), "100000", "_Exit"); +SPAWN_BENCHMARK(bench_cxa_atexit_full, test_program("bench_cxa_atexit").c_str(), "100000", "exit"); // Android has a /bin -> /system/bin symlink, but use /system/bin explicitly so we can more easily // compare Bionic-vs-glibc on a Linux desktop machine.