]> git.saurik.com Git - redis.git/commitdiff
Hem... actual memtest.c file added.
authorantirez <antirez@gmail.com>
Fri, 16 Mar 2012 16:21:49 +0000 (17:21 +0100)
committerantirez <antirez@gmail.com>
Fri, 16 Mar 2012 16:21:49 +0000 (17:21 +0100)
src/memtest.c [new file with mode: 0644]

diff --git a/src/memtest.c b/src/memtest.c
new file mode 100644 (file)
index 0000000..a0e76f1
--- /dev/null
@@ -0,0 +1,91 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+#include <errno.h>
+
+#if (ULONG_MAX == 4294967295UL)
+#define MEMTEST_32BIT
+#elif (ULONG_MAX == 18446744073709551615ULL)
+#define MEMTEST_64BIT
+#else
+#error "ULONG_MAX value not supported."
+#endif
+
+/* 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(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;
+        }
+    }
+}
+
+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 ++;
+    }
+}
+
+void memtest_test(size_t megabytes, int passes) {
+    size_t bytes = megabytes*1024*1024;
+    unsigned long *m = malloc(bytes);
+    int pass = 0;
+
+    if (m == NULL) {
+        fprintf(stderr,"Unable to allocate %zu megabytes: %s",
+            megabytes, strerror(errno));
+        exit(1);
+    }
+    while (pass != passes) {
+        pass++;
+        printf("PASS %d... ", pass);
+        fflush(stdout);
+        memtest_fill(m,bytes);
+        memtest_compare(m,bytes);
+        printf("ok\n");
+    }
+}
+
+void memtest(size_t megabytes, int passes) {
+    memtest_test(megabytes,passes);
+    printf("\nYour memory passed this test.\n");
+    printf("Please if you are stil in doubt use the following two tools:\n");
+    printf("1) memtest86: http://www.memtest86.com/\n");
+    printf("2) memtester: http://pyropus.ca/software/memtester/\n");
+    exit(0);
+}