140 lines
4.8 KiB
Perl
140 lines
4.8 KiB
Perl
.\" $NetBSD: appendix.t,v 1.2 1998/01/09 06:41:11 perry Exp $
|
|
.\"
|
|
.\" Copyright (c) 1988 The Regents of the University of California.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\" 3. All advertising materials mentioning features or use of this software
|
|
.\" must display the following acknowledgement:
|
|
.\" This product includes software developed by the University of
|
|
.\" California, Berkeley and its contributors.
|
|
.\" 4. Neither the name of the University nor the names of its contributors
|
|
.\" may be used to endorse or promote products derived from this software
|
|
.\" without specific prior written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
.\" SUCH DAMAGE.
|
|
.\"
|
|
.\" @(#)appendix.t 5.1 (Berkeley) 4/16/91
|
|
.\"
|
|
.bp
|
|
.H 1 "Appendix A - Implementation Details"
|
|
.LP
|
|
.nf
|
|
.vS
|
|
/*
|
|
* Constants for setting the parameters of the kernel memory allocator.
|
|
*
|
|
* 2 ** MINBUCKET is the smallest unit of memory that will be
|
|
* allocated. It must be at least large enough to hold a pointer.
|
|
*
|
|
* Units of memory less or equal to MAXALLOCSAVE will permanently
|
|
* allocate physical memory; requests for these size pieces of memory
|
|
* are quite fast. Allocations greater than MAXALLOCSAVE must
|
|
* always allocate and free physical memory; requests for these size
|
|
* allocations should be done infrequently as they will be slow.
|
|
* Constraints: CLBYTES <= MAXALLOCSAVE <= 2 ** (MINBUCKET + 14)
|
|
* and MAXALLOCSIZE must be a power of two.
|
|
*/
|
|
#define MINBUCKET 4 /* 4 => min allocation of 16 bytes */
|
|
#define MAXALLOCSAVE (2 * CLBYTES)
|
|
|
|
/*
|
|
* Maximum amount of kernel dynamic memory.
|
|
* Constraints: must be a multiple of the pagesize.
|
|
*/
|
|
#define MAXKMEM (1024 * PAGESIZE)
|
|
|
|
/*
|
|
* Arena for all kernel dynamic memory allocation.
|
|
* This arena is known to start on a page boundary.
|
|
*/
|
|
extern char kmembase[MAXKMEM];
|
|
|
|
/*
|
|
* Array of descriptors that describe the contents of each page
|
|
*/
|
|
struct kmemsizes {
|
|
short ks_indx; /* bucket index, size of small allocations */
|
|
u_short ks_pagecnt; /* for large allocations, pages allocated */
|
|
} kmemsizes[MAXKMEM / PAGESIZE];
|
|
|
|
/*
|
|
* Set of buckets for each size of memory block that is retained
|
|
*/
|
|
struct kmembuckets {
|
|
caddr_t kb_next; /* list of free blocks */
|
|
} bucket[MINBUCKET + 16];
|
|
.bp
|
|
/*
|
|
* Macro to convert a size to a bucket index. If the size is constant,
|
|
* this macro reduces to a compile time constant.
|
|
*/
|
|
#define MINALLOCSIZE (1 << MINBUCKET)
|
|
#define BUCKETINDX(size) \
|
|
(size) <= (MINALLOCSIZE * 128) \
|
|
? (size) <= (MINALLOCSIZE * 8) \
|
|
? (size) <= (MINALLOCSIZE * 2) \
|
|
? (size) <= (MINALLOCSIZE * 1) \
|
|
? (MINBUCKET + 0) \
|
|
: (MINBUCKET + 1) \
|
|
: (size) <= (MINALLOCSIZE * 4) \
|
|
? (MINBUCKET + 2) \
|
|
: (MINBUCKET + 3) \
|
|
: (size) <= (MINALLOCSIZE* 32) \
|
|
? (size) <= (MINALLOCSIZE * 16) \
|
|
? (MINBUCKET + 4) \
|
|
: (MINBUCKET + 5) \
|
|
: (size) <= (MINALLOCSIZE * 64) \
|
|
? (MINBUCKET + 6) \
|
|
: (MINBUCKET + 7) \
|
|
: (size) <= (MINALLOCSIZE * 2048) \
|
|
/* etc ... */
|
|
|
|
/*
|
|
* Macro versions for the usual cases of malloc/free
|
|
*/
|
|
#define MALLOC(space, cast, size, flags) { \
|
|
register struct kmembuckets *kbp = &bucket[BUCKETINDX(size)]; \
|
|
long s = splimp(); \
|
|
if (kbp->kb_next == NULL) { \
|
|
(space) = (cast)malloc(size, flags); \
|
|
} else { \
|
|
(space) = (cast)kbp->kb_next; \
|
|
kbp->kb_next = *(caddr_t *)(space); \
|
|
} \
|
|
splx(s); \
|
|
}
|
|
|
|
#define FREE(addr) { \
|
|
register struct kmembuckets *kbp; \
|
|
register struct kmemsizes *ksp = \
|
|
&kmemsizes[((addr) - kmembase) / PAGESIZE]; \
|
|
long s = splimp(); \
|
|
if (1 << ksp->ks_indx > MAXALLOCSAVE) { \
|
|
free(addr); \
|
|
} else { \
|
|
kbp = &bucket[ksp->ks_indx]; \
|
|
*(caddr_t *)(addr) = kbp->kb_next; \
|
|
kbp->kb_next = (caddr_t)(addr); \
|
|
} \
|
|
splx(s); \
|
|
}
|
|
.vE
|