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