Index: uspace/app/perf/Makefile
===================================================================
--- uspace/app/perf/Makefile	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ uspace/app/perf/Makefile	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -34,4 +34,5 @@
 
 SOURCES = \
+	benchlist.c \
 	perf.c \
 	ipc/ns_ping.c \
Index: uspace/app/perf/benchlist.c
===================================================================
--- uspace/app/perf/benchlist.c	(revision d5caf7922353a9ff31141de881200acc494919a3)
+++ uspace/app/perf/benchlist.c	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * Copyright (c) 2018 Vojtech Horky
+ * 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.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/** @addtogroup perf
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdlib.h>
+#include "benchlist.h"
+
+benchmark_t *benchmarks[] = {
+	&bench_malloc1,
+	&bench_malloc2,
+	&bench_ns_ping,
+	&bench_ping_pong
+};
+
+size_t benchmark_count = sizeof(benchmarks) / sizeof(benchmarks[0]);
+
+/** @}
+ */
Index: uspace/app/perf/benchlist.h
===================================================================
--- uspace/app/perf/benchlist.h	(revision d5caf7922353a9ff31141de881200acc494919a3)
+++ uspace/app/perf/benchlist.h	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/** @addtogroup perf
+ * @{
+ */
+/** @file
+ */
+
+#ifndef BENCHLIST_H_
+#define BENCHLIST_H_
+
+#include "perf.h"
+
+extern benchmark_t bench_malloc1;
+extern benchmark_t bench_malloc2;
+extern benchmark_t bench_ns_ping;
+extern benchmark_t bench_ping_pong;
+
+extern benchmark_t *benchmarks[];
+extern size_t benchmark_count;
+
+#endif
+
+/** @}
+ */
Index: uspace/app/perf/ipc/ns_ping.c
===================================================================
--- uspace/app/perf/ipc/ns_ping.c	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ uspace/app/perf/ipc/ns_ping.c	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -32,7 +32,8 @@
 #include <errno.h>
 #include <str_error.h>
+#include "../benchlist.h"
 #include "../perf.h"
 
-bool bench_ns_ping(stopwatch_t *stopwatch, uint64_t niter,
+static bool runner(stopwatch_t *stopwatch, uint64_t niter,
     char *error, size_t error_size)
 {
@@ -54,2 +55,10 @@
 	return true;
 }
+
+benchmark_t bench_ns_ping = {
+	.name = "ns_ping",
+	.desc = "Name service IPC ping-pong benchmark",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
Index: pace/app/perf/ipc/ns_ping.def
===================================================================
--- uspace/app/perf/ipc/ns_ping.def	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"ns_ping",
-	"Name service IPC ping-pong benchmark",
-	&bench_ns_ping,
-	NULL, NULL
-},
Index: uspace/app/perf/ipc/ping_pong.c
===================================================================
--- uspace/app/perf/ipc/ping_pong.c	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ uspace/app/perf/ipc/ping_pong.c	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -32,9 +32,10 @@
 #include <errno.h>
 #include <str_error.h>
+#include "../benchlist.h"
 #include "../perf.h"
 
 static ipc_test_t *test = NULL;
 
-bool bench_ping_pong_setup(char *error, size_t error_size)
+static bool setup(char *error, size_t error_size)
 {
 	errno_t rc = ipc_test_create(&test);
@@ -49,5 +50,5 @@
 }
 
-bool bench_ping_pong_teardown(char *error, size_t error_size)
+static bool teardown(char *error, size_t error_size)
 {
 	ipc_test_destroy(test);
@@ -55,5 +56,5 @@
 }
 
-bool bench_ping_pong(stopwatch_t *stopwatch, uint64_t niter,
+static bool runner(stopwatch_t *stopwatch, uint64_t niter,
     char *error, size_t error_size)
 {
@@ -75,2 +76,10 @@
 	return true;
 }
+
+benchmark_t bench_ping_pong = {
+	.name = "ping_pong",
+	.desc = "IPC ping-pong benchmark",
+	.entry = &runner,
+	.setup = &setup,
+	.teardown = &teardown
+};
Index: pace/app/perf/ipc/ping_pong.def
===================================================================
--- uspace/app/perf/ipc/ping_pong.def	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"ping_pong",
-	"IPC ping-pong benchmark",
-	&bench_ping_pong,
-	&bench_ping_pong_setup, &bench_ping_pong_teardown
-},
Index: uspace/app/perf/malloc/malloc1.c
===================================================================
--- uspace/app/perf/malloc/malloc1.c	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ uspace/app/perf/malloc/malloc1.c	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -30,7 +30,8 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include "../benchlist.h"
 #include "../perf.h"
 
-bool bench_malloc1(stopwatch_t *stopwatch, uint64_t size,
+static bool runner(stopwatch_t *stopwatch, uint64_t size,
     char *error, size_t error_size)
 {
@@ -50,2 +51,10 @@
 	return true;
 }
+
+benchmark_t bench_malloc1 = {
+	.name = "malloc1",
+	.desc = "User-space memory allocator benchmark, repeatedly allocate one block",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
Index: pace/app/perf/malloc/malloc1.def
===================================================================
--- uspace/app/perf/malloc/malloc1.def	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"malloc1",
-	"User-space memory allocator benchmark, repeatedly allocate one block",
-	&bench_malloc1,
-	NULL, NULL
-},
Index: uspace/app/perf/malloc/malloc2.c
===================================================================
--- uspace/app/perf/malloc/malloc2.c	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ uspace/app/perf/malloc/malloc2.c	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -29,7 +29,8 @@
 #include <stdlib.h>
 #include <stdio.h>
+#include "../benchlist.h"
 #include "../perf.h"
 
-bool bench_malloc2(stopwatch_t *stopwatch, uint64_t niter,
+static bool runner(stopwatch_t *stopwatch, uint64_t niter,
     char *error, size_t error_size)
 {
@@ -67,2 +68,10 @@
 	return true;
 }
+
+benchmark_t bench_malloc2 = {
+	.name = "malloc2",
+	.desc = "User-space memory allocator benchmark, allocate many small blocks",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
Index: pace/app/perf/malloc/malloc2.def
===================================================================
--- uspace/app/perf/malloc/malloc2.def	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"malloc2",
-	"User-space memory allocator benchmark, allocate many small blocks",
-	&bench_malloc2,
-	NULL, NULL
-},
Index: uspace/app/perf/perf.c
===================================================================
--- uspace/app/perf/perf.c	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ uspace/app/perf/perf.c	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -43,16 +43,9 @@
 #include <perf.h>
 #include "perf.h"
+#include "benchlist.h"
 
 #define MIN_DURATION_SECS 10
 #define NUM_SAMPLES 10
 #define MAX_ERROR_STR_LENGTH 1024
-
-benchmark_t benchmarks[] = {
-#include "ipc/ns_ping.def"
-#include "ipc/ping_pong.def"
-#include "malloc/malloc1.def"
-#include "malloc/malloc2.def"
-	{ NULL, NULL, NULL, NULL, NULL }
-};
 
 static void short_report(stopwatch_t *stopwatch, int run_index,
@@ -179,5 +172,4 @@
 static int run_benchmarks(void)
 {
-	benchmark_t *bench;
 	unsigned int i = 0;
 	unsigned int n = 0;
@@ -187,7 +179,7 @@
 	printf("\n*** Running all benchmarks ***\n\n");
 
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		printf("%s (%s)\n", bench->name, bench->desc);
-		if (run_benchmark(bench)) {
+	for (size_t it = 0; it < benchmark_count; it++) {
+		printf("%s (%s)\n", benchmarks[it]->name, benchmarks[it]->desc);
+		if (run_benchmark(benchmarks[it])) {
 			i++;
 			continue;
@@ -195,8 +187,8 @@
 
 		if (!failed_names) {
-			failed_names = str_dup(bench->name);
+			failed_names = str_dup(benchmarks[it]->name);
 		} else {
 			char *f = NULL;
-			asprintf(&f, "%s, %s", failed_names, bench->name);
+			asprintf(&f, "%s, %s", failed_names, benchmarks[it]->name);
 			if (!f) {
 				printf("Out of memory.\n");
@@ -219,8 +211,8 @@
 {
 	size_t len = 0;
-	benchmark_t *bench;
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		if (str_length(bench->name) > len)
-			len = str_length(bench->name);
+	for (size_t i = 0; i < benchmark_count; i++) {
+		size_t len_now = str_length(benchmarks[i]->name);
+		if (len_now > len)
+			len = len_now;
 	}
 
@@ -231,6 +223,6 @@
 	}
 
-	for (bench = benchmarks; bench->name != NULL; bench++)
-		printf("%-*s %s\n", _len, bench->name, bench->desc);
+	for (size_t i = 0; i < benchmark_count; i++)
+		printf("%-*s %s\n", _len, benchmarks[i]->name, benchmarks[i]->desc);
 
 	printf("%-*s Run all benchmarks\n", _len, "*");
@@ -250,8 +242,7 @@
 	}
 
-	benchmark_t *bench;
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		if (str_cmp(argv[1], bench->name) == 0) {
-			return (run_benchmark(bench) ? 0 : -1);
+	for (size_t i = 0; i < benchmark_count; i++) {
+		if (str_cmp(argv[1], benchmarks[i]->name) == 0) {
+			return (run_benchmark(benchmarks[i]) ? 0 : -1);
 		}
 	}
Index: uspace/app/perf/perf.h
===================================================================
--- uspace/app/perf/perf.h	(revision c7de81bdf0faf0c3b0af8ccb51f2cee45cfc4258)
+++ uspace/app/perf/perf.h	(revision d5caf7922353a9ff31141de881200acc494919a3)
@@ -51,13 +51,4 @@
 } benchmark_t;
 
-extern bool bench_malloc1(stopwatch_t *, uint64_t, char *, size_t);
-extern bool bench_malloc2(stopwatch_t *, uint64_t, char *, size_t);
-extern bool bench_ns_ping(stopwatch_t *, uint64_t, char *, size_t);
-extern bool bench_ping_pong(stopwatch_t *, uint64_t, char *, size_t);
-extern bool bench_ping_pong_setup(char *, size_t);
-extern bool bench_ping_pong_teardown(char *, size_t);
-
-extern benchmark_t benchmarks[];
-
 #endif
 
