1 | /* |
---|
2 | * Copyright (c) 1987, 1993 |
---|
3 | * The Regents of the University of California. All rights reserved. |
---|
4 | * |
---|
5 | * Redistribution and use in source and binary forms, with or without |
---|
6 | * modification, are permitted provided that the following conditions |
---|
7 | * are met: |
---|
8 | * 1. Redistributions of source code must retain the above copyright |
---|
9 | * notice, this list of conditions and the following disclaimer. |
---|
10 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer in the |
---|
12 | * documentation and/or other materials provided with the distribution. |
---|
13 | * 3. All advertising materials mentioning features or use of this software |
---|
14 | * must display the following acknowledgement: |
---|
15 | * This product includes software developed by the University of |
---|
16 | * California, Berkeley and its contributors. |
---|
17 | * 4. Neither the name of the University nor the names of its contributors |
---|
18 | * may be used to endorse or promote products derived from this software |
---|
19 | * without specific prior written permission. |
---|
20 | * |
---|
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
---|
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
---|
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
31 | * SUCH DAMAGE. |
---|
32 | * |
---|
33 | * @(#)malloc.h 8.5 (Berkeley) 5/3/95 |
---|
34 | * $Id$ |
---|
35 | */ |
---|
36 | |
---|
37 | #ifndef _SYS_MALLOC_H_ |
---|
38 | #define _SYS_MALLOC_H_ |
---|
39 | |
---|
40 | #include <rtems/rtems_bsdnet_internal.h> /* Ensure we get RTEMS malloc hooks */ |
---|
41 | #define KMEMSTATS |
---|
42 | |
---|
43 | /* |
---|
44 | * flags to malloc |
---|
45 | */ |
---|
46 | #define M_WAITOK 0x0000 |
---|
47 | #define M_NOWAIT 0x0001 |
---|
48 | #define M_KERNEL 0x0002 |
---|
49 | |
---|
50 | /* |
---|
51 | * Types of memory to be allocated |
---|
52 | */ |
---|
53 | #define M_FREE 0 /* should be on free list */ |
---|
54 | #define M_MBUF 1 /* mbuf */ |
---|
55 | #define M_DEVBUF 2 /* device driver memory */ |
---|
56 | #define M_SOCKET 3 /* socket structure */ |
---|
57 | #define M_PCB 4 /* protocol control block */ |
---|
58 | #define M_RTABLE 5 /* routing tables */ |
---|
59 | #define M_HTABLE 6 /* IMP host tables */ |
---|
60 | #define M_FTABLE 7 /* fragment reassembly header */ |
---|
61 | #define M_ZOMBIE 8 /* zombie proc status */ |
---|
62 | #define M_IFADDR 9 /* interface address */ |
---|
63 | #define M_SOOPTS 10 /* socket options */ |
---|
64 | #define M_SONAME 11 /* socket name */ |
---|
65 | #define M_NAMEI 12 /* namei path name buffer */ |
---|
66 | #define M_GPROF 13 /* kernel profiling buffer */ |
---|
67 | #define M_IOCTLOPS 14 /* ioctl data buffer */ |
---|
68 | #define M_MAPMEM 15 /* mapped memory descriptors */ |
---|
69 | #define M_CRED 16 /* credentials */ |
---|
70 | #define M_PGRP 17 /* process group header */ |
---|
71 | #define M_SESSION 18 /* session header */ |
---|
72 | #define M_IOV 19 /* large iov's */ |
---|
73 | #define M_MOUNT 20 /* vfs mount struct */ |
---|
74 | #define M_FHANDLE 21 /* network file handle */ |
---|
75 | #define M_NFSREQ 22 /* NFS request header */ |
---|
76 | #define M_NFSMNT 23 /* NFS mount structure */ |
---|
77 | #define M_NFSNODE 24 /* NFS vnode private part */ |
---|
78 | #define M_VNODE 25 /* Dynamically allocated vnodes */ |
---|
79 | #define M_CACHE 26 /* Dynamically allocated cache entries */ |
---|
80 | #define M_DQUOT 27 /* UFS quota entries */ |
---|
81 | #define M_UFSMNT 28 /* UFS mount structure */ |
---|
82 | #define M_SHM 29 /* SVID compatible shared memory segments */ |
---|
83 | #define M_VMMAP 30 /* VM map structures */ |
---|
84 | #define M_VMMAPENT 31 /* VM map entry structures */ |
---|
85 | #define M_VMOBJ 32 /* VM object structure */ |
---|
86 | #define M_VMOBJHASH 33 /* VM object hash structure */ |
---|
87 | #define M_VMPMAP 34 /* VM pmap */ |
---|
88 | #define M_VMPVENT 35 /* VM phys-virt mapping entry */ |
---|
89 | #define M_VMPAGER 36 /* XXX: VM pager struct */ |
---|
90 | #define M_VMPGDATA 37 /* XXX: VM pager private data */ |
---|
91 | #define M_FILE 38 /* Open file structure */ |
---|
92 | #define M_FILEDESC 39 /* Open file descriptor table */ |
---|
93 | #define M_LOCKF 40 /* Byte-range locking structures */ |
---|
94 | #define M_PROC 41 /* Proc structures */ |
---|
95 | #define M_SUBPROC 42 /* Proc sub-structures */ |
---|
96 | #define M_SEGMENT 43 /* Segment for LFS */ |
---|
97 | #define M_LFSNODE 44 /* LFS vnode private part */ |
---|
98 | #define M_FFSNODE 45 /* FFS vnode private part */ |
---|
99 | #define M_MFSNODE 46 /* MFS vnode private part */ |
---|
100 | #define M_NQLEASE 47 /* Nqnfs lease */ |
---|
101 | #define M_NQMHOST 48 /* Nqnfs host address table */ |
---|
102 | #define M_NETADDR 49 /* Export host address structure */ |
---|
103 | #define M_NFSSVC 50 /* Nfs server structure */ |
---|
104 | #define M_NFSUID 51 /* Nfs uid mapping structure */ |
---|
105 | #define M_NFSD 52 /* Nfs server daemon structure */ |
---|
106 | #define M_IPMOPTS 53 /* internet multicast options */ |
---|
107 | #define M_IPMADDR 54 /* internet multicast address */ |
---|
108 | #define M_IFMADDR 55 /* link-level multicast address */ |
---|
109 | #define M_MRTABLE 56 /* multicast routing tables */ |
---|
110 | #define M_ISOFSMNT 57 /* ISOFS mount structure */ |
---|
111 | #define M_ISOFSNODE 58 /* ISOFS vnode private part */ |
---|
112 | #define M_NFSRVDESC 59 /* NFS server socket descriptor */ |
---|
113 | #define M_NFSDIROFF 60 /* NFS directory offset data */ |
---|
114 | #define M_NFSBIGFH 61 /* NFS version 3 file handle */ |
---|
115 | #define M_MSDOSFSMNT 67 /* MSDOSFS mount structure */ |
---|
116 | #define M_MSDOSFSNODE 68 /* MSDOSFS vnode private part */ |
---|
117 | #define M_MSDOSFSFAT 69 /* MSDOSFS file allocation table */ |
---|
118 | #define M_DEVFSMNT 70 /* DEVFS mount structure */ |
---|
119 | #define M_DEVFSBACK 71 /* DEVFS Back node */ |
---|
120 | #define M_DEVFSFRONT 72 /* DEVFS Front node */ |
---|
121 | #define M_DEVFSNODE 73 /* DEVFS node */ |
---|
122 | #define M_TEMP 74 /* misc temporary data buffers */ |
---|
123 | #define M_TTYS 75 /* tty data structures */ |
---|
124 | #define M_GZIP 76 /* Gzip trees */ |
---|
125 | #define M_IPFW 77 /* IpFw/IpAcct chain's */ |
---|
126 | #define M_DEVL 78 /* isa_device lists in userconfig() */ |
---|
127 | #define M_PKTCLASS 79 /* structures used in packet classifier */ |
---|
128 | #define M_SYSCTL 80 /* sysctl internal magic */ |
---|
129 | #define M_SECA 81 /* security associations, key management */ |
---|
130 | #define M_BIOBUF 82 /* BIO buffer */ |
---|
131 | #define M_KTRACE 83 /* KTRACE */ |
---|
132 | #define M_SELECT 84 /* select() buffer */ |
---|
133 | #define M_CFS 85 /* Coda */ |
---|
134 | #define M_LAST 86 /* Must be last type + 1 */ |
---|
135 | |
---|
136 | #define INITKMEMNAMES { \ |
---|
137 | "free", /* 0 M_FREE */ \ |
---|
138 | "mbuf", /* 1 M_MBUF */ \ |
---|
139 | "devbuf", /* 2 M_DEVBUF */ \ |
---|
140 | "socket", /* 3 M_SOCKET */ \ |
---|
141 | "pcb", /* 4 M_PCB */ \ |
---|
142 | "routetbl", /* 5 M_RTABLE */ \ |
---|
143 | "hosttbl", /* 6 M_HTABLE */ \ |
---|
144 | "fragtbl", /* 7 M_FTABLE */ \ |
---|
145 | "zombie", /* 8 M_ZOMBIE */ \ |
---|
146 | "ifaddr", /* 9 M_IFADDR */ \ |
---|
147 | "soopts", /* 10 M_SOOPTS */ \ |
---|
148 | "soname", /* 11 M_SONAME */ \ |
---|
149 | "namei", /* 12 M_NAMEI */ \ |
---|
150 | "gprof", /* 13 M_GPROF */ \ |
---|
151 | "ioctlops", /* 14 M_IOCTLOPS */ \ |
---|
152 | "mapmem", /* 15 M_MAPMEM */ \ |
---|
153 | "cred", /* 16 M_CRED */ \ |
---|
154 | "pgrp", /* 17 M_PGRP */ \ |
---|
155 | "session", /* 18 M_SESSION */ \ |
---|
156 | "iov", /* 19 M_IOV */ \ |
---|
157 | "mount", /* 20 M_MOUNT */ \ |
---|
158 | "fhandle", /* 21 M_FHANDLE */ \ |
---|
159 | "NFS req", /* 22 M_NFSREQ */ \ |
---|
160 | "NFS mount", /* 23 M_NFSMNT */ \ |
---|
161 | "NFS node", /* 24 M_NFSNODE */ \ |
---|
162 | "vnodes", /* 25 M_VNODE */ \ |
---|
163 | "namecache", /* 26 M_CACHE */ \ |
---|
164 | "UFS quota", /* 27 M_DQUOT */ \ |
---|
165 | "UFS mount", /* 28 M_UFSMNT */ \ |
---|
166 | "shm", /* 29 M_SHM */ \ |
---|
167 | "VM map", /* 30 M_VMMAP */ \ |
---|
168 | "VM mapent", /* 31 M_VMMAPENT */ \ |
---|
169 | "VM object", /* 32 M_VMOBJ */ \ |
---|
170 | "VM objhash", /* 33 M_VMOBJHASH */ \ |
---|
171 | "VM pmap", /* 34 M_VMPMAP */ \ |
---|
172 | "VM pvmap", /* 35 M_VMPVENT */ \ |
---|
173 | "VM pager", /* 36 M_VMPAGER */ \ |
---|
174 | "VM pgdata", /* 37 M_VMPGDATA */ \ |
---|
175 | "file", /* 38 M_FILE */ \ |
---|
176 | "file desc", /* 39 M_FILEDESC */ \ |
---|
177 | "lockf", /* 40 M_LOCKF */ \ |
---|
178 | "proc", /* 41 M_PROC */ \ |
---|
179 | "subproc", /* 42 M_SUBPROC */ \ |
---|
180 | "LFS segment", /* 43 M_SEGMENT */ \ |
---|
181 | "LFS node", /* 44 M_LFSNODE */ \ |
---|
182 | "FFS node", /* 45 M_FFSNODE */ \ |
---|
183 | "MFS node", /* 46 M_MFSNODE */ \ |
---|
184 | "NQNFS Lease", /* 47 M_NQLEASE */ \ |
---|
185 | "NQNFS Host", /* 48 M_NQMHOST */ \ |
---|
186 | "Export Host", /* 49 M_NETADDR */ \ |
---|
187 | "NFS srvsock", /* 50 M_NFSSVC */ \ |
---|
188 | "NFS uid", /* 51 M_NFSUID */ \ |
---|
189 | "NFS daemon", /* 52 M_NFSD */ \ |
---|
190 | "ip_moptions", /* 53 M_IPMOPTS */ \ |
---|
191 | "in_multi", /* 54 M_IPMADDR */ \ |
---|
192 | "ether_multi", /* 55 M_IFMADDR */ \ |
---|
193 | "mrt", /* 56 M_MRTABLE */ \ |
---|
194 | "ISOFS mount", /* 57 M_ISOFSMNT */ \ |
---|
195 | "ISOFS node", /* 58 M_ISOFSNODE */ \ |
---|
196 | "NFSV3 srvdesc",/* 59 M_NFSRVDESC */ \ |
---|
197 | "NFSV3 diroff", /* 60 M_NFSDIROFF */ \ |
---|
198 | "NFSV3 bigfh", /* 61 M_NFSBIGFH */ \ |
---|
199 | NULL, \ |
---|
200 | NULL, NULL, NULL, NULL, \ |
---|
201 | "MSDOSFS mount",/* 67 M_MSDOSFSMNT */ \ |
---|
202 | "MSDOSFS node", /* 68 M_MSDOSFSNODE */ \ |
---|
203 | "MSDOSFS FAT", /* 69 M_MSDOSFSFAR */ \ |
---|
204 | "DEVFS mount", /* 70 M_DEVFSMNT */ \ |
---|
205 | "DEVFS back", /* 71 M_DEVFSBACK */ \ |
---|
206 | "DEVFS front", /* 72 M_DEVFSFRONT */ \ |
---|
207 | "DEVFS node", /* 73 M_DEVFSNODE */ \ |
---|
208 | "temp", /* 74 M_TEMP */ \ |
---|
209 | "ttys", /* 75 M_TTYS */ \ |
---|
210 | "Gzip trees", /* 76 M_GZIP */ \ |
---|
211 | "IpFw/IpAcct", /* 77 M_IPFW */ \ |
---|
212 | "isa_devlist", /* 78 M_DEVL */ \ |
---|
213 | "PktClass", /* 79 M_PKTCLASS */ \ |
---|
214 | "sysctl", /* 80 M_SYSCTL */ \ |
---|
215 | "key mgmt", /* 81 M_SECA */ \ |
---|
216 | "BIO buffer", /* 82 M_BIOBUF */ \ |
---|
217 | "KTRACE", /* 83 M_KTRACE */ \ |
---|
218 | "select", /* 84 M_SELECT */ \ |
---|
219 | "Coda", /* 85 M_CFS */ \ |
---|
220 | } |
---|
221 | |
---|
222 | struct kmemstats { |
---|
223 | long ks_inuse; /* # of packets of this type currently in use */ |
---|
224 | long ks_calls; /* total packets of this type ever allocated */ |
---|
225 | long ks_memuse; /* total memory held in bytes */ |
---|
226 | u_short ks_limblocks; /* number of times blocked for hitting limit */ |
---|
227 | u_short ks_mapblocks; /* number of times blocked for kernel map */ |
---|
228 | long ks_maxused; /* maximum number ever used */ |
---|
229 | long ks_limit; /* most that are allowed to exist */ |
---|
230 | long ks_size; /* sizes of this thing that are allocated */ |
---|
231 | long ks_spare; |
---|
232 | }; |
---|
233 | |
---|
234 | /* |
---|
235 | * Array of descriptors that describe the contents of each page |
---|
236 | */ |
---|
237 | struct kmemusage { |
---|
238 | short ku_indx; /* bucket index */ |
---|
239 | union { |
---|
240 | u_short freecnt;/* for small allocations, free pieces in page */ |
---|
241 | u_short pagecnt;/* for large allocations, pages alloced */ |
---|
242 | } ku_un; |
---|
243 | }; |
---|
244 | #define ku_freecnt ku_un.freecnt |
---|
245 | #define ku_pagecnt ku_un.pagecnt |
---|
246 | |
---|
247 | /* |
---|
248 | * Set of buckets for each size of memory block that is retained |
---|
249 | */ |
---|
250 | struct kmembuckets { |
---|
251 | caddr_t kb_next; /* list of free blocks */ |
---|
252 | caddr_t kb_last; /* last free block */ |
---|
253 | long kb_calls; /* total calls to allocate this size */ |
---|
254 | long kb_total; /* total number of blocks allocated */ |
---|
255 | long kb_totalfree; /* # of free elements in this bucket */ |
---|
256 | long kb_elmpercl; /* # of elements in this sized allocation */ |
---|
257 | long kb_highwat; /* high water mark */ |
---|
258 | long kb_couldfree; /* over high water mark and could free */ |
---|
259 | }; |
---|
260 | |
---|
261 | #ifdef _KERNEL |
---|
262 | #define MINALLOCSIZE (1 << MINBUCKET) |
---|
263 | #define BUCKETINDX(size) \ |
---|
264 | ((size) <= (MINALLOCSIZE * 128) \ |
---|
265 | ? (size) <= (MINALLOCSIZE * 8) \ |
---|
266 | ? (size) <= (MINALLOCSIZE * 2) \ |
---|
267 | ? (size) <= (MINALLOCSIZE * 1) \ |
---|
268 | ? (MINBUCKET + 0) \ |
---|
269 | : (MINBUCKET + 1) \ |
---|
270 | : (size) <= (MINALLOCSIZE * 4) \ |
---|
271 | ? (MINBUCKET + 2) \ |
---|
272 | : (MINBUCKET + 3) \ |
---|
273 | : (size) <= (MINALLOCSIZE* 32) \ |
---|
274 | ? (size) <= (MINALLOCSIZE * 16) \ |
---|
275 | ? (MINBUCKET + 4) \ |
---|
276 | : (MINBUCKET + 5) \ |
---|
277 | : (size) <= (MINALLOCSIZE * 64) \ |
---|
278 | ? (MINBUCKET + 6) \ |
---|
279 | : (MINBUCKET + 7) \ |
---|
280 | : (size) <= (MINALLOCSIZE * 2048) \ |
---|
281 | ? (size) <= (MINALLOCSIZE * 512) \ |
---|
282 | ? (size) <= (MINALLOCSIZE * 256) \ |
---|
283 | ? (MINBUCKET + 8) \ |
---|
284 | : (MINBUCKET + 9) \ |
---|
285 | : (size) <= (MINALLOCSIZE * 1024) \ |
---|
286 | ? (MINBUCKET + 10) \ |
---|
287 | : (MINBUCKET + 11) \ |
---|
288 | : (size) <= (MINALLOCSIZE * 8192) \ |
---|
289 | ? (size) <= (MINALLOCSIZE * 4096) \ |
---|
290 | ? (MINBUCKET + 12) \ |
---|
291 | : (MINBUCKET + 13) \ |
---|
292 | : (size) <= (MINALLOCSIZE * 16384) \ |
---|
293 | ? (MINBUCKET + 14) \ |
---|
294 | : (MINBUCKET + 15)) |
---|
295 | |
---|
296 | /* |
---|
297 | * Turn virtual addresses into kmem map indices |
---|
298 | */ |
---|
299 | #define kmemxtob(alloc) (kmembase + (alloc) * PAGE_SIZE) |
---|
300 | #define btokmemx(addr) (((caddr_t)(addr) - kmembase) / PAGE_SIZE) |
---|
301 | #define btokup(addr) (&kmemusage[(caddr_t)(addr) - kmembase >> PAGE_SHIFT]) |
---|
302 | |
---|
303 | /* |
---|
304 | * Macro versions for the usual cases of malloc/free |
---|
305 | */ |
---|
306 | #if defined(KMEMSTATS) || defined(DIAGNOSTIC) |
---|
307 | #define MALLOC(space, cast, size, type, flags) \ |
---|
308 | (space) = (cast)malloc((u_long)(size), type, flags) |
---|
309 | #define FREE(addr, type) free((addr), type) |
---|
310 | |
---|
311 | #else /* do not collect statistics */ |
---|
312 | #define MALLOC(space, cast, size, type, flags) { \ |
---|
313 | register struct kmembuckets *kbp = &bucket[BUCKETINDX(size)]; \ |
---|
314 | long s = splimp(); \ |
---|
315 | if (kbp->kb_next == NULL) { \ |
---|
316 | (space) = (cast)malloc((u_long)(size), type, flags); \ |
---|
317 | } else { \ |
---|
318 | (space) = (cast)kbp->kb_next; \ |
---|
319 | kbp->kb_next = *(caddr_t *)(space); \ |
---|
320 | } \ |
---|
321 | splx(s); \ |
---|
322 | } |
---|
323 | |
---|
324 | #define FREE(addr, type) { \ |
---|
325 | register struct kmembuckets *kbp; \ |
---|
326 | register struct kmemusage *kup = btokup(addr); \ |
---|
327 | long s = splimp(); \ |
---|
328 | if (1 << kup->ku_indx > MAXALLOCSAVE) { \ |
---|
329 | free((addr), type); \ |
---|
330 | } else { \ |
---|
331 | kbp = &bucket[kup->ku_indx]; \ |
---|
332 | if (kbp->kb_next == NULL) \ |
---|
333 | kbp->kb_next = (caddr_t)(addr); \ |
---|
334 | else \ |
---|
335 | *(caddr_t *)(kbp->kb_last) = (caddr_t)(addr); \ |
---|
336 | *(caddr_t *)(addr) = NULL; \ |
---|
337 | kbp->kb_last = (caddr_t)(addr); \ |
---|
338 | } \ |
---|
339 | splx(s); \ |
---|
340 | } |
---|
341 | #endif /* do not collect statistics */ |
---|
342 | |
---|
343 | extern struct kmemstats kmemstats[]; |
---|
344 | extern struct kmemusage *kmemusage; |
---|
345 | extern char *kmembase; |
---|
346 | extern struct kmembuckets bucket[]; |
---|
347 | |
---|
348 | void free (void *addr, int type); |
---|
349 | void *malloc (size_t size, int type, int flags); |
---|
350 | #endif /* _KERNEL */ |
---|
351 | |
---|
352 | #endif /* !_SYS_MALLOC_H_ */ |
---|