Annotation of kernel/kern/kalloc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /* 
        !            26:  * Mach Operating System
        !            27:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
        !            28:  * All Rights Reserved.
        !            29:  * 
        !            30:  * Permission to use, copy, modify and distribute this software and its
        !            31:  * documentation is hereby granted, provided that both the copyright
        !            32:  * notice and this permission notice appear in all copies of the
        !            33:  * software, derivative works or modified versions, and any portions
        !            34:  * thereof, and that both notices appear in supporting documentation.
        !            35:  * 
        !            36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            39:  * 
        !            40:  * Carnegie Mellon requests users of this software to return to
        !            41:  * 
        !            42:  *  Software Distribution Coordinator  or  [email protected]
        !            43:  *  School of Computer Science
        !            44:  *  Carnegie Mellon University
        !            45:  *  Pittsburgh PA 15213-3890
        !            46:  * 
        !            47:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            48:  * the rights to redistribute these changes.
        !            49:  */
        !            50: /*
        !            51:  *     File:   kern/kalloc.c
        !            52:  *     Author: Avadis Tevanian, Jr.
        !            53:  *     Date:   1985
        !            54:  *
        !            55:  *     General kernel memory allocator.  This allocator is designed
        !            56:  *     to be used by the kernel to manage dynamic memory fast.
        !            57:  */
        !            58: 
        !            59: #include <mach/machine/vm_types.h>
        !            60: #include <mach/vm_param.h>
        !            61: 
        !            62: #include <kern/zalloc.h>
        !            63: #include <kern/kalloc.h>
        !            64: #include <vm/vm_kern.h>
        !            65: #include <vm/vm_object.h>
        !            66: #include <vm/vm_map.h>
        !            67: 
        !            68: vm_map_t kalloc_map;
        !            69: 
        !            70: /*
        !            71:  *     All allocations of size less than kalloc_max are rounded to the
        !            72:  *     next highest power of 2.  This allocator is built on top of
        !            73:  *     the zone allocator.  A zone is created for each potential size
        !            74:  *     that we are willing to get in small blocks.
        !            75:  *
        !            76:  *     We assume that kalloc_max is not greater than 64K;
        !            77:  *     thus 16 is a safe array size for k_zone and k_zone_name.
        !            78:  */
        !            79: 
        !            80: #define        NKSIZE  16
        !            81: vm_size_t k_zone_maxsize;
        !            82: struct zone *k_zone[NKSIZE];
        !            83: static char k_zone_name[NKSIZE][16];
        !            84: vm_size_t k_zone_elemsize[NKSIZE] = {
        !            85:        16, 32, 48, 64, 80, 128, 256, 384, 512,
        !            86:        1024, 2048, 3072, 4096, 8192, 12288, 16384
        !            87: };
        !            88: 
        !            89: #if DIAGNOSTIC
        !            90: /*
        !            91:  * Be careful with ZALLOC0!  It seems that kdp now has a subtle dependency
        !            92:  * on allocated memory not being initialized.  If you do use it you'll need
        !            93:  * to enter gdb with cmd-Power and even then you may see a "SIGTRAP".
        !            94:  */
        !            95: #if ZALLOC0
        !            96: void    *memset __P((void *, int, size_t));
        !            97: #endif
        !            98: #endif
        !            99: 
        !           100: 
        !           101: /*
        !           102:  *     Initialize the memory allocator.  This should be called only
        !           103:  *     once on a system wide basis (i.e. first processor to get here
        !           104:  *     does the initialization).
        !           105:  *
        !           106:  *     This initializes all of the zones.
        !           107:  */
        !           108: 
        !           109: void kalloc_init(void)
        !           110: {
        !           111:        vm_size_t size;
        !           112:        register int i;
        !           113:        
        !           114:        kalloc_map = kernel_map;
        !           115: 
        !           116:        /*
        !           117:         *      Allocate a zone for each size we are going to handle.
        !           118:         *      We specify non-paged memory.
        !           119:         */
        !           120:        for (i = 0; i < NKSIZE; i++) {
        !           121:                if ((size = k_zone_elemsize[i]) >= PAGE_SIZE)
        !           122:                        break;
        !           123:                sprintf (k_zone_name[i], "kalloc.%d", size);
        !           124:                k_zone[i] = zinit(size, 1024*1024, PAGE_SIZE,
        !           125:                        FALSE, k_zone_name[i]);
        !           126:                k_zone_maxsize = size;
        !           127:        }
        !           128: }
        !           129: 
        !           130: vm_offset_t kalloc_noblock(size)
        !           131:        vm_size_t size;
        !           132: {
        !           133:        register int zindex = 0;
        !           134:        register vm_size_t allocsize;
        !           135:        vm_offset_t addr;
        !           136: 
        !           137:        /* compute the size of the block that we will actually allocate */
        !           138: 
        !           139:        allocsize = size;
        !           140:        if (size <= k_zone_maxsize) {
        !           141:                allocsize = k_zone_elemsize[0];
        !           142:                zindex = 0;
        !           143:                while (allocsize < size) {
        !           144:                        allocsize = k_zone_elemsize[++zindex];
        !           145:                }
        !           146:        }
        !           147: 
        !           148:        /*
        !           149:         * If our size is still small enough, check the queue for that size
        !           150:         * and allocate.
        !           151:         */
        !           152: 
        !           153:        if (allocsize <= k_zone_maxsize) {
        !           154:                addr = zalloc_noblock(k_zone[zindex]);
        !           155: #if DIAGNOSTIC
        !           156: #if ZALLOC0
        !           157:                (void) memset((void *)addr, 0, (size_t) size);
        !           158: #endif
        !           159: #endif
        !           160:        } else {
        !           161:                if (kmem_alloc_zone(kalloc_map, &addr, allocsize, FALSE)
        !           162:                                                            != KERN_SUCCESS)
        !           163:                        addr = 0;
        !           164:        }
        !           165: 
        !           166:        return(addr);
        !           167: }
        !           168: 
        !           169: vm_offset_t kalloc(size)
        !           170:        vm_size_t size;
        !           171: {
        !           172:        register int zindex = 0;
        !           173:        register vm_size_t allocsize;
        !           174:        vm_offset_t addr;
        !           175: 
        !           176:        /* compute the size of the block that we will actually allocate */
        !           177:        allocsize = size;
        !           178:        if (size <= k_zone_maxsize) {
        !           179:                allocsize = k_zone_elemsize[0];
        !           180:                zindex = 0;
        !           181:                while (allocsize < size) {
        !           182:                        allocsize = k_zone_elemsize[++zindex];
        !           183:                }
        !           184:        }
        !           185: 
        !           186:        /*
        !           187:         * If our size is still small enough, check the queue for that size
        !           188:         * and allocate.
        !           189:         */
        !           190: 
        !           191:        if (allocsize <= k_zone_maxsize) {
        !           192:                addr = zalloc(k_zone[zindex]);
        !           193: #if DIAGNOSTIC
        !           194: #if ZALLOC0
        !           195:                (void) memset((void *)addr, 0, (size_t) size);
        !           196: #endif
        !           197: #endif
        !           198:        } else {
        !           199:                if (kmem_alloc_wired(kalloc_map, &addr, allocsize)
        !           200:                                                        != KERN_SUCCESS)
        !           201:                        addr = 0;
        !           202:        }
        !           203:        return(addr);
        !           204: }
        !           205: 
        !           206: vm_offset_t kget(size)
        !           207:        vm_size_t size;
        !           208: {
        !           209:        register int zindex = 0;
        !           210:        register vm_size_t allocsize;
        !           211:        vm_offset_t addr = 0;
        !           212: 
        !           213:        /* compute the size of the block that we will actually allocate */
        !           214:        allocsize = size;
        !           215:        if (size <= k_zone_maxsize) {
        !           216:                allocsize = k_zone_elemsize[0];
        !           217:                zindex = 0;
        !           218:                while (allocsize < size) {
        !           219:                        allocsize = k_zone_elemsize[++zindex];
        !           220:                }
        !           221:        }
        !           222: 
        !           223:        /*
        !           224:         * If our size is still small enough, check the queue for that size
        !           225:         * and allocate.
        !           226:         */
        !           227: 
        !           228:        if (allocsize <= k_zone_maxsize) {
        !           229:                addr = zget(k_zone[zindex]);
        !           230:        } else {
        !           231:                /* This will never work, so we might as well panic */
        !           232:                panic("kget");
        !           233:        }
        !           234:        return(addr);
        !           235: }
        !           236: 
        !           237: void 
        !           238: kfree(data, size)
        !           239:        vm_offset_t data;
        !           240:        vm_size_t size;
        !           241: {
        !           242:        register int zindex = 0;
        !           243:        register vm_size_t freesize;
        !           244: 
        !           245:        freesize = size;
        !           246:        if (size <= k_zone_maxsize) {
        !           247:                freesize = k_zone_elemsize[0];
        !           248:                zindex = 0;
        !           249:                while (freesize < size) {
        !           250:                        freesize = k_zone_elemsize[++zindex];
        !           251:                }
        !           252:        }
        !           253: 
        !           254:        if (freesize <= k_zone_maxsize) {
        !           255:                zfree(k_zone[zindex], data);
        !           256:        } else {
        !           257:                kmem_free(kalloc_map, data, freesize);
        !           258:        }
        !           259: }
        !           260: 
        !           261: struct zone *kalloc_zone(
        !           262:        vm_size_t       size)
        !           263: {
        !           264:        register int zindex = 0;
        !           265:        register vm_size_t allocsize;
        !           266: 
        !           267:        /* compute the size of the block that we will actually allocate */
        !           268: 
        !           269:        allocsize = size;
        !           270:        if (size <= k_zone_maxsize) {
        !           271:                allocsize = k_zone_elemsize[0];
        !           272:                zindex = 0;
        !           273:                while (allocsize < size) {
        !           274:                        allocsize = k_zone_elemsize[++zindex];
        !           275:                }
        !           276: 
        !           277:                return (k_zone[zindex]);
        !           278:        }
        !           279: 
        !           280:        return (0);
        !           281: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.