FxLibcTest/src/string/memarray.h

97 lines
4.1 KiB
C

//---
// string.memarray: Alignment/size combination array for core memory functions
//
// This header provides tools to check memory functions in all size/alignment
// configurations. Up to two buffers can be involved (source and destination),
// and for each buffer all 4n + {0,1,2,3} alignments are tested. Different
// sizes are also tested, each with all possible 4n + {0,1,2,3} values.
//
// By default, two size configurations are tested:
// * 12..15 bytes (intended to use naive, minimum-logic methods)
// * 92..95 bytes (intended to use elaborate methods)
// If two buffers are involved, overlapping sections can also be requested:
// * (32-[64)-32] (approximately; alignment slightly alters values)
// * [32-(64]-32) (approximately; alignment slightly alters values)
//
// This header defines two functions memarray_single() and memarray_double()
// that repeatedly invoke a user-supplied test function with different
// combinations of alignments and sizes. The test function is guarded against
// misaligned memory accesses (which are detected and counted as failures) to
// avoid application crashes.
//
// When invoked, the test function is supplied with a memarray_args_t structure
// that gives buffer addresses and sizes for a single combination. Each buffer
// is provided twice ("name1" and "name2") so that tests requiring a baseline
// (eg. comparing optimized memcpy with naive memcpy) can run the baseline on
// the duplicate buffers.
//
// Test results are recorded in bitmaps based on the return value of the test
// function (0 for success, 1 for failure); this header provides memarray_set()
// and memarray_get() to use the bitmaps (although rarely needed), as well as
// memarray_assert() to record results into an ft_test and memarray_widget() to
// generate result visualizations.
//---
#ifndef _STRING_MEMARRAY_H
#define _STRING_MEMARRAY_H
#include <gint/defs/types.h>
#include <ft/test.h>
#include <justui/jwidget.h>
/* Size of result buffers to allocate for each configuration; one byte is
reserved to indicate the configuration for the bitmap functions */
/* Single buffer: 4 alignments * 8 sizes = 32 tests -> 4 bytes */
#define MEMARRAY_RC_SINGLE 5
/* Double buffer : 4 * 4 alignments * 8 sizes = 128 tests -> 16 bytes */
#define MEMARRAY_RC_DOUBLE 17
/* Double with overlap : 4 * 4 alignments * 16 sizes = 256 tests -> 32 bytes */
#define MEMARRAY_RC_DOUBLE_OVERLAP 33
/* Arguments to test functions:
* In single mode, buf1 and buf2 are used
* In double mode, left1, left2, right1 and right2 are used */
typedef struct {
/* Pointers with varying alignment, to test with */
union { void *buf1, *left1; };
union { void *buf2, *left2; };
void *right1;
void *right2;
/* Size of the operation to perform */
size_t size;
/* Pointers to the orignal buffers (which occupy a larger interval of
memory than the pointers above). This is useful to initialize and check
an area slightly larger than the tested area, to make sure that tested
functions don't write outside their assigned bounds */
union { void *full_buf1, *full_left1; };
union { void *full_buf2, *full_left2; };
void *full_right1;
void *full_right2;
/* Size of the original buffers (128) */
size_t full_size;
} memarray_args_t;
/* Type of test functions; should return 0 for success, 1 for failure */
typedef int (*memarray_func_t)(memarray_args_t const *args);
/* Run a test; the result buffer must have a suitable size allocated */
void memarray_single(uint8_t *rc, memarray_func_t f);
void memarray_double(uint8_t *rc, bool do_overlaps, memarray_func_t f);
/* Set a bit in the result buffer; if position is out of bounds, no-op */
void memarray_set(uint8_t *rc, int position, int value);
/* Get a bit in the result buffer; if position is out of bounds, returns -1 */
int memarray_get(uint8_t *rc, int position);
/* Assert that every value in the result array is 0 */
void memarray_assert(uint8_t *rc, ft_test *test);
/* Create a widget to visualize the contents of a result buffer. The result
pointer is not tied to the widget so it will continue to exist even after
the widget is destroyed. */
jwidget *memarray_widget(uint8_t *buffer);
#endif /* _STRING_MEMARRAY_H */