diff options
Diffstat (limited to 'benchmarks/unistd_benchmark.cpp')
-rw-r--r-- | benchmarks/unistd_benchmark.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/benchmarks/unistd_benchmark.cpp b/benchmarks/unistd_benchmark.cpp index d697dfd52..f0a308959 100644 --- a/benchmarks/unistd_benchmark.cpp +++ b/benchmarks/unistd_benchmark.cpp @@ -14,9 +14,16 @@ * limitations under the License. */ +#include <errno.h> +#include <string.h> #include <sys/syscall.h> +#include <sys/types.h> +#include <sys/wait.h> #include <unistd.h> +#include <string> + +#include <android-base/stringprintf.h> #include <benchmark/benchmark.h> #include "util.h" @@ -28,3 +35,35 @@ BIONIC_TRIVIAL_BENCHMARK(BM_unistd_getpid_syscall, syscall(__NR_getpid)); BIONIC_TRIVIAL_BENCHMARK(BM_unistd_gettid, gettid()); #endif BIONIC_TRIVIAL_BENCHMARK(BM_unistd_gettid_syscall, syscall(__NR_gettid)); + +// Many native allocators have custom prefork and postfork functions. +// Measure the fork call to make sure nothing takes too long. +void BM_unistd_fork_call(benchmark::State& state) { + for (auto _ : state) { + pid_t pid; + if ((pid = fork()) == 0) { + // Sleep for a little while so that the parent is not interrupted + // right away when the process exits. + usleep(100); + _exit(1); + } + state.PauseTiming(); + if (pid == -1) { + std::string err = android::base::StringPrintf("Fork failed: %s", strerror(errno)); + state.SkipWithError(err.c_str()); + } + pid_t wait_pid = waitpid(pid, 0, 0); + if (wait_pid != pid) { + if (wait_pid == -1) { + std::string err = android::base::StringPrintf("waitpid call failed: %s", strerror(errno)); + state.SkipWithError(err.c_str()); + } else { + std::string err = android::base::StringPrintf( + "waitpid return an unknown pid, expected %d, actual %d", pid, wait_pid); + state.SkipWithError(err.c_str()); + } + } + state.ResumeTiming(); + } +} +BIONIC_BENCHMARK(BM_unistd_fork_call); |