diff options
Diffstat (limited to 'src/memtest.c')
-rw-r--r-- | src/memtest.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/memtest.c b/src/memtest.c index 56162ff4f..82da27c8b 100644 --- a/src/memtest.c +++ b/src/memtest.c @@ -35,6 +35,7 @@ #include <errno.h> #include <termios.h> #include <sys/ioctl.h> +#include "config.h" #if (ULONG_MAX == 4294967295UL) #define MEMTEST_32BIT @@ -240,6 +241,36 @@ void memtest_test(size_t megabytes, int passes) { } } +/* This is a fast O(N) best effort memory test, only ZERO-ONE tests and + * checkerboard tests are performed, without pauses between setting and + * reading the value, so this can only detect a subclass of permanent errors. + * + * However the function does not destroy the content of the memory tested that + * is left unmodified. + * + * If a memory error is detected, 1 is returned. Otherwise 0 is returned. */ +int memtest_non_destructive(void *addr, size_t size) { + volatile unsigned long *p = addr; + unsigned long val; + size_t j; + + size /= sizeof(unsigned long); + for (j = 0; j < size; j++) { + val = p[j]; + + p[j] = 0; if (p[j] != 0) goto err; + p[j] = (unsigned long)-1; if (p[j] != (unsigned long)-1) goto err; + p[j] = ULONG_ONEZERO; if (p[j] != ULONG_ONEZERO) goto err; + p[j] = ULONG_ZEROONE; if (p[j] != ULONG_ZEROONE) goto err; + p[j] = val; /* restore the original value. */ + } + return 0; + +err: /* memory error detected. */ + p[j] = val; + return 1; +} + void memtest(size_t megabytes, int passes) { if (ioctl(1, TIOCGWINSZ, &ws) == -1) { ws.ws_col = 80; |