/* Test that addressing is fine. Every location is populated with its own * address, and finally verified. This test is very fast but may detect * ASAP big issues with the memory subsystem. */ void memtest_addressing(unsigned long *l, size_t bytes) { unsigned long words = bytes/sizeof(unsigned long); unsigned long j, *p; /* Fill */ p = l; for (j = 0; j < words; j++) { *p = (unsigned long)p; p++; if ((j & 0xffff) == 0) memtest_progress_step(j,words*2,'A'); } /* Test */ p = l; for (j = 0; j < words; j++) { if (*p != (unsigned long)p) { printf("\n*** MEMORY ADDRESSING ERROR: %p contains %lu\n", (void*) p, *p); exit(1); } p++; if ((j & 0xffff) == 0) memtest_progress_step(j+words,words*2,'A'); } }
/* Like memtest_fill_random() but uses the two specified values to fill * memory, in an alternated way (v1|v2|v1|v2|...) */ void memtest_fill_value(unsigned long *l, size_t bytes, unsigned long v1, unsigned long v2, char sym) { unsigned long step = 4096/sizeof(unsigned long); unsigned long words = bytes/sizeof(unsigned long)/2; unsigned long iwords = words/step; /* words per iteration */ unsigned long off, w, *l1, *l2, v; assert((bytes & 4095) == 0); for (off = 0; off < step; off++) { l1 = l+off; l2 = l1+words; v = (off & 1) ? v2 : v1; for (w = 0; w < iwords; w++) { #ifdef MEMTEST_32BIT *l1 = *l2 = ((unsigned long) v) | (((unsigned long) v) << 16); #else *l1 = *l2 = ((unsigned long) v) | (((unsigned long) v) << 16) | (((unsigned long) v) << 32) | (((unsigned long) v) << 48); #endif l1 += step; l2 += step; if ((w & 0xffff) == 0) memtest_progress_step(w+iwords*off,words,sym); } } }
/* Fill words stepping a single page at every write, so we continue to * touch all the pages in the smallest amount of time reducing the * effectiveness of caches, and making it hard for the OS to transfer * pages on the swap. */ void memtest_fill_random(unsigned long *l, size_t bytes) { unsigned long step = 4096/sizeof(unsigned long); unsigned long words = bytes/sizeof(unsigned long)/2; unsigned long iwords = words/step; /* words per iteration */ unsigned long off, w, *l1, *l2; assert((bytes & 4095) == 0); for (off = 0; off < step; off++) { l1 = l+off; l2 = l1+words; for (w = 0; w < iwords; w++) { #ifdef MEMTEST_32BIT *l1 = *l2 = ((unsigned long) (rand()&0xffff)) | (((unsigned long) (rand()&0xffff)) << 16); #else *l1 = *l2 = ((unsigned long) (rand()&0xffff)) | (((unsigned long) (rand()&0xffff)) << 16) | (((unsigned long) (rand()&0xffff)) << 32) | (((unsigned long) (rand()&0xffff)) << 48); #endif l1 += step; l2 += step; if ((w & 0xffff) == 0) memtest_progress_step(w+iwords*off,words,'R'); } } }
void memtest_compare(unsigned long *l, size_t bytes) { unsigned long words = bytes/sizeof(unsigned long)/2; unsigned long w, *l1, *l2; assert((bytes & 4095) == 0); l1 = l; l2 = l1+words; for (w = 0; w < words; w++) { if (*l1 != *l2) { printf("\n*** MEMORY ERROR DETECTED: %p != %p (%lu vs %lu)\n", (void*)l1, (void*)l2, *l1, *l2); exit(1); } l1 ++; l2 ++; if ((w & 0xffff) == 0) memtest_progress_step(w,words,'='); } }
void memtest_fill_random(unsigned long *l, size_t bytes, int interactive) { unsigned long step = 4096/sizeof(unsigned long); unsigned long words = bytes/sizeof(unsigned long)/2; unsigned long iwords = words/step; /* words per iteration */ unsigned long off, w, *l1, *l2; uint64_t rseed = UINT64_C(0xd13133de9afdb566); /* Just a random seed. */ uint64_t rout = 0; assert((bytes & 4095) == 0); for (off = 0; off < step; off++) { l1 = l+off; l2 = l1+words; for (w = 0; w < iwords; w++) { xorshift64star_next(); *l1 = *l2 = (unsigned long) rout; l1 += step; l2 += step; if ((w & 0xffff) == 0 && interactive) memtest_progress_step(w+iwords*off,words,'R'); } } }