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