97 lines
4.1 KiB
C
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 */
|