From 55629e0a1c05cd119d34bcbc1299782ae3967dac Mon Sep 17 00:00:00 2001
From: Hauke Petersen <hauke.petersen@fu-berlin.de>
Date: Wed, 20 Dec 2017 11:32:16 +0100
Subject: [PATCH] sys: added simple benchmark module

---
 Makefile.dep              |  4 +++
 sys/benchmark/Makefile    |  1 +
 sys/benchmark/benchmark.c | 32 +++++++++++++++++
 sys/include/benchmark.h   | 76 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 113 insertions(+)
 create mode 100644 sys/benchmark/Makefile
 create mode 100644 sys/benchmark/benchmark.c
 create mode 100644 sys/include/benchmark.h

diff --git a/Makefile.dep b/Makefile.dep
index 654daa430d..db9e356d9d 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -679,6 +679,10 @@ ifneq (,$(filter fatfs_vfs,$(USEMODULE)))
   USEMODULE += vfs
 endif
 
+ifneq (,$(filter benchmark,$(USEMODULE)))
+  USEMODULE += xtimer
+endif
+
 # always select gpio (until explicit dependencies are sorted out)
 FEATURES_OPTIONAL += periph_gpio
 
diff --git a/sys/benchmark/Makefile b/sys/benchmark/Makefile
new file mode 100644
index 0000000000..48422e909a
--- /dev/null
+++ b/sys/benchmark/Makefile
@@ -0,0 +1 @@
+include $(RIOTBASE)/Makefile.base
diff --git a/sys/benchmark/benchmark.c b/sys/benchmark/benchmark.c
new file mode 100644
index 0000000000..e9d0e50da0
--- /dev/null
+++ b/sys/benchmark/benchmark.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Freie Universität Berlin
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser General
+ * Public License v2.1. See the file LICENSE in the top level directory for more
+ * details.
+ */
+
+/**
+ * @ingroup     sys_benchmark
+ * @{
+ *
+ * @file
+ * @brief       Utility functions for the benchmark module
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ *
+ * @}
+ */
+
+#include <stdio.h>
+
+#include "benchmark.h"
+
+void benchmark_print_time(uint32_t time, unsigned long runs, const char *name)
+{
+    uint32_t full = (time / runs);
+    uint32_t div  = (time - (full * runs)) / (runs / 1000);
+
+    printf("%11s: %9" PRIu32 "us  ---  %2" PRIu32 ".%03" PRIu32 "us per call\n",
+           name, time, full, div);
+}
diff --git a/sys/include/benchmark.h b/sys/include/benchmark.h
new file mode 100644
index 0000000000..9a321a3d4d
--- /dev/null
+++ b/sys/include/benchmark.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 Freie Universität Berlin
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @defgroup    sys_benchmark Benchmark
+ * @ingroup     sys
+ * @brief       Framework for running simple runtime benchmarks
+ * @{
+ *
+ * @file
+ * @brief       Interface for running simple benchmarks
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ */
+
+#ifndef BENCHMARK_H
+#define BENCHMARK_H
+
+#include <stdint.h>
+
+#include "xtimer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Prepare the current scope for running BENCHMARK_x() macros
+ */
+#define BENCHMARK_SETUP()                       \
+    unsigned state;                             \
+    unsigned time
+
+/**
+ * @brief   Measure the runtime of a given function call
+ *
+ * As we are doing a time sensitive measurement here, there is no way around
+ * using a preprocessor function, as going with a function pointer or similar
+ * would influence the measured runtime...
+ *
+ * @note    BENCHMARK_SETUP() needs to be called in the same scope
+ *
+ * @param[in] name      name for labeling the output
+ * @param[in] runs      number of times to run @p func
+ * @param[in] func      function call to benchmark
+ */
+#define BENCHMARK_FUNC(name, runs, func)        \
+    state = irq_disable();                      \
+    time = xtimer_now_usec();                   \
+    for (unsigned long i = 0; i < runs; i++) {  \
+        func;                                   \
+    }                                           \
+    time = (xtimer_now_usec() - time);          \
+    irq_restore(state);                         \
+    benchmark_print_time(time, runs, name)
+
+/**
+ * @brief   Output the given time as well as the time per run on STDIO
+ *
+ * @param[in] time      overall runtime in us
+ * @param[in] runs      number of runs
+ * @param[in] name      name to label the output
+ */
+void benchmark_print_time(uint32_t time, unsigned long runs, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BENCHMARK_H */
+/** @} */
-- 
GitLab