kernel/vinum: Fix -Wundef.
[dragonfly.git] / sys / dev / raid / vinum / vinummemory.c
blobd602b1cb3418fdf052482245cbbaf08d97266d1e
1 /*-
2 * Copyright (c) 1997, 1998
3 * Nan Yang Computer Services Limited. All rights reserved.
5 * This software is distributed under the so-called ``Berkeley
6 * License'':
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Nan Yang Computer
19 * Services Limited.
20 * 4. Neither the name of the Company nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * This software is provided ``as is'', and any express or implied
25 * warranties, including, but not limited to, the implied warranties of
26 * merchantability and fitness for a particular purpose are disclaimed.
27 * In no event shall the company or contributors be liable for any
28 * direct, indirect, incidental, special, exemplary, or consequential
29 * damages (including, but not limited to, procurement of substitute
30 * goods or services; loss of use, data, or profits; or business
31 * interruption) however caused and on any theory of liability, whether
32 * in contract, strict liability, or tort (including negligence or
33 * otherwise) arising in any way out of the use of this software, even if
34 * advised of the possibility of such damage.
36 * $Id: vinummemory.c,v 1.25 2000/05/04 01:57:48 grog Exp grog $
37 * $FreeBSD: src/sys/dev/vinum/vinummemory.c,v 1.22.2.1 2000/06/02 04:26:11 grog Exp $
40 #include "vinumhdr.h"
42 #ifdef VINUMDEBUG
44 #include "request.h"
45 extern struct rqinfo rqinfo[];
46 extern struct rqinfo *rqip;
47 int rqinfo_size = RQINFO_SIZE; /* for debugger */
49 #define LongJmp longjmp /* just use the kernel function */
50 #endif
52 /* find the base name of a path name */
53 char *
54 basename(char *file)
56 char *f = rindex(file, '/'); /* chop off dirname if present */
58 if (f == NULL)
59 return file;
60 else
61 return ++f; /* skip the / */
64 void
65 expand_table(void **table, int oldsize, int newsize)
67 if (newsize > oldsize) {
68 int *temp;
70 crit_enter();
71 temp = (int *) Malloc(newsize); /* allocate a new table */
72 CHECKALLOC(temp, "vinum: Can't expand table\n");
73 bzero((char *) temp, newsize); /* clean it all out */
74 if (*table != NULL) { /* already something there, */
75 bcopy((char *) *table, (char *) temp, oldsize); /* copy it to the old table */
76 Free(*table);
78 *table = temp;
79 crit_exit();
83 #ifdef VINUMDEBUG /* XXX debug */
84 #define MALLOCENTRIES 16384
85 int malloccount = 0;
86 int highwater = 0; /* highest index ever allocated */
87 struct mc malloced[MALLOCENTRIES];
89 #define FREECOUNT 64
90 int freecount = FREECOUNT; /* for debugger */
91 int lastfree = 0;
92 struct mc freeinfo[FREECOUNT];
94 int total_malloced;
95 static int mallocseq = 0;
97 caddr_t
98 MMalloc(int size, char *file, int line)
100 caddr_t result;
101 int i;
103 if (malloccount >= MALLOCENTRIES) { /* too many */
104 log(LOG_ERR, "vinum: can't allocate table space to trace memory allocation");
105 return 0; /* can't continue */
107 /* Wait for malloc if we can */
108 result = kmalloc(size, M_DEVBUF, mycpu->gd_intr_nesting_level == 0 ? M_WAITOK : M_INTWAIT);
109 if (result == NULL)
110 log(LOG_ERR, "vinum: can't allocate %d bytes from %s:%d\n", size, file, line);
111 else {
112 crit_enter();
113 for (i = 0; i < malloccount; i++) {
114 if (((result + size) > malloced[i].address)
115 && (result < malloced[i].address + malloced[i].size)) /* overlap */
116 Debugger("Malloc overlap");
118 if (result) {
119 char *f = basename(file);
121 i = malloccount++;
122 total_malloced += size;
123 microtime(&malloced[i].time);
124 malloced[i].seq = mallocseq++;
125 malloced[i].size = size;
126 malloced[i].line = line;
127 malloced[i].address = result;
128 bcopy(f, malloced[i].file, min(strlen(f), MCFILENAMELEN - 1));
129 malloced[i].file[MCFILENAMELEN - 1] = '\0';
131 if (malloccount > highwater)
132 highwater = malloccount;
133 crit_exit();
135 return result;
138 void
139 FFree(void *mem, char *file, int line)
141 int i;
143 crit_enter();
144 for (i = 0; i < malloccount; i++) {
145 if ((caddr_t) mem == malloced[i].address) { /* found it */
146 bzero(mem, malloced[i].size); /* XXX */
147 kfree(mem, M_DEVBUF);
148 malloccount--;
149 total_malloced -= malloced[i].size;
150 if (debug & DEBUG_MEMFREE) { /* keep track of recent frees */
151 char *f = rindex(file, '/'); /* chop off dirname if present */
153 if (f == NULL)
154 f = file;
155 else
156 f++; /* skip the / */
158 microtime(&freeinfo[lastfree].time);
159 freeinfo[lastfree].seq = malloced[i].seq;
160 freeinfo[lastfree].size = malloced[i].size;
161 freeinfo[lastfree].line = line;
162 freeinfo[lastfree].address = mem;
163 bcopy(f, freeinfo[lastfree].file, min(strlen(f), MCFILENAMELEN - 1));
164 freeinfo[lastfree].file[MCFILENAMELEN - 1] = '\0';
165 if (++lastfree == FREECOUNT)
166 lastfree = 0;
168 if (i < malloccount) /* more coming after */
169 bcopy(&malloced[i + 1], &malloced[i], (malloccount - i) * sizeof(struct mc));
170 crit_exit();
171 return;
174 log(LOG_ERR,
175 "Freeing unallocated data at 0x%p from %s, line %d\n",
176 mem,
177 file,
178 line);
179 Debugger("Free");
180 crit_exit();
183 void
184 vinum_meminfo(caddr_t data)
186 struct meminfo *m = (struct meminfo *) data;
188 m->mallocs = malloccount;
189 m->total_malloced = total_malloced;
190 m->malloced = malloced;
191 m->highwater = highwater;
195 vinum_mallocinfo(caddr_t data)
197 struct mc *m = (struct mc *) data;
198 unsigned int ent = m->seq; /* index of entry to return */
200 if (ent >= malloccount)
201 return ENOENT;
202 m->address = malloced[ent].address;
203 m->size = malloced[ent].size;
204 m->line = malloced[ent].line;
205 m->seq = malloced[ent].seq;
206 bcopy(malloced[ent].file, m->file, MCFILENAMELEN);
207 return 0;
211 * return the nth request trace buffer entry. This
212 * is indexed back from the current entry (which
213 * has index 0)
216 vinum_rqinfo(caddr_t data)
218 struct rqinfo *rq = (struct rqinfo *) data;
219 int ent = *(int *) data; /* 1st word is index */
220 int lastent = rqip - rqinfo; /* entry number of current entry */
222 if (ent >= RQINFO_SIZE) /* out of the table */
223 return ENOENT;
224 if ((ent = lastent - ent - 1) < 0)
225 ent += RQINFO_SIZE; /* roll over backwards */
226 bcopy(&rqinfo[ent], rq, sizeof(struct rqinfo));
227 return 0;
229 #endif