summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2023-03-27 10:02:38 +0200
committerMitya Selivanov <automainint@guattari.tech>2023-03-27 10:02:38 +0200
commit4eca708d8e693438d4e643dff7283f3cfb79d360 (patch)
tree4ffc2a6b8632a88e33617a152e657e2e522f5f6a /source
parentfc820c883938e7daa257820c818a5c6b609f755f (diff)
downloadkit-4eca708d8e693438d4e643dff7283f3cfb79d360.zip
Benchmark multiple cycles
Diffstat (limited to 'source')
-rw-r--r--source/kit_test/bench.c311
-rw-r--r--source/kit_test/bench.h85
-rw-r--r--source/kit_test/test.c94
-rw-r--r--source/kit_test/test.h2
-rw-r--r--source/test/unittests/foo.bench.c20
5 files changed, 319 insertions, 193 deletions
diff --git a/source/kit_test/bench.c b/source/kit_test/bench.c
index b7de35f..1dc2736 100644
--- a/source/kit_test/bench.c
+++ b/source/kit_test/bench.c
@@ -10,35 +10,51 @@
kit_benchs_list_t kit_benchs_list = { 0 };
+static void bench_set_repeats_limit(int i, int repeats_limit) {
+ if (kit_benchs_list.v[i].ready)
+ return;
+ if (kit_benchs_list.v[i].cycles_size >= KIT_BENCH_MAX_CYCLES)
+ return;
+ kit_benchs_list.v[i].cycles[kit_benchs_list.v[i].cycles_size] =
+ repeats_limit;
+ kit_benchs_list.v[i].cycles_size++;
+}
+
+static int bench_loop(int i) {
+ if (!kit_benchs_list.v[i].ready)
+ return 0;
+ return kit_benchs_list.v[i].repeats <
+ kit_benchs_list.v[i].cycles[kit_benchs_list.v[i].cycle];
+}
+
static void bench_begin(int i) {
- int const n = kit_benchs_list.benchs[i].repeats++;
+ int const n = kit_benchs_list.v[i].repeats++;
- if (n >= KIT_BENCH_REPEATS)
+ if (n >= KIT_BENCH_MAX_REPEATS)
return;
struct timespec tv;
timespec_get(&tv, TIME_UTC);
- kit_benchs_list.benchs[i].sec[n] = (int64_t) tv.tv_sec;
- kit_benchs_list.benchs[i].nsec[n] = (int64_t) tv.tv_nsec;
+ kit_benchs_list.v[i].sec[n] = (int64_t) tv.tv_sec;
+ kit_benchs_list.v[i].nsec[n] = (int64_t) tv.tv_nsec;
}
static void bench_end(int i) {
- int const n = kit_benchs_list.benchs[i].repeats - 1;
+ int const n = kit_benchs_list.v[i].repeats - 1;
- if (n < 0 || n >= KIT_BENCH_REPEATS)
+ if (n < 0 || n >= KIT_BENCH_MAX_REPEATS)
return;
struct timespec tv;
timespec_get(&tv, TIME_UTC);
int64_t const sec = ((int64_t) tv.tv_sec) -
- kit_benchs_list.benchs[i].sec[n];
+ kit_benchs_list.v[i].sec[n];
int64_t const nsec = ((int64_t) tv.tv_nsec) -
- kit_benchs_list.benchs[i].nsec[n];
+ kit_benchs_list.v[i].nsec[n];
- kit_benchs_list.benchs[i].duration_nsec[n] = sec * 1000000000 +
- nsec;
+ kit_benchs_list.v[i].duration_nsec[n] = sec * 1000000000 + nsec;
}
enum { white, blue, light, yellow, red, green };
@@ -56,10 +72,13 @@ void kit_bench_register(char const *name, char const *file,
kit_bench_run_fn fn) {
int n = kit_benchs_list.size++;
if (n < KIT_BENCHS_SIZE_LIMIT) {
- kit_benchs_list.benchs[n].bench_fn = fn;
- kit_benchs_list.benchs[n].bench_name = name;
- kit_benchs_list.benchs[n].bench_file = file;
- kit_benchs_list.benchs[n].repeats = 0;
+ kit_benchmark_t *const bench = kit_benchs_list.v + n;
+
+ bench->bench_fn = fn;
+ bench->bench_name = name;
+ bench->bench_file = file;
+ bench->cycles_size = 0;
+ bench->ready = 0;
}
}
@@ -85,7 +104,8 @@ static void setup_signals() {
int i;
for (i = 0; i < sizeof signums / sizeof *signums; i++) {
-#if defined(_WIN32) && !(defined __CYGWIN__)
+#if (defined(_WIN32) && !defined(__CYGWIN__)) || \
+ !defined(_POSIX_C_SOURCE)
signal(signums[i], handle_signal);
#else
struct sigaction action;
@@ -101,11 +121,12 @@ static int run_bench(volatile int i) {
int signum = setjmp(kit_bench_restore_execution);
if (signum != 0) {
- kit_benchs_list.benchs[i].signal = signum;
+ kit_benchs_list.v[i].signal = signum;
return 0;
}
- kit_benchs_list.benchs[i].bench_fn(i, bench_begin, bench_end);
+ kit_benchs_list.v[i].bench_fn(i, bench_set_repeats_limit,
+ bench_loop, bench_begin, bench_end);
return 1;
}
@@ -115,6 +136,12 @@ int compare_64_(void const *x_, void const *y_) {
return *x - *y;
}
+int compare_32_(void const *x_, void const *y_) {
+ int const *x = (int const *) x_;
+ int const *y = (int const *) y_;
+ return *x - *y;
+}
+
int kit_run_benchmarks(int argc, char **argv) {
int success_count = 0;
int status = 0;
@@ -122,13 +149,11 @@ int kit_run_benchmarks(int argc, char **argv) {
int line_width = 20;
int carriage_return = 1;
- int i, j;
-
char const *specific_bench = NULL;
setup_signals();
- for (i = 0; i < argc; i++)
+ for (int i = 0; i < argc; i++)
if (strcmp("--no-term-color", argv[i]) == 0)
no_color = 1;
else if (strcmp("--no-carriage-return", argv[i]) == 0)
@@ -149,41 +174,40 @@ int kit_run_benchmarks(int argc, char **argv) {
ptrdiff_t file_root = -1;
int benchs_total = 0;
- for (i = 0; i < kit_benchs_list.size && i < KIT_BENCHS_SIZE_LIMIT;
- i++) {
+ for (int i = 0;
+ i < kit_benchs_list.size && i < KIT_BENCHS_SIZE_LIMIT; i++) {
if (specific_bench != NULL &&
- strstr(kit_benchs_list.benchs[i].bench_name,
- specific_bench) == NULL)
+ strstr(kit_benchs_list.v[i].bench_name, specific_bench) ==
+ NULL)
continue;
benchs_total++;
- int const l = 2 +
- (int) strlen(kit_benchs_list.benchs[i].bench_name);
+ int const l = 2 + (int) strlen(kit_benchs_list.v[i].bench_name);
if (line_width < l)
line_width = l;
}
if (benchs_total > 0) {
- char const *const s = kit_benchs_list.benchs[0].bench_file;
+ char const *const s = kit_benchs_list.v[0].bench_file;
+
+ for (int j = 1;
+ j < kit_benchs_list.size && j < KIT_BENCHS_SIZE_LIMIT; j++) {
+ kit_benchmark_t *const bench = kit_benchs_list.v + j;
- for (j = 1; j < kit_benchs_list.size && j < KIT_BENCHS_SIZE_LIMIT;
- j++) {
if (specific_bench != NULL &&
- strstr(kit_benchs_list.benchs[j].bench_name,
- specific_bench) == NULL)
+ strstr(bench->bench_name, specific_bench) == NULL)
continue;
- if (strcmp(s, kit_benchs_list.benchs[j].bench_file) == 0)
+ if (strcmp(s, bench->bench_file) == 0)
continue;
int k = 0;
- for (; s[k] != '\0' &&
- kit_benchs_list.benchs[j].bench_file[k] != '\0' &&
- s[k] == kit_benchs_list.benchs[j].bench_file[k];
+ for (; s[k] != '\0' && bench->bench_file[k] != '\0' &&
+ s[k] == bench->bench_file[k];
k++) { }
if (file_root == -1 || file_root > k)
file_root = k;
}
if (file_root == -1) {
- for (i = 0; s[i] != '\0'; i++)
+ for (int i = 0; s[i] != '\0'; i++)
if (s[i] == '/' || s[i] == '\\')
file_root = i + 1;
}
@@ -207,91 +231,150 @@ int kit_run_benchmarks(int argc, char **argv) {
no_color || print_color(light);
printf(" in nanoseconds\n\n");
- for (i = 0; i < kit_benchs_list.size && i < KIT_BENCHS_SIZE_LIMIT;
- i++) {
+ /* Prepare cycles.
+ */
+
+ for (int i = 0;
+ i < kit_benchs_list.size && i < KIT_BENCHS_SIZE_LIMIT; i++) {
+ kit_benchmark_t *const bench = kit_benchs_list.v + i;
+
if (specific_bench != NULL &&
- strstr(kit_benchs_list.benchs[i].bench_name,
- specific_bench) == NULL)
+ strstr(bench->bench_name, specific_bench) == NULL)
continue;
- if (file == NULL ||
- strcmp(file, kit_benchs_list.benchs[i].bench_file) != 0) {
- if (file != NULL)
- printf("\n");
- file = kit_benchs_list.benchs[i].bench_file;
- no_color || print_color(blue);
- printf("* ");
- no_color || print_color(white);
- printf("%s\n", file + file_root);
+
+ run_bench(i);
+
+ if (bench->cycles_size == 0) {
+ bench->cycles_size = 2;
+ bench->cycles[0] = KIT_BENCH_REPEATS_DEFAULT_1;
+ bench->cycles[1] = KIT_BENCH_REPEATS_DEFAULT_2;
}
- !carriage_return || no_color || print_color(yellow);
- carriage_return || no_color || print_color(light);
- printf("` %s ", kit_benchs_list.benchs[i].bench_name);
- !carriage_return || printf("\r");
- fflush(stdout);
-
- int bench_status = run_bench(i);
-
- if (kit_benchs_list.benchs[i].repeats > KIT_BENCH_REPEATS)
- bench_status = 0;
-
- !carriage_return || no_color || print_color(light);
- !carriage_return ||
- printf("` %s ", kit_benchs_list.benchs[i].bench_name);
-
- int const l = (int) strlen(kit_benchs_list.benchs[i].bench_name);
- printf("%*c", line_width - l, ' ');
-
- if (kit_benchs_list.benchs[i].repeats <= 0) {
- no_color || print_color(yellow);
- printf(" 0 runs\n");
- success_count++;
- } else if (bench_status == 0) {
- no_color || print_color(red);
- printf(" FAIL\n");
- status = 1;
- } else {
- int const repeats = kit_benchs_list.benchs[i].repeats;
-
- qsort(kit_benchs_list.benchs[i].duration_nsec, repeats,
- sizeof *kit_benchs_list.benchs[i].duration_nsec,
- compare_64_);
-
- int64_t const average =
- kit_benchs_list.benchs[i].duration_nsec[repeats / 2];
- int64_t const floor =
- kit_benchs_list.benchs[i].duration_nsec[repeats / 20];
- int64_t const roof =
- kit_benchs_list.benchs[i]
- .duration_nsec[repeats - repeats / 20 - 1];
-
- no_color || print_color(white);
- printf("%-8lld", (long long) floor);
- no_color || print_color(light);
- printf("| ");
- no_color || print_color(white);
- printf("%-8lld", (long long) average);
- no_color || print_color(light);
- printf("| ");
- no_color || print_color(white);
- printf("%-8lld", (long long) roof);
- no_color || print_color(light);
- printf(" %d runs\n", repeats);
- success_count++;
+ qsort(bench->cycles, bench->cycles_size, sizeof *bench->cycles,
+ compare_32_);
+
+ kit_benchs_list.v[i].ready = 1;
+ }
+
+ /* Run cycles.
+ */
+
+ for (int cycle = 0; cycle < KIT_BENCH_MAX_CYCLES; cycle++) {
+ /* Prepare cycle.
+ */
+
+ int cycles_done = 1;
+
+ for (int i = 0;
+ i < kit_benchs_list.size && i < KIT_BENCHS_SIZE_LIMIT; i++) {
+ kit_benchmark_t *const bench = kit_benchs_list.v + i;
+
+ if (specific_bench != NULL &&
+ strstr(bench->bench_name, specific_bench) == NULL)
+ continue;
+ if (cycle >= bench->cycles_size)
+ continue;
+
+ bench->repeats = 0;
+ bench->cycle = cycle;
+ cycles_done = 0;
+ }
+
+ if (cycles_done)
+ break;
+
+ /* Run benchmarks.
+ */
+
+ for (int i = 0;
+ i < kit_benchs_list.size && i < KIT_BENCHS_SIZE_LIMIT; i++) {
+ kit_benchmark_t *const bench = kit_benchs_list.v + i;
+
+ if (specific_bench != NULL &&
+ strstr(bench->bench_name, specific_bench) == NULL)
+ continue;
+ if (cycle >= bench->cycles_size)
+ continue;
+
+ if (file == NULL || strcmp(file, bench->bench_file) != 0) {
+ if (file != NULL)
+ printf("\n");
+ file = bench->bench_file;
+ no_color || print_color(blue);
+ printf("* ");
+ no_color || print_color(white);
+ printf("%s\n", file + file_root);
+ }
+
+ !carriage_return || no_color || print_color(yellow);
+ carriage_return || no_color || print_color(light);
+ printf("` %s ", bench->bench_name);
+ !carriage_return || printf("\r");
+ fflush(stdout);
+
+ int bench_status = run_bench(i);
+
+ if (bench->repeats > KIT_BENCH_MAX_REPEATS)
+ bench_status = 0;
+
+ !carriage_return || no_color || print_color(light);
+ !carriage_return || printf("` %s ", bench->bench_name);
+
+ int const l = (int) strlen(bench->bench_name);
+ printf("%*c", line_width - l, ' ');
+
+ if (bench->repeats <= 0) {
+ no_color || print_color(yellow);
+ printf(" 0 runs\n");
+ success_count++;
+ } else if (bench_status == 0) {
+ no_color || print_color(red);
+ printf(" FAIL\n");
+ status = 1;
+ } else {
+ int const repeats = bench->repeats;
+
+ memcpy(bench->duration_sorted_nsec, bench->duration_nsec,
+ repeats * sizeof *bench->duration_sorted_nsec);
+ qsort(bench->duration_sorted_nsec, repeats,
+ sizeof *bench->duration_sorted_nsec, compare_64_);
+
+ int64_t const average =
+ bench->duration_sorted_nsec[repeats / 2];
+ int64_t const floor =
+ bench->duration_sorted_nsec[repeats / 20];
+ int64_t const roof =
+ bench->duration_sorted_nsec[repeats - repeats / 20 - 1];
+
+ no_color || print_color(white);
+ printf("%-8lld", (long long) floor);
+ no_color || print_color(light);
+ printf("| ");
+ no_color || print_color(white);
+ printf("%-8lld", (long long) average);
+ no_color || print_color(light);
+ printf("| ");
+ no_color || print_color(white);
+ printf("%-8lld", (long long) roof);
+ no_color || print_color(light);
+ printf(" %d runs\n", repeats);
+ success_count++;
+ }
}
}
printf("\n");
if (status != 0) {
- for (i = 0; i < kit_benchs_list.size && i < KIT_BENCHS_SIZE_LIMIT;
- i++) {
+ for (int i = 0;
+ i < kit_benchs_list.size && i < KIT_BENCHS_SIZE_LIMIT; i++) {
+ kit_benchmark_t *const bench = kit_benchs_list.v + i;
+
if (specific_bench != NULL &&
- strstr(kit_benchs_list.benchs[i].bench_name,
- specific_bench) == NULL)
+ strstr(bench->bench_name, specific_bench) == NULL)
continue;
- if (kit_benchs_list.benchs[i].signal != 0) {
- int signum = kit_benchs_list.benchs[i].signal;
+ if (bench->signal != 0) {
+ int signum = bench->signal;
if (signum >= 0 &&
signum < sizeof signames / sizeof *signames &&
signames[signum] != NULL) {
@@ -299,24 +382,22 @@ int kit_run_benchmarks(int argc, char **argv) {
printf("Signal \"%s\" (%d) for \"", signames[signum],
signum);
no_color || print_color(white);
- printf("%s", kit_benchs_list.benchs[i].bench_name);
+ printf("%s", bench->bench_name);
no_color || print_color(light);
printf("\" in \"");
no_color || print_color(white);
- printf("%s",
- kit_benchs_list.benchs[i].bench_file + file_root);
+ printf("%s", bench->bench_file + file_root);
no_color || print_color(light);
printf("\"!.\n");
} else {
no_color || print_color(light);
printf("Unknown signal (%d) for \"", signum);
no_color || print_color(white);
- printf("%s", kit_benchs_list.benchs[i].bench_name);
+ printf("%s", bench->bench_name);
no_color || print_color(light);
printf("\" in \"");
no_color || print_color(white);
- printf("%s",
- kit_benchs_list.benchs[i].bench_file + file_root);
+ printf("%s", bench->bench_file + file_root);
no_color || print_color(light);
printf("\"!.\n");
}
diff --git a/source/kit_test/bench.h b/source/kit_test/bench.h
index 6c701bb..ba3e0f5 100644
--- a/source/kit_test/bench.h
+++ b/source/kit_test/bench.h
@@ -8,38 +8,62 @@ extern "C" {
#include "test.h"
#include <stdint.h>
-#ifndef KIT_BENCH_FILE
-# define KIT_BENCH_FILE kit_bench
+#ifndef KIT_TEST_FILE
+# define KIT_TEST_FILE kit_bench
#endif
#ifndef KIT_BENCHS_SIZE_LIMIT
# define KIT_BENCHS_SIZE_LIMIT 0x1000
#endif
-#ifndef KIT_BENCH_REPEATS
-# define KIT_BENCH_REPEATS 400
+#ifndef KIT_BENCH_MAX_REPEATS
+# define KIT_BENCH_MAX_REPEATS 4000
#endif
+#ifndef KIT_BENCH_MAX_CYCLES
+# define KIT_BENCH_MAX_CYCLES 40
+#endif
+
+#ifndef KIT_BENCH_REPEATS_DEFAULT_1
+# define KIT_BENCH_REPEATS_DEFAULT_1 40
+#endif
+
+#ifndef KIT_BENCH_REPEATS_DEFAULT_2
+# define KIT_BENCH_REPEATS_DEFAULT_2 400
+#endif
+
+typedef void (*kit_bench_set_repeats_limit_fn)(int bench_index,
+ int repeats_limit);
+typedef int (*kit_bench_loop_fn)(int bench_index);
typedef void (*kit_bench_begin_fn)(int bench_index);
typedef void (*kit_bench_end_fn)(int bench_index);
+
typedef void (*kit_bench_run_fn)(
- int kit_bench_index_, kit_bench_begin_fn kit_bench_begin_fn_,
- kit_bench_end_fn kit_bench_end_fn_);
+ int kit_bench_index_,
+ kit_bench_set_repeats_limit_fn kit_bench_set_repeats_limit_,
+ kit_bench_loop_fn kit_bench_loop_,
+ kit_bench_begin_fn kit_bench_begin_,
+ kit_bench_end_fn kit_bench_end_);
typedef struct {
char const *bench_name;
char const *bench_file;
kit_bench_run_fn bench_fn;
- int64_t sec[KIT_BENCH_REPEATS];
- int32_t nsec[KIT_BENCH_REPEATS];
- int64_t duration_nsec[KIT_BENCH_REPEATS];
+ int64_t sec[KIT_BENCH_MAX_REPEATS];
+ int32_t nsec[KIT_BENCH_MAX_REPEATS];
+ int64_t duration_nsec[KIT_BENCH_MAX_REPEATS];
+ int64_t duration_sorted_nsec[KIT_BENCH_MAX_REPEATS];
int repeats;
+ int cycles_size;
+ int cycles[KIT_BENCH_MAX_CYCLES];
+ int cycle;
int signal;
+ int ready;
} kit_benchmark_t;
typedef struct {
int size;
- kit_benchmark_t benchs[KIT_BENCHS_SIZE_LIMIT];
+ kit_benchmark_t v[KIT_BENCHS_SIZE_LIMIT];
} kit_benchs_list_t;
extern kit_benchs_list_t kit_benchs_list;
@@ -49,28 +73,34 @@ void kit_bench_register(char const *name, char const *file,
#define KIT_BENCHMARK(name) \
static void KIT_TEST_CONCAT3_(kit_bench_run_, __LINE__, \
- KIT_BENCH_FILE)( \
- int, kit_bench_begin_fn, kit_bench_end_fn); \
+ KIT_TEST_FILE)( \
+ int, kit_bench_set_repeats_limit_fn, kit_bench_loop_fn, \
+ kit_bench_begin_fn, kit_bench_end_fn); \
KIT_TEST_ON_START_( \
- KIT_TEST_CONCAT3_(kit_benchmark_, __LINE__, KIT_BENCH_FILE)) { \
- kit_bench_register(name, __FILE__, \
- KIT_TEST_CONCAT3_(kit_bench_run_, __LINE__, \
- KIT_BENCH_FILE)); \
+ KIT_TEST_CONCAT3_(kit_benchmark_, __LINE__, KIT_TEST_FILE)) { \
+ kit_bench_register( \
+ name, __FILE__, \
+ KIT_TEST_CONCAT3_(kit_bench_run_, __LINE__, KIT_TEST_FILE)); \
} \
static void KIT_TEST_CONCAT3_(kit_bench_run_, __LINE__, \
- KIT_BENCH_FILE)( \
- int kit_bench_index_, kit_bench_begin_fn kit_bench_begin_fn_, \
- kit_bench_end_fn kit_bench_end_fn_)
-
-#define KIT_BENCHMARK_BEGIN \
- for (int kit_bench_repeat_ = 0; \
- kit_bench_repeat_ < KIT_BENCH_REPEATS; kit_bench_repeat_++) { \
- kit_bench_begin_fn_(kit_bench_index_); \
+ KIT_TEST_FILE)( \
+ int kit_bench_index_, \
+ kit_bench_set_repeats_limit_fn kit_bench_set_repeats_limit_, \
+ kit_bench_loop_fn kit_bench_loop_, \
+ kit_bench_begin_fn kit_bench_begin_, \
+ kit_bench_end_fn kit_bench_end_)
+
+#define KIT_BENCHMARK_REPEAT(repeats_limit_) \
+ kit_bench_set_repeats_limit_(kit_bench_index_, repeats_limit_)
+
+#define KIT_BENCHMARK_BEGIN \
+ while (kit_bench_loop_(kit_bench_index_)) { \
+ kit_bench_begin_(kit_bench_index_); \
{
-#define KIT_BENCHMARK_END \
- } \
- kit_bench_end_fn_(kit_bench_index_); \
+#define KIT_BENCHMARK_END \
+ } \
+ kit_bench_end_(kit_bench_index_); \
}
/* FIXME
@@ -85,6 +115,7 @@ int kit_run_benchmarks(int argc, char **argv);
#ifndef KIT_DISABLE_SHORT_NAMES
# define BENCHMARK KIT_BENCHMARK
+# define BENCHMARK_REPEAT KIT_BENCHMARK_REPEAT
# define BENCHMARK_BEGIN KIT_BENCHMARK_BEGIN
# define BENCHMARK_END KIT_BENCHMARK_END
# define DO_NOT_OPTIMIZE KIT_DO_NOT_OPTIMIZE
diff --git a/source/kit_test/test.c b/source/kit_test/test.c
index 3d3e180..6603d65 100644
--- a/source/kit_test/test.c
+++ b/source/kit_test/test.c
@@ -10,13 +10,13 @@
kit_tests_list_t kit_tests_list = { 0 };
static void report(int i, int line, int ok) {
- int const n = kit_tests_list.tests[i].assertions++;
+ int const n = kit_tests_list.v[i].assertions++;
if (n >= KIT_TEST_ASSERTIONS_LIMIT)
return;
- kit_tests_list.tests[i].line[n] = line;
- kit_tests_list.tests[i].status[n] = ok;
+ kit_tests_list.v[i].line[n] = line;
+ kit_tests_list.v[i].status[n] = ok;
}
static long long ns_to_ms(long long ns) {
@@ -42,10 +42,10 @@ void kit_test_register(char const *name, char const *file,
kit_test_run_fn fn) {
int n = kit_tests_list.size++;
if (n < KIT_TESTS_SIZE_LIMIT) {
- kit_tests_list.tests[n].test_fn = fn;
- kit_tests_list.tests[n].test_name = name;
- kit_tests_list.tests[n].test_file = file;
- kit_tests_list.tests[n].assertions = 0;
+ kit_tests_list.v[n].test_fn = fn;
+ kit_tests_list.v[n].test_name = name;
+ kit_tests_list.v[n].test_file = file;
+ kit_tests_list.v[n].assertions = 0;
}
}
@@ -71,7 +71,8 @@ static void setup_signals() {
int i;
for (i = 0; i < sizeof signums / sizeof *signums; i++) {
-#if defined(_WIN32) && !(defined __CYGWIN__)
+#if (defined(_WIN32) && !defined(__CYGWIN__)) || \
+ !defined(_POSIX_C_SOURCE)
signal(signums[i], handle_signal);
#else
struct sigaction action;
@@ -87,11 +88,11 @@ static int run_test(volatile int i) {
int signum = setjmp(kit_test_restore_execution);
if (signum != 0) {
- kit_tests_list.tests[i].signal = signum;
+ kit_tests_list.v[i].signal = signum;
return 0;
}
- kit_tests_list.tests[i].test_fn(i, report);
+ kit_tests_list.v[i].test_fn(i, report);
return 1;
}
@@ -139,30 +140,29 @@ int kit_run_tests(int argc, char **argv) {
for (i = 0; i < kit_tests_list.size && i < KIT_TESTS_SIZE_LIMIT;
i++) {
if (specific_test != NULL &&
- strstr(kit_tests_list.tests[i].test_name, specific_test) ==
- NULL)
+ strstr(kit_tests_list.v[i].test_name, specific_test) == NULL)
continue;
tests_total++;
- int const l = 2 + (int) strlen(kit_tests_list.tests[i].test_name);
+ int const l = 2 + (int) strlen(kit_tests_list.v[i].test_name);
if (line_width < l)
line_width = l;
}
if (tests_total > 0) {
- char const *const s = kit_tests_list.tests[0].test_file;
+ char const *const s = kit_tests_list.v[0].test_file;
for (j = 1; j < kit_tests_list.size && j < KIT_TESTS_SIZE_LIMIT;
j++) {
if (specific_test != NULL &&
- strstr(kit_tests_list.tests[j].test_name, specific_test) ==
+ strstr(kit_tests_list.v[j].test_name, specific_test) ==
NULL)
continue;
- if (strcmp(s, kit_tests_list.tests[j].test_file) == 0)
+ if (strcmp(s, kit_tests_list.v[j].test_file) == 0)
continue;
int k = 0;
- for (; s[k] != '\0' &&
- kit_tests_list.tests[j].test_file[k] != '\0' &&
- s[k] == kit_tests_list.tests[j].test_file[k];
+ for (;
+ s[k] != '\0' && kit_tests_list.v[j].test_file[k] != '\0' &&
+ s[k] == kit_tests_list.v[j].test_file[k];
k++) { }
if (file_root == -1 || file_root > k)
file_root = k;
@@ -178,14 +178,13 @@ int kit_run_tests(int argc, char **argv) {
for (i = 0; i < kit_tests_list.size && i < KIT_TESTS_SIZE_LIMIT;
i++) {
if (specific_test != NULL &&
- strstr(kit_tests_list.tests[i].test_name, specific_test) ==
- NULL)
+ strstr(kit_tests_list.v[i].test_name, specific_test) == NULL)
continue;
if (file == NULL ||
- strcmp(file, kit_tests_list.tests[i].test_file) != 0) {
+ strcmp(file, kit_tests_list.v[i].test_file) != 0) {
if (file != NULL)
quiet || printf("\n");
- file = kit_tests_list.tests[i].test_file;
+ file = kit_tests_list.v[i].test_file;
no_color || print_color(blue);
quiet || printf("* ");
no_color || print_color(white);
@@ -194,7 +193,7 @@ int kit_run_tests(int argc, char **argv) {
!carriage_return || no_color || print_color(yellow);
carriage_return || no_color || print_color(light);
- quiet || printf("` %s ", kit_tests_list.tests[i].test_name);
+ quiet || printf("` %s ", kit_tests_list.v[i].test_name);
!carriage_return || quiet || printf("\r");
quiet || fflush(stdout);
@@ -207,23 +206,22 @@ int kit_run_tests(int argc, char **argv) {
int duration = (int) (ns_to_ms(end.tv_nsec - begin.tv_nsec) +
sec_to_ms(end.tv_sec - begin.tv_sec));
- for (j = 0; j < kit_tests_list.tests[i].assertions; j++)
- if (kit_tests_list.tests[i].status[j] == 0) {
+ for (j = 0; j < kit_tests_list.v[i].assertions; j++)
+ if (kit_tests_list.v[i].status[j] == 0) {
fail_assertion_count++;
test_status = 0;
}
- if (kit_tests_list.tests[i].assertions >
- KIT_TEST_ASSERTIONS_LIMIT)
+ if (kit_tests_list.v[i].assertions > KIT_TEST_ASSERTIONS_LIMIT)
test_status = 0;
- total_assertion_count += kit_tests_list.tests[i].assertions;
+ total_assertion_count += kit_tests_list.v[i].assertions;
!carriage_return || no_color || print_color(light);
!carriage_return || quiet ||
- printf("` %s ", kit_tests_list.tests[i].test_name);
+ printf("` %s ", kit_tests_list.v[i].test_name);
- int const l = (int) strlen(kit_tests_list.tests[i].test_name);
+ int const l = (int) strlen(kit_tests_list.v[i].test_name);
quiet || printf("%*c", line_width - l, ' ');
if (test_status == 0) {
@@ -256,11 +254,11 @@ int kit_run_tests(int argc, char **argv) {
for (i = 0; i < kit_tests_list.size && i < KIT_TESTS_SIZE_LIMIT;
i++) {
if (specific_test != NULL &&
- strstr(kit_tests_list.tests[i].test_name, specific_test) ==
+ strstr(kit_tests_list.v[i].test_name, specific_test) ==
NULL)
continue;
- if (kit_tests_list.tests[i].signal != 0) {
- int signum = kit_tests_list.tests[i].signal;
+ if (kit_tests_list.v[i].signal != 0) {
+ int signum = kit_tests_list.v[i].signal;
if (signum >= 0 &&
signum < sizeof signames / sizeof *signames &&
signames[signum] != NULL) {
@@ -268,52 +266,52 @@ int kit_run_tests(int argc, char **argv) {
quiet || printf("Signal \"%s\" (%d) for \"",
signames[signum], signum);
no_color || print_color(white);
- quiet || printf("%s", kit_tests_list.tests[i].test_name);
+ quiet || printf("%s", kit_tests_list.v[i].test_name);
no_color || print_color(light);
quiet || printf("\" in \"");
no_color || print_color(white);
- quiet || printf("%s", kit_tests_list.tests[i].test_file +
- file_root);
+ quiet ||
+ printf("%s", kit_tests_list.v[i].test_file + file_root);
no_color || print_color(light);
quiet || printf("\"!.\n");
} else {
no_color || print_color(light);
quiet || printf("Unknown signal (%d) for \"", signum);
no_color || print_color(white);
- quiet || printf("%s", kit_tests_list.tests[i].test_name);
+ quiet || printf("%s", kit_tests_list.v[i].test_name);
no_color || print_color(light);
quiet || printf("\" in \"");
no_color || print_color(white);
- quiet || printf("%s", kit_tests_list.tests[i].test_file +
- file_root);
+ quiet ||
+ printf("%s", kit_tests_list.v[i].test_file + file_root);
no_color || print_color(light);
quiet || printf("\"!.\n");
}
}
- if (kit_tests_list.tests[i].assertions >
+ if (kit_tests_list.v[i].assertions >
KIT_TEST_ASSERTIONS_LIMIT) {
no_color || print_color(light);
quiet || printf("Too many assertions for \"");
no_color || print_color(white);
- quiet || printf("%s", kit_tests_list.tests[i].test_name);
+ quiet || printf("%s", kit_tests_list.v[i].test_name);
no_color || print_color(light);
quiet || printf("\" in \"");
no_color || print_color(white);
- quiet || printf("%s", kit_tests_list.tests[i].test_file +
- file_root);
+ quiet ||
+ printf("%s", kit_tests_list.v[i].test_file + file_root);
no_color || print_color(light);
quiet || printf("\"!.\n");
} else
- for (j = 0; j < kit_tests_list.tests[i].assertions; j++)
- if (!kit_tests_list.tests[i].status[j]) {
+ for (j = 0; j < kit_tests_list.v[i].assertions; j++)
+ if (!kit_tests_list.v[i].status[j]) {
no_color || print_color(light);
quiet || printf("Assertion on line ");
no_color || print_color(white);
- quiet || printf("%d", kit_tests_list.tests[i].line[j]);
+ quiet || printf("%d", kit_tests_list.v[i].line[j]);
no_color || print_color(light);
quiet || printf(" in \"");
no_color || print_color(white);
- quiet || printf("%s", kit_tests_list.tests[i].test_file +
+ quiet || printf("%s", kit_tests_list.v[i].test_file +
file_root);
no_color || print_color(light);
quiet || printf("\" failed.\n");
diff --git a/source/kit_test/test.h b/source/kit_test/test.h
index 39c28e7..44aae09 100644
--- a/source/kit_test/test.h
+++ b/source/kit_test/test.h
@@ -35,7 +35,7 @@ typedef struct {
typedef struct {
int size;
- kit_test_case_t tests[KIT_TESTS_SIZE_LIMIT];
+ kit_test_case_t v[KIT_TESTS_SIZE_LIMIT];
} kit_tests_list_t;
extern kit_tests_list_t kit_tests_list;
diff --git a/source/test/unittests/foo.bench.c b/source/test/unittests/foo.bench.c
index a3d5c18..ac1e0b5 100644
--- a/source/test/unittests/foo.bench.c
+++ b/source/test/unittests/foo.bench.c
@@ -1,4 +1,4 @@
-#define KIT_BENCH_FILE foo
+#define KIT_TEST_FILE foo
#include "../../kit_test/bench.h"
struct test_foo_ {
@@ -6,8 +6,15 @@ struct test_foo_ {
};
BENCHMARK("foo") {
+
+ /* Benchmark setup.
+ */
+
BENCHMARK_BEGIN;
{
+ /* Measured code snippet.
+ */
+
int x = 0;
struct test_foo_ f = { 0. };
@@ -16,10 +23,19 @@ BENCHMARK("foo") {
x ^= i;
f.f += 0.1;
}
+
DO_NOT_OPTIMIZE(x);
DO_NOT_OPTIMIZE(f);
}
BENCHMARK_END;
}
-BENCHMARK("bar") { }
+BENCHMARK("bar") {
+ BENCHMARK_REPEAT(10);
+ BENCHMARK_REPEAT(100);
+
+ BENCHMARK_BEGIN;
+ BENCHMARK_END;
+}
+
+BENCHMARK("empty") { }