Go to the documentation of this file.
37 #ifndef CHECKASM_TEST_H
38 #define CHECKASM_TEST_H
43 #include "checkasm/checkasm.h"
77 #define checkasm_check_func(func, ...) \
79 = checkasm_check_key((checkasm_key_new = (CheckasmKey) (func)), __VA_ARGS__))
155 #define checkasm_fail() checkasm_fail_func("%s:%d", __FILE__, __LINE__)
205 #define checkasm_declare(ret, ...) \
206 checkasm_declare_impl(ret, __VA_ARGS__); \
207 typedef ret func_type(__VA_ARGS__); \
208 (void) ((func_type *) NULL)
233 #ifndef checkasm_declare_emms
234 #define checkasm_declare_emms(cpu_flags, ret, ...) checkasm_declare(ret, __VA_ARGS__)
252 #define checkasm_call(func, ...) \
253 (checkasm_set_signal_handler_state(1), (func) (__VA_ARGS__)); \
254 checkasm_clear_cpu_state(); \
255 checkasm_set_signal_handler_state(0)
272 #ifndef checkasm_call_checked
273 #define checkasm_call_checked(func, ...) \
274 (checkasm_set_signal_handler_state(1), \
275 checkasm_push_stack_guard((uintptr_t[16]) { 0, 0 }), \
276 ((func_type *) (func))(__VA_ARGS__)); \
277 checkasm_pop_stack_guard(); \
278 checkasm_set_signal_handler_state(0)
339 #define checkasm_func_ref ((func_type *) checkasm_key_ref)
353 #define checkasm_func_new ((func_type *) checkasm_key_new)
367 #define checkasm_call_ref(...) checkasm_call(checkasm_func_ref, __VA_ARGS__)
382 #define checkasm_call_new(...) checkasm_call_checked(checkasm_func_new, __VA_ARGS__)
403 #define checkasm_bench(func, ...) \
405 if (checkasm_bench_func()) { \
406 func_type *const bench_func = (func); \
407 checkasm_set_signal_handler_state(1); \
408 for (int truns; (truns = checkasm_bench_runs());) { \
410 CHECKASM_PERF_BENCH(truns, time, __VA_ARGS__); \
411 checkasm_clear_cpu_state(); \
412 checkasm_bench_update(truns, time); \
414 checkasm_set_signal_handler_state(0); \
415 checkasm_bench_finish(); \
417 const int tidx = 0; \
419 checkasm_call_checked(func, __VA_ARGS__); \
447 #define checkasm_bench_new(...) checkasm_bench(checkasm_func_new, __VA_ARGS__)
469 #define checkasm_alternate(a, b) ((tidx & 1) ? (b) : (a))
479 #define fail checkasm_fail
480 #define report checkasm_report
481 #define check_func checkasm_check_func
482 #define check_key checkasm_check_key
483 #define func_ref checkasm_func_ref
484 #define func_new checkasm_func_new
485 #define call_ref checkasm_call_ref
486 #define call_new checkasm_call_new
487 #define bench_new checkasm_bench_new
488 #define alternate checkasm_alternate
489 #define declare_func checkasm_declare
490 #define declare_func_emms checkasm_declare_emms
522 #ifndef checkasm_clear_cpu_state
523 #define checkasm_clear_cpu_state() \
549 #ifdef CHECKASM_PERF_ASM
555 #define CHECKASM_PERF_CALL4(...) \
558 bench_func(__VA_ARGS__); \
560 bench_func(__VA_ARGS__); \
562 bench_func(__VA_ARGS__); \
564 bench_func(__VA_ARGS__); \
568 #define CHECKASM_PERF_CALL16(...) \
570 CHECKASM_PERF_CALL4(__VA_ARGS__); \
571 CHECKASM_PERF_CALL4(__VA_ARGS__); \
572 CHECKASM_PERF_CALL4(__VA_ARGS__); \
573 CHECKASM_PERF_CALL4(__VA_ARGS__); \
578 #define CHECKASM_PERF_BENCH_SIMPLE(count, time, ...) \
580 time = perf.start(); \
581 for (int tidx = 0; tidx < count; tidx++) \
582 bench_func(__VA_ARGS__); \
583 time = perf.stop(time); \
587 #define CHECKASM_PERF_BENCH_ASM(total_count, time, ...) \
589 int tcount_trim = 0; \
590 uint64_t tsum_trim = 0; \
591 for (int titer = 0; titer < total_count; titer += 32) { \
592 uint64_t t = CHECKASM_PERF_ASM(); \
593 CHECKASM_PERF_CALL16(__VA_ARGS__); \
594 CHECKASM_PERF_CALL16(__VA_ARGS__); \
595 t = CHECKASM_PERF_ASM() - t; \
596 if (t * tcount_trim <= tsum_trim * 4 && (titer > 0 || total_count < 1000)) { \
602 total_count = tcount_trim << 5; \
608 #ifdef CHECKASM_PERF_ASM
609 #ifndef CHECKASM_PERF_ASM_USABLE
610 #define CHECKASM_PERF_ASM_USABLE perf.asm_usable
612 #define CHECKASM_PERF_BENCH(count, time, ...) \
614 const CheckasmPerf perf = *checkasm_get_perf(); \
615 if (CHECKASM_PERF_ASM_USABLE && count >= 128) { \
616 CHECKASM_PERF_BENCH_ASM(count, time, __VA_ARGS__); \
618 CHECKASM_PERF_BENCH_SIMPLE(count, time, __VA_ARGS__); \
622 #define CHECKASM_PERF_BENCH(count, time, ...) \
624 const CheckasmPerf perf = *checkasm_get_perf(); \
625 CHECKASM_PERF_BENCH_SIMPLE(count, time, __VA_ARGS__); \
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
static CheckasmKey checkasm_key_new
Key identifying the implementation being tested.
uint64_t(* start)(void)
Start timing measurement.
static void checkasm_unused(void)
Suppress unused variable warnings.
CHECKASM_API CheckasmKey CHECKASM_API void CHECKASM_API int checkasm_fail_func(const char *msg,...) CHECKASM_PRINTF(1
Mark the current function as failed with a custom message.
Platform and compiler attribute macros.
uint64_t(* stop)(uint64_t start_time)
Stop timing measurement.
const char * name
Name of the timing mechanism (e.g., "clock_gettime")
CHECKASM_API void checkasm_set_signal_handler_state(int enabled)
Enable or disable signal handling.
CHECKASM_API CheckasmKey checkasm_check_key(CheckasmKey key, const char *name,...) CHECKASM_PRINTF(2
Check if a key should be tested.
CHECKASM_API CheckasmKey CHECKASM_API void checkasm_set_func_variant(const char *id,...) CHECKASM_PRINTF(1
Set a custom variant identifier for the next checkasm_check_func() call.
CHECKASM_API void checkasm_bench_update(int iterations, uint64_t cycles)
Update benchmark statistics with timing results.
CHECKASM_API void checkasm_push_stack_guard(uintptr_t guard[2])
Push stack guard values for corruption detection.
static CheckasmKey checkasm_key_ref
Key identifying the reference implementation.
static int64_t start_time
CHECKASM_API int checkasm_bench_func(void)
Check if current function should be benchmarked.
CHECKASM_API void checkasm_report(const char *name,...) CHECKASM_PRINTF(1
Report test outcome for a named group of functions.
const char * unit
Unit of measurement (e.g., "ns", "cycles")
CHECKASM_API int checkasm_bench_runs(void)
Get number of iterations for current benchmark run.
#define CHECKASM_API
Symbol visibility attribute for public API functions.
const CHECKASM_API CheckasmPerf * checkasm_get_perf(void)
uintptr_t CheckasmKey
Opaque type used to identify function implementations.
CHECKASM_API void checkasm_pop_stack_guard(void)
CHECKASM_API void checkasm_bench_finish(void)
Finalize and store benchmark results.
CHECKASM_API int checkasm_should_fail(CheckasmCpu cpu_flags)
Mark a block of tests as expected to fail.
uint64_t CheckasmCpu
Opaque type representing a set of CPU feature flags.
#define CHECKASM_PRINTF(fmt, attr)
Printf-style format string checking attribute.