xref: /original-bsd/sys/sys/malloc.h (revision 780b584d)
1 /*
2  * Copyright (c) 1987 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  *	@(#)malloc.h	7.12 (Berkeley) 10/26/89
18  */
19 
20 #define KMEMSTATS
21 
22 /*
23  * flags to malloc
24  */
25 #define M_WAITOK	0x0000
26 #define M_NOWAIT	0x0001
27 
28 /*
29  * Types of memory to be allocated
30  */
31 #define	M_FREE		0	/* should be on free list */
32 #define M_MBUF		1	/* mbuf */
33 #define M_DEVBUF	2	/* device driver memory */
34 #define	M_SOCKET	3	/* socket structure */
35 #define	M_PCB		4	/* protocol control block */
36 #define	M_RTABLE	5	/* routing tables */
37 #define	M_HTABLE	6	/* IMP host tables */
38 #define	M_FTABLE	7	/* fragment reassembly header */
39 #define	M_ZOMBIE	8	/* zombie proc status */
40 #define	M_IFADDR	9	/* interface address */
41 #define	M_SOOPTS	10	/* socket options */
42 #define	M_SONAME	11	/* socket name */
43 #define M_NAMEI		12	/* namei path name buffer */
44 #define M_GPROF		13	/* kernel profiling buffer */
45 #define M_IOCTLOPS	14	/* ioctl data buffer */
46 #define M_SUPERBLK	15	/* super block data */
47 #define M_CRED		16	/* credentials */
48 #define	M_PGRP		17	/* process group header */
49 #define	M_SESSION	18	/* session header */
50 #define M_IOV		19	/* large iov's */
51 #define M_MOUNT		20	/* vfs mount struct */
52 #define M_FHANDLE	21	/* network file handle */
53 #define	M_NFSREQ	22	/* NFS request header */
54 #define	M_NFSMNT	23	/* NFS mount structure */
55 #define	M_VNODE		24	/* Dynamically allocated vnodes */
56 #define M_TEMP		49	/* misc temporary data buffers */
57 #define M_LAST		50
58 
59 struct kmemstats {
60 	long	ks_inuse;	/* # of packets of this type currently in use */
61 	long	ks_calls;	/* total packets of this type ever allocated */
62 	long 	ks_memuse;	/* total memory held in bytes */
63 	u_short	ks_limblocks;	/* number of times blocked for hitting limit */
64 	u_short	ks_mapblocks;	/* number of times blocked for kernel map */
65 	long	ks_maxused;	/* maximum number ever used */
66 	long	ks_limit;	/* most that are allowed to exist */
67 };
68 
69 /*
70  * Array of descriptors that describe the contents of each page
71  */
72 struct kmemusage {
73 	short ku_indx;		/* bucket index */
74 	union {
75 		u_short freecnt;/* for small allocations, free pieces in page */
76 		u_short pagecnt;/* for large allocations, pages alloced */
77 	} ku_un;
78 };
79 #define ku_freecnt ku_un.freecnt
80 #define ku_pagecnt ku_un.pagecnt
81 
82 /*
83  * Set of buckets for each size of memory block that is retained
84  */
85 struct kmembuckets {
86 	caddr_t kb_next;	/* list of free blocks */
87 	long	kb_calls;	/* total calls to allocate this size */
88 	long	kb_total;	/* total number of blocks allocated */
89 	long	kb_totalfree;	/* # of free elements in this bucket */
90 	long	kb_elmpercl;	/* # of elements in this sized allocation */
91 	long	kb_highwat;	/* high water mark */
92 	long	kb_couldfree;	/* over high water mark and could free */
93 };
94 
95 #ifdef KERNEL
96 #define MINALLOCSIZE	(1 << MINBUCKET)
97 #define BUCKETINDX(size) \
98 	(size) <= (MINALLOCSIZE * 128) \
99 		? (size) <= (MINALLOCSIZE * 8) \
100 			? (size) <= (MINALLOCSIZE * 2) \
101 				? (size) <= (MINALLOCSIZE * 1) \
102 					? (MINBUCKET + 0) \
103 					: (MINBUCKET + 1) \
104 				: (size) <= (MINALLOCSIZE * 4) \
105 					? (MINBUCKET + 2) \
106 					: (MINBUCKET + 3) \
107 			: (size) <= (MINALLOCSIZE* 32) \
108 				? (size) <= (MINALLOCSIZE * 16) \
109 					? (MINBUCKET + 4) \
110 					: (MINBUCKET + 5) \
111 				: (size) <= (MINALLOCSIZE * 64) \
112 					? (MINBUCKET + 6) \
113 					: (MINBUCKET + 7) \
114 		: (size) <= (MINALLOCSIZE * 2048) \
115 			? (size) <= (MINALLOCSIZE * 512) \
116 				? (size) <= (MINALLOCSIZE * 256) \
117 					? (MINBUCKET + 8) \
118 					: (MINBUCKET + 9) \
119 				: (size) <= (MINALLOCSIZE * 1024) \
120 					? (MINBUCKET + 10) \
121 					: (MINBUCKET + 11) \
122 			: (size) <= (MINALLOCSIZE * 8192) \
123 				? (size) <= (MINALLOCSIZE * 4096) \
124 					? (MINBUCKET + 12) \
125 					: (MINBUCKET + 13) \
126 				: (size) <= (MINALLOCSIZE * 16384) \
127 					? (MINBUCKET + 14) \
128 					: (MINBUCKET + 15)
129 
130 /*
131  * Turn virtual addresses into kmem map indicies
132  */
133 #define kmemxtob(alloc)	(kmembase + (alloc) * NBPG)
134 #define btokmemx(addr)	(((caddr_t)(addr) - kmembase) / NBPG)
135 #define btokup(addr)	(&kmemusage[((caddr_t)(addr) - kmembase) >> CLSHIFT])
136 
137 /*
138  * Macro versions for the usual cases of malloc/free
139  */
140 #ifdef KMEMSTATS
141 #define MALLOC(space, cast, size, type, flags) \
142 	(space) = (cast)malloc((u_long)(size), type, flags)
143 #define FREE(addr, type) free((caddr_t)(addr), type)
144 
145 #else /* do not collect statistics */
146 #define MALLOC(space, cast, size, type, flags) { \
147 	register struct kmembuckets *kbp = &bucket[BUCKETINDX(size)]; \
148 	long s = splimp(); \
149 	if (kbp->kb_next == NULL) { \
150 		(space) = (cast)malloc((u_long)(size), type, flags); \
151 	} else { \
152 		(space) = (cast)kbp->kb_next; \
153 		kbp->kb_next = *(caddr_t *)(space); \
154 	} \
155 	splx(s); \
156 }
157 
158 #define FREE(addr, type) { \
159 	register struct kmembuckets *kbp; \
160 	register struct kmemusage *kup = btokup(addr); \
161 	long s = splimp(); \
162 	if (1 << kup->ku_indx > MAXALLOCSAVE) { \
163 		free((caddr_t)(addr), type); \
164 	} else { \
165 		kbp = &bucket[kup->ku_indx]; \
166 		*(caddr_t *)(addr) = kbp->kb_next; \
167 		kbp->kb_next = (caddr_t)(addr); \
168 	} \
169 	splx(s); \
170 }
171 #endif /* do not collect statistics */
172 
173 extern struct kmemstats kmemstats[];
174 extern struct kmemusage *kmemusage;
175 extern char kmembase[];
176 extern struct kmembuckets bucket[];
177 extern qaddr_t malloc();
178 extern void free();
179 #endif KERNEL
180