Whamcloud - gitweb
b=15967
[fs/lustre-release.git] / lustre / tests / memhog.c
1 #include <sys/types.h>
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #define CHUNK (128 * 1024)
7
8 void usage(const char *prog, FILE *out)
9 {
10         fprintf(out, "usage: %s allocsize\n", prog);
11         fprintf(out, " allocsize is kbytes, or number[KMGP] (P = pages)\n");
12         exit(out == stderr);
13 }
14
15 int main(int argc, char *argv[])
16 {
17         long long kbtotal = 0, kballoc;
18         int i, j, k, numchunk, alloc, sum, rc = 0;
19         char **mem, *tmp;
20
21         if (argc == 2) {
22                 char *end = NULL;
23                 kbtotal = strtoull(argv[1], &end, 0);
24
25                 switch(*end) {
26                 case 'g':
27                 case 'G':
28                         kbtotal *= 1024;
29                 case 'm':
30                 case 'M':
31                         kbtotal *= 1024;
32                 case '\0':
33                 case 'k':
34                 case 'K':
35                         break;
36                 case 'p':
37                 case 'P':
38                         kbtotal *= 4;
39                         break;
40                 default:
41                         usage(argv[0], stderr);
42                         break;
43                 }
44         }
45
46         if (argc != 2 || kbtotal == 0)
47                 usage(argv[0], stderr);
48
49         numchunk = (kbtotal + CHUNK - 1) / CHUNK;
50         mem = calloc(numchunk, sizeof(*mem));
51         if (mem == NULL) {
52                 fprintf(stderr, "error allocating initial chunk array\n");
53                 exit(-1);
54         }
55
56         alloc = CHUNK;
57         printf("[%d] allocating %lld kbytes in %u kbyte chunks\n",
58                getpid(), kbtotal, alloc);
59         for (i = kballoc = 0; i < numchunk && alloc > 0; i++, kballoc += alloc){
60                 if (kbtotal - kballoc < alloc)
61                         alloc = kbtotal - kballoc;
62
63                 while (alloc > 0 && (mem[i] = malloc(alloc * 1024)) == NULL) {
64                         fprintf(stderr, "malloc(%u) failed (%lld/%lld)\n",
65                                 alloc * 1024, kballoc, kbtotal);
66                         alloc /= 2;
67                 }
68                 if (alloc == 0)
69                         break;
70
71                 printf("touching %p ([%lld-%lld]/%lld)\n", mem[i], kballoc,
72                        kballoc + alloc - 1, kbtotal);
73                 for (j = 0, tmp = mem[i]; j < alloc; j += 4) {
74                         for (k = 0, sum = 0; k < 4095; k++, tmp++)
75                                 sum += *tmp;
76                         *tmp = sum;
77                 }
78         }
79         if (kballoc == 0)
80                 exit(-2);
81
82         kbtotal = kballoc;
83         printf("touched %lld kbytes\n", kballoc);
84
85         alloc = CHUNK;
86         printf("verifying %lld kbytes in %u kbyte chunks\n", kbtotal, alloc);
87         for (i = kballoc = 0; i < numchunk; i++, kballoc += alloc) {
88                 if (kbtotal - kballoc < alloc)
89                         alloc = kbtotal - kballoc;
90
91                 tmp = mem[i];
92                 if (tmp != NULL) {
93                         printf("verifying %p (%lld/%lld)\n",
94                                tmp, kballoc, kbtotal);
95                         for (j = 0; j < alloc; j += 4) {
96                                 for (k = 0, sum = 0; k < 4095; k++, tmp++)
97                                         sum += *tmp;
98                                 if (*tmp != sum) {
99                                         fprintf(stderr, "sum %x != %x at %p\n",
100                                                 *tmp, sum, tmp - 4092);
101                                         rc++;
102                                 }
103                         }
104                 }
105         }
106         printf("verified %lld kbytes\n", kballoc);
107         return rc;
108 }