Whamcloud - gitweb
LU-1303 lod: introduce lod device
[fs/lustre-release.git] / lustre / tests / memhog.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  */
34
35 #include <sys/types.h>
36 #include <unistd.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39
40 #define CHUNK (128 * 1024)
41
42 void usage(const char *prog, FILE *out)
43 {
44         fprintf(out, "usage: %s allocsize\n", prog);
45         fprintf(out, " allocsize is kbytes, or number[KMGP] (P = pages)\n");
46         exit(out == stderr);
47 }
48
49 int main(int argc, char *argv[])
50 {
51         long long kbtotal = 0, kballoc;
52         int i, j, k, numchunk, alloc, sum, rc = 0;
53         char **mem, *tmp;
54
55         if (argc == 2) {
56                 char *end = NULL;
57                 kbtotal = strtoull(argv[1], &end, 0);
58
59                 switch(*end) {
60                 case 'g':
61                 case 'G':
62                         kbtotal *= 1024;
63                 case 'm':
64                 case 'M':
65                         kbtotal *= 1024;
66                 case '\0':
67                 case 'k':
68                 case 'K':
69                         break;
70                 case 'p':
71                 case 'P':
72                         kbtotal *= 4;
73                         break;
74                 default:
75                         usage(argv[0], stderr);
76                         break;
77                 }
78         }
79
80         if (argc != 2 || kbtotal == 0)
81                 usage(argv[0], stderr);
82
83         numchunk = (kbtotal + CHUNK - 1) / CHUNK;
84         mem = calloc(numchunk, sizeof(*mem));
85         if (mem == NULL) {
86                 fprintf(stderr, "error allocating initial chunk array\n");
87                 exit(-1);
88         }
89
90         alloc = CHUNK;
91         printf("[%d] allocating %lld kbytes in %u kbyte chunks\n",
92                getpid(), kbtotal, alloc);
93         for (i = kballoc = 0; i < numchunk && alloc > 0; i++, kballoc += alloc){
94                 if (kbtotal - kballoc < alloc)
95                         alloc = kbtotal - kballoc;
96
97                 while (alloc > 0 && (mem[i] = malloc(alloc * 1024)) == NULL) {
98                         fprintf(stderr, "malloc(%u) failed (%lld/%lld)\n",
99                                 alloc * 1024, kballoc, kbtotal);
100                         alloc /= 2;
101                 }
102                 if (alloc == 0)
103                         break;
104
105                 printf("touching %p ([%lld-%lld]/%lld)\n", mem[i], kballoc,
106                        kballoc + alloc - 1, kbtotal);
107                 for (j = 0, tmp = mem[i]; j < alloc; j += 4) {
108                         for (k = 0, sum = 0; k < 4095; k++, tmp++)
109                                 sum += *tmp;
110                         *tmp = sum;
111                 }
112         }
113         if (kballoc == 0)
114                 exit(-2);
115
116         kbtotal = kballoc;
117         printf("touched %lld kbytes\n", kballoc);
118
119         alloc = CHUNK;
120         printf("verifying %lld kbytes in %u kbyte chunks\n", kbtotal, alloc);
121         for (i = kballoc = 0; i < numchunk; i++, kballoc += alloc) {
122                 if (kbtotal - kballoc < alloc)
123                         alloc = kbtotal - kballoc;
124
125                 tmp = mem[i];
126                 if (tmp != NULL) {
127                         printf("verifying %p (%lld/%lld)\n",
128                                tmp, kballoc, kbtotal);
129                         for (j = 0; j < alloc; j += 4) {
130                                 for (k = 0, sum = 0; k < 4095; k++, tmp++)
131                                         sum += *tmp;
132                                 if (*tmp != sum) {
133                                         fprintf(stderr, "sum %x != %x at %p\n",
134                                                 *tmp, sum, tmp - 4092);
135                                         rc++;
136                                 }
137                         }
138                 }
139         }
140         printf("verified %lld kbytes\n", kballoc);
141         return rc;
142 }