]>
git.saurik.com Git - redis.git/blob - src/memtest.c
10 #if (ULONG_MAX == 4294967295UL)
12 #elif (ULONG_MAX == 18446744073709551615ULL)
15 #error "ULONG_MAX value not supported."
18 static struct winsize ws
;
19 size_t progress_printed
; /* Printed chars in screen-wide progress bar. */
20 size_t progress_full
; /* How many chars to write to fill the progress bar. */
22 void memtest_progress_start(char *title
, int pass
) {
25 printf("\x1b[H\x1b[2J"); /* Cursor home, clear screen. */
27 for (j
= 0; j
< ws
.ws_col
*ws
.ws_row
; j
++) printf(".");
28 printf("\x1b[H\x1b[2K"); /* Cursor home, clear current line. */
29 printf("%s [%d]\n", title
, pass
); /* Print title. */
31 progress_full
= ws
.ws_col
*(ws
.ws_row
-1);
35 void memtest_progress_end(void) {
36 printf("\x1b[H\x1b[2J"); /* Cursor home, clear screen. */
39 void memtest_progress_step(size_t curr
, size_t size
, char c
) {
40 size_t chars
= (curr
*progress_full
)/size
, j
;
42 for (j
= 0; j
< chars
-progress_printed
; j
++) {
49 /* Fill words stepping a single page at every write, so we continue to
50 * touch all the pages in the smallest amount of time reducing the
51 * effectiveness of caches, and making it hard for the OS to transfer
52 * pages on the swap. */
53 void memtest_fill(unsigned long *l
, size_t bytes
) {
54 unsigned long step
= 4096/sizeof(unsigned long);
55 unsigned long words
= bytes
/sizeof(unsigned long)/2;
56 unsigned long iwords
= words
/step
; /* words per iteration */
57 unsigned long off
, w
, *l1
, *l2
;
59 assert((bytes
& 4095) == 0);
60 for (off
= 0; off
< step
; off
++) {
63 for (w
= 0; w
< iwords
; w
++) {
65 *l1
= *l2
= ((unsigned long) (rand()&0xffff)) |
66 (((unsigned long) (rand()&0xffff)) << 16);
68 *l1
= *l2
= ((unsigned long) (rand()&0xffff)) |
69 (((unsigned long) (rand()&0xffff)) << 16) |
70 (((unsigned long) (rand()&0xffff)) << 32) |
71 (((unsigned long) (rand()&0xffff)) << 48);
75 if ((w
& 0xffff) == 0)
76 memtest_progress_step(w
+iwords
*off
,words
,'+');
81 void memtest_compare(unsigned long *l
, size_t bytes
) {
82 unsigned long words
= bytes
/sizeof(unsigned long)/2;
83 unsigned long w
, *l1
, *l2
;
85 assert((bytes
& 4095) == 0);
88 for (w
= 0; w
< words
; w
++) {
90 printf("\n*** MEMORY ERROR DETECTED: %p != %p (%lu vs %lu)\n",
91 (void*)l1
, (void*)l2
, *l1
, *l2
);
96 if ((w
& 0xffff) == 0) memtest_progress_step(w
,words
,'=');
100 void memtest_test(size_t megabytes
, int passes
) {
101 size_t bytes
= megabytes
*1024*1024;
102 unsigned long *m
= malloc(bytes
);
106 fprintf(stderr
,"Unable to allocate %zu megabytes: %s",
107 megabytes
, strerror(errno
));
110 while (pass
!= passes
) {
112 memtest_progress_start("Random fill",pass
);
113 memtest_fill(m
,bytes
);
114 memtest_progress_end();
115 for (j
= 0; j
< 4; j
++) {
116 memtest_progress_start("Compare",pass
);
117 memtest_compare(m
,bytes
);
118 memtest_progress_end();
123 void memtest(size_t megabytes
, int passes
) {
124 if (ioctl(1, TIOCGWINSZ
, &ws
) == -1) {
128 memtest_test(megabytes
,passes
);
129 printf("\nYour memory passed this test.\n");
130 printf("Please if you are stil in doubt use the following two tools:\n");
131 printf("1) memtest86: http://www.memtest86.com/\n");
132 printf("2) memtester: http://pyropus.ca/software/memtester/\n");