xref: /original-bsd/sys/sys/malloc.h (revision 2674464e)
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.15 (Berkeley) 05/09/90
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_CACHE		25	/* Dynamically allocated cache entries */
57 #define	M_DQUOT		26	/* UFS quota entries */
58 #define	M_UFSMNT	27	/* UFS mount structure */
59 #define	M_MAPMEM	28	/* mapped memory descriptors */
60 #define	M_SHM		29	/* SVID compatible shared memory segments */
61 #define M_TEMP		49	/* misc temporary data buffers */
62 #define M_LAST		50
63 
64 struct kmemstats {
65 	long	ks_inuse;	/* # of packets of this type currently in use */
66 	long	ks_calls;	/* total packets of this type ever allocated */
67 	long 	ks_memuse;	/* total memory held in bytes */
68 	u_short	ks_limblocks;	/* number of times blocked for hitting limit */
69 	u_short	ks_mapblocks;	/* number of times blocked for kernel map */
70 	long	ks_maxused;	/* maximum number ever used */
71 	long	ks_limit;	/* most that are allowed to exist */
72 };
73 
74 /*
75  * Array of descriptors that describe the contents of each page
76  */
77 struct kmemusage {
78 	short ku_indx;		/* bucket index */
79 	union {
80 		u_short freecnt;/* for small allocations, free pieces in page */
81 		u_short pagecnt;/* for large allocations, pages alloced */
82 	} ku_un;
83 };
84 #define ku_freecnt ku_un.freecnt
85 #define ku_pagecnt ku_un.pagecnt
86 
87 /*
88  * Set of buckets for each size of memory block that is retained
89  */
90 struct kmembuckets {
91 	caddr_t kb_next;	/* list of free blocks */
92 	long	kb_calls;	/* total calls to allocate this size */
93 	long	kb_total;	/* total number of blocks allocated */
94 	long	kb_totalfree;	/* # of free elements in this bucket */
95 	long	kb_elmpercl;	/* # of elements in this sized allocation */
96 	long	kb_highwat;	/* high water mark */
97 	long	kb_couldfree;	/* over high water mark and could free */
98 };
99 
100 #ifdef KERNEL
101 #define MINALLOCSIZE	(1 << MINBUCKET)
102 #define BUCKETINDX(size) \
103 	(size) <= (MINALLOCSIZE * 128) \
104 		? (size) <= (MINALLOCSIZE * 8) \
105 			? (size) <= (MINALLOCSIZE * 2) \
106 				? (size) <= (MINALLOCSIZE * 1) \
107 					? (MINBUCKET + 0) \
108 					: (MINBUCKET + 1) \
109 				: (size) <= (MINALLOCSIZE * 4) \
110 					? (MINBUCKET + 2) \
111 					: (MINBUCKET + 3) \
112 			: (size) <= (MINALLOCSIZE* 32) \
113 				? (size) <= (MINALLOCSIZE * 16) \
114 					? (MINBUCKET + 4) \
115 					: (MINBUCKET + 5) \
116 				: (size) <= (MINALLOCSIZE * 64) \
117 					? (MINBUCKET + 6) \
118 					: (MINBUCKET + 7) \
119 		: (size) <= (MINALLOCSIZE * 2048) \
120 			? (size) <= (MINALLOCSIZE * 512) \
121 				? (size) <= (MINALLOCSIZE * 256) \
122 					? (MINBUCKET + 8) \
123 					: (MINBUCKET + 9) \
124 				: (size) <= (MINALLOCSIZE * 1024) \
125 					? (MINBUCKET + 10) \
126 					: (MINBUCKET + 11) \
127 			: (size) <= (MINALLOCSIZE * 8192) \
128 				? (size) <= (MINALLOCSIZE * 4096) \
129 					? (MINBUCKET + 12) \
130 					: (MINBUCKET + 13) \
131 				: (size) <= (MINALLOCSIZE * 16384) \
132 					? (MINBUCKET + 14) \
133 					: (MINBUCKET + 15)
134 
135 /*
136  * Turn virtual addresses into kmem map indicies
137  */
138 #define kmemxtob(alloc)	(kmembase + (alloc) * NBPG)
139 #define btokmemx(addr)	(((caddr_t)(addr) - kmembase) / NBPG)
140 #define btokup(addr)	(&kmemusage[((caddr_t)(addr) - kmembase) >> CLSHIFT])
141 
142 /*
143  * Macro versions for the usual cases of malloc/free
144  */
145 #ifdef KMEMSTATS
146 #define MALLOC(space, cast, size, type, flags) \
147 	(space) = (cast)malloc((u_long)(size), type, flags)
148 #define FREE(addr, type) free((caddr_t)(addr), type)
149 
150 #else /* do not collect statistics */
151 #define MALLOC(space, cast, size, type, flags) { \
152 	register struct kmembuckets *kbp = &bucket[BUCKETINDX(size)]; \
153 	long s = splimp(); \
154 	if (kbp->kb_next == NULL) { \
155 		(space) = (cast)malloc((u_long)(size), type, flags); \
156 	} else { \
157 		(space) = (cast)kbp->kb_next; \
158 		kbp->kb_next = *(caddr_t *)(space); \
159 	} \
160 	splx(s); \
161 }
162 
163 #define FREE(addr, type) { \
164 	register struct kmembuckets *kbp; \
165 	register struct kmemusage *kup = btokup(addr); \
166 	long s = splimp(); \
167 	if (1 << kup->ku_indx > MAXALLOCSAVE) { \
168 		free((caddr_t)(addr), type); \
169 	} else { \
170 		kbp = &bucket[kup->ku_indx]; \
171 		*(caddr_t *)(addr) = kbp->kb_next; \
172 		kbp->kb_next = (caddr_t)(addr); \
173 	} \
174 	splx(s); \
175 }
176 #endif /* do not collect statistics */
177 
178 extern struct kmemstats kmemstats[];
179 extern struct kmemusage *kmemusage;
180 extern char kmembase[];
181 extern struct kmembuckets bucket[];
182 extern qaddr_t malloc();
183 extern void free();
184 #endif KERNEL
185