Switch bionic over to google-benchmark.
Also removes the old benchmarking library.
Change-Id: I4791ae69fa5dea03644d3d411c60b7c6d1fceae3
diff --git a/benchmarks/semaphore_benchmark.cpp b/benchmarks/semaphore_benchmark.cpp
index 8dd5684..d260803 100644
--- a/benchmarks/semaphore_benchmark.cpp
+++ b/benchmarks/semaphore_benchmark.cpp
@@ -18,101 +18,112 @@
#include <semaphore.h>
#include <stdatomic.h>
#include <stdio.h>
+#include <stdlib.h>
-#include <benchmark/Benchmark.h>
+#include <benchmark/benchmark.h>
-BENCHMARK_NO_ARG(BM_semaphore_sem_getvalue);
-void BM_semaphore_sem_getvalue::Run(int iters) {
- StopBenchmarkTiming();
+static void BM_semaphore_sem_getvalue(benchmark::State& state) {
sem_t semaphore;
sem_init(&semaphore, 1, 1);
- StartBenchmarkTiming();
- for (int i = 0; i < iters; ++i) {
+ while (state.KeepRunning()) {
int dummy;
sem_getvalue(&semaphore, &dummy);
}
-
- StopBenchmarkTiming();
}
+BENCHMARK(BM_semaphore_sem_getvalue);
-BENCHMARK_NO_ARG(BM_semaphore_sem_wait_sem_post);
-void BM_semaphore_sem_wait_sem_post::Run(int iters) {
- StopBenchmarkTiming();
+static void BM_semaphore_sem_wait_sem_post(benchmark::State& state) {
sem_t semaphore;
sem_init(&semaphore, 1, 1);
- StartBenchmarkTiming();
- for (int i = 0; i < iters; ++i) {
+ while (state.KeepRunning()) {
sem_wait(&semaphore);
sem_post(&semaphore);
}
-
- StopBenchmarkTiming();
}
+BENCHMARK(BM_semaphore_sem_wait_sem_post);
-/*
- * This test reports the overhead of the underlying futex wake syscall on
- * the producer. It does not report the overhead from issuing the wake to the
- * point where the posted consumer thread wakes up. It suffers from
- * clock_gettime syscall overhead. Lock the CPU speed for consistent results
- * as we may not reach >50% cpu utilization.
- *
- * We will run a background thread that catches the sem_post wakeup and
- * loops immediately returning back to sleep in sem_wait for the next one. This
- * thread is run with policy SCHED_OTHER (normal policy), a middle policy.
- *
- * The primary thread will run at SCHED_IDLE (lowest priority policy) when
- * monitoring the background thread to detect when it hits sem_wait sleep. It
- * will do so with no clock running. Once we are ready, we will switch to
- * SCHED_FIFO (highest priority policy) to time the act of running sem_post
- * with the benchmark clock running. This ensures nothing else in the system
- * can preempt our timed activity, including the background thread. We are
- * also protected with the scheduling policy of letting a process hit a
- * resource limit rather than get hit with a context switch.
- *
- * The background thread will start executing either on another CPU, or
- * after we back down from SCHED_FIFO, but certainly not in the context of
- * the timing of the sem_post.
- */
+// This test reports the overhead of the underlying futex wake syscall on
+// the producer. It does not report the overhead from issuing the wake to the
+// point where the posted consumer thread wakes up. It suffers from
+// clock_gettime syscall overhead. Lock the CPU speed for consistent results
+// as we may not reach >50% cpu utilization.
+//
+// We will run a background thread that catches the sem_post wakeup and
+// loops immediately returning back to sleep in sem_wait for the next one. This
+// thread is run with policy SCHED_OTHER (normal policy), a middle policy.
+//
+// The primary thread will run at SCHED_IDLE (lowest priority policy) when
+// monitoring the background thread to detect when it hits sem_wait sleep. It
+// will do so with no clock running. Once we are ready, we will switch to
+// SCHED_FIFO (highest priority policy) to time the act of running sem_post
+// with the benchmark clock running. This ensures nothing else in the system
+// can preempt our timed activity, including the background thread. We are
+// also protected with the scheduling policy of letting a process hit a
+// resource limit rather than get hit with a context switch.
+//
+// The background thread will start executing either on another CPU, or
+// after we back down from SCHED_FIFO, but certainly not in the context of
+// the timing of the sem_post.
+
static atomic_int BM_semaphore_sem_post_running;
-static void *BM_semaphore_sem_post_start_thread(void *obj) {
- sem_t *semaphore = reinterpret_cast<sem_t *>(obj);
-
- while ((BM_semaphore_sem_post_running > 0) && !sem_wait(semaphore)) {
- ;
- }
- BM_semaphore_sem_post_running = -1;
- return NULL;
+static void* BM_semaphore_sem_post_start_thread(void* arg) {
+ sem_t* semaphore = reinterpret_cast<sem_t*>(arg);
+ while ((BM_semaphore_sem_post_running > 0) && !sem_wait(semaphore)) {
+ }
+ BM_semaphore_sem_post_running = -1;
+ return NULL;
}
-BENCHMARK_NO_ARG(BM_semaphore_sem_post);
-void BM_semaphore_sem_post::Run(int iters) {
- StopBenchmarkTiming();
+class SemaphoreFixture : public benchmark::Fixture {
+ public:
+ void SetUp(const benchmark::State&) {
+ sem_init(&semaphore, 0, 0);
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+
+ memset(¶m, 0, sizeof(param));
+ pthread_attr_setschedparam(&attr, ¶m);
+ pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_t pthread;
+ pthread_create(&pthread, &attr, BM_semaphore_sem_post_start_thread, &semaphore);
+ pthread_attr_destroy(&attr);
+
+ sched_setscheduler(0, SCHED_IDLE, ¶m);
+
+ BM_semaphore_sem_post_running = 1;
+ }
+
+ ~SemaphoreFixture() {
+ sched_setscheduler(0, SCHED_OTHER, ¶m);
+
+ if (BM_semaphore_sem_post_running > 0) {
+ BM_semaphore_sem_post_running = 0;
+ }
+ do {
+ sem_post(&semaphore);
+ sched_yield();
+ } while (BM_semaphore_sem_post_running != -1);
+ }
sem_t semaphore;
- sem_init(&semaphore, 0, 0);
+ sched_param param;
+};
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- BM_semaphore_sem_post_running = 1;
- struct sched_param param = { 0, };
- pthread_attr_setschedparam(&attr, ¶m);
- pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- pthread_t pthread;
- pthread_create(&pthread, &attr, BM_semaphore_sem_post_start_thread, &semaphore);
- pthread_attr_destroy(&attr);
+BENCHMARK_F(SemaphoreFixture, semaphore_sem_post)(benchmark::State& state) {
+ while (state.KeepRunning()) {
+ state.PauseTiming();
- sched_setscheduler((pid_t)0, SCHED_IDLE, ¶m);
- for (int i = 0; i < iters; ++i) {
int trys = 3, dummy = 0;
do {
if (BM_semaphore_sem_post_running < 0) {
- sched_setscheduler((pid_t)0, SCHED_OTHER, ¶m);
+ sched_setscheduler(0, SCHED_OTHER, ¶m);
fprintf(stderr, "BM_semaphore_sem_post: start_thread died unexpectedly\n");
- return;
+ abort();
}
sched_yield();
sem_getvalue(&semaphore, &dummy);
@@ -123,21 +134,14 @@
--trys;
}
} while (trys);
- param.sched_priority = 1;
- sched_setscheduler((pid_t)0, SCHED_FIFO, ¶m);
- StartBenchmarkTiming();
- sem_post(&semaphore);
- StopBenchmarkTiming(); // Remember to subtract clock syscall overhead
- param.sched_priority = 0;
- sched_setscheduler((pid_t)0, SCHED_IDLE, ¶m);
- }
- sched_setscheduler((pid_t)0, SCHED_OTHER, ¶m);
- if (BM_semaphore_sem_post_running > 0) {
- BM_semaphore_sem_post_running = 0;
- }
- do {
+ param.sched_priority = 1;
+ sched_setscheduler(0, SCHED_FIFO, ¶m);
+
+ state.ResumeTiming();
sem_post(&semaphore);
- sched_yield();
- } while (!BM_semaphore_sem_post_running);
+
+ param.sched_priority = 0;
+ sched_setscheduler(0, SCHED_IDLE, ¶m);
+ }
}