]>
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
-2); j
++) printf(".");
28 printf("Please keep the test running several minutes per GB of memory.\n");
29 printf("Also check http://www.memtest86.com/ and http://pyropus.ca/software/memtester/");
30 printf("\x1b[H\x1b[2K"); /* Cursor home, clear current line. */
31 printf("%s [%d]\n", title
, pass
); /* Print title. */
33 progress_full
= ws
.ws_col
*(ws
.ws_row
-3);
37 void memtest_progress_end(void) {
38 printf("\x1b[H\x1b[2J"); /* Cursor home, clear screen. */
41 void memtest_progress_step(size_t curr
, size_t size
, char c
) {
42 size_t chars
= (curr
*progress_full
)/size
, j
;
44 for (j
= 0; j
< chars
-progress_printed
; j
++) {
51 /* Fill words stepping a single page at every write, so we continue to
52 * touch all the pages in the smallest amount of time reducing the
53 * effectiveness of caches, and making it hard for the OS to transfer
54 * pages on the swap. */
55 void memtest_fill(unsigned long *l
, size_t bytes
) {
56 unsigned long step
= 4096/sizeof(unsigned long);
57 unsigned long words
= bytes
/sizeof(unsigned long)/2;
58 unsigned long iwords
= words
/step
; /* words per iteration */
59 unsigned long off
, w
, *l1
, *l2
;
61 assert((bytes
& 4095) == 0);
62 for (off
= 0; off
< step
; off
++) {
65 for (w
= 0; w
< iwords
; w
++) {
67 *l1
= *l2
= ((unsigned long) (rand()&0xffff)) |
68 (((unsigned long) (rand()&0xffff)) << 16);
70 *l1
= *l2
= ((unsigned long) (rand()&0xffff)) |
71 (((unsigned long) (rand()&0xffff)) << 16) |
72 (((unsigned long) (rand()&0xffff)) << 32) |
73 (((unsigned long) (rand()&0xffff)) << 48);
77 if ((w
& 0xffff) == 0)
78 memtest_progress_step(w
+iwords
*off
,words
,'+');
83 void memtest_compare(unsigned long *l
, size_t bytes
) {
84 unsigned long words
= bytes
/sizeof(unsigned long)/2;
85 unsigned long w
, *l1
, *l2
;
87 assert((bytes
& 4095) == 0);
90 for (w
= 0; w
< words
; w
++) {
92 printf("\n*** MEMORY ERROR DETECTED: %p != %p (%lu vs %lu)\n",
93 (void*)l1
, (void*)l2
, *l1
, *l2
);
98 if ((w
& 0xffff) == 0) memtest_progress_step(w
,words
,'=');
102 void memtest_test(size_t megabytes
, int passes
) {
103 size_t bytes
= megabytes
*1024*1024;
104 unsigned long *m
= malloc(bytes
);
108 fprintf(stderr
,"Unable to allocate %zu megabytes: %s",
109 megabytes
, strerror(errno
));
112 while (pass
!= passes
) {
114 memtest_progress_start("Random fill",pass
);
115 memtest_fill(m
,bytes
);
116 memtest_progress_end();
117 for (j
= 0; j
< 4; j
++) {
118 memtest_progress_start("Compare",pass
);
119 memtest_compare(m
,bytes
);
120 memtest_progress_end();
125 void memtest(size_t megabytes
, int passes
) {
126 if (ioctl(1, TIOCGWINSZ
, &ws
) == -1) {
130 memtest_test(megabytes
,passes
);
131 printf("\nYour memory passed this test.\n");
132 printf("Please if you are still in doubt use the following two tools:\n");
133 printf("1) memtest86: http://www.memtest86.com/\n");
134 printf("2) memtester: http://pyropus.ca/software/memtester/\n");