Annotation of 43BSDReno/sys/kern/kern_malloc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1987 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution is only permitted until one year after the first shipment
                      6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                      7:  * binary forms are permitted provided that: (1) source distributions retain
                      8:  * this entire copyright notice and comment, and (2) distributions including
                      9:  * binaries display the following acknowledgement:  This product includes
                     10:  * software developed by the University of California, Berkeley and its
                     11:  * contributors'' in the documentation or other materials provided with the
                     12:  * distribution and in all advertising materials mentioning features or use
                     13:  * of this software.  Neither the name of the University nor the names of
                     14:  * its contributors may be used to endorse or promote products derived from
                     15:  * this software without specific prior written permission.
                     16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     19:  *
                     20:  *     @(#)kern_malloc.c       7.19 (Berkeley) 7/27/90
                     21:  */
                     22: 
                     23: #include "param.h"
                     24: #include "vm.h"
                     25: #include "cmap.h"
                     26: #include "time.h"
                     27: #include "proc.h"
                     28: #include "map.h"
                     29: #include "kernel.h"
                     30: #include "malloc.h"
                     31: 
                     32: #include "machine/pte.h"
                     33: 
                     34: struct kmembuckets bucket[MINBUCKET + 16];
                     35: struct kmemstats kmemstats[M_LAST];
                     36: struct kmemusage *kmemusage;
                     37: long wantkmemmap;
                     38: 
                     39: /*
                     40:  * Allocate a block of memory
                     41:  */
                     42: qaddr_t
                     43: malloc(size, type, flags)
                     44:        unsigned long size;
                     45:        int type, flags;
                     46: {
                     47:        register struct kmembuckets *kbp;
                     48:        register struct kmemusage *kup;
                     49:        long indx, npg, alloc, allocsize;
                     50:        int s;
                     51:        caddr_t va, cp;
                     52: #ifdef KMEMSTATS
                     53:        register struct kmemstats *ksp = &kmemstats[type];
                     54: 
                     55:        if (((unsigned long)type) > M_LAST)
                     56:                panic("malloc - bogus type");
                     57: #endif
                     58: 
                     59:        indx = BUCKETINDX(size);
                     60:        kbp = &bucket[indx];
                     61:        s = splimp();
                     62: again:
                     63: #ifdef KMEMSTATS
                     64:        while (ksp->ks_memuse >= ksp->ks_limit) {
                     65:                if (flags & M_NOWAIT) {
                     66:                        splx(s);
                     67:                        return (0);
                     68:                }
                     69:                if (ksp->ks_limblocks < 65535)
                     70:                        ksp->ks_limblocks++;
                     71:                sleep((caddr_t)ksp, PSWP+2);
                     72:        }
                     73: #endif
                     74:        if (kbp->kb_next == NULL) {
                     75:                if (size > MAXALLOCSAVE)
                     76:                        allocsize = roundup(size, CLBYTES);
                     77:                else
                     78:                        allocsize = 1 << indx;
                     79:                npg = clrnd(btoc(allocsize));
                     80:                if ((flags & M_NOWAIT) && freemem < npg) {
                     81:                        splx(s);
                     82:                        return (0);
                     83:                }
                     84:                alloc = rmalloc(kmemmap, npg);
                     85:                if (alloc == 0) {
                     86:                        if (flags & M_NOWAIT) {
                     87:                                splx(s);
                     88:                                return (0);
                     89:                        }
                     90: #ifdef KMEMSTATS
                     91:                        if (ksp->ks_mapblocks < 65535)
                     92:                                ksp->ks_mapblocks++;
                     93: #endif
                     94:                        wantkmemmap++;
                     95:                        sleep((caddr_t)&wantkmemmap, PSWP+2);
                     96:                        goto again;
                     97:                }
                     98:                alloc -= CLSIZE;                /* convert to base 0 */
                     99:                (void) vmemall(&kmempt[alloc], (int)npg, &proc[0], CSYS);
                    100:                va = (caddr_t) kmemxtob(alloc);
                    101:                vmaccess(&kmempt[alloc], va, (int)npg);
                    102: #ifdef KMEMSTATS
                    103:                kbp->kb_total += kbp->kb_elmpercl;
                    104: #endif
                    105:                kup = btokup(va);
                    106:                kup->ku_indx = indx;
                    107:                if (allocsize > MAXALLOCSAVE) {
                    108:                        if (npg > 65535)
                    109:                                panic("malloc: allocation too large");
                    110:                        kup->ku_pagecnt = npg;
                    111: #ifdef KMEMSTATS
                    112:                        ksp->ks_memuse += allocsize;
                    113: #endif
                    114:                        goto out;
                    115:                }
                    116: #ifdef KMEMSTATS
                    117:                kup->ku_freecnt = kbp->kb_elmpercl;
                    118:                kbp->kb_totalfree += kbp->kb_elmpercl;
                    119: #endif
                    120:                kbp->kb_next = va + (npg * NBPG) - allocsize;
                    121:                for (cp = kbp->kb_next; cp > va; cp -= allocsize)
                    122:                        *(caddr_t *)cp = cp - allocsize;
                    123:                *(caddr_t *)cp = NULL;
                    124:        }
                    125:        va = kbp->kb_next;
                    126:        kbp->kb_next = *(caddr_t *)va;
                    127: #ifdef KMEMSTATS
                    128:        kup = btokup(va);
                    129:        if (kup->ku_indx != indx)
                    130:                panic("malloc: wrong bucket");
                    131:        if (kup->ku_freecnt == 0)
                    132:                panic("malloc: lost data");
                    133:        kup->ku_freecnt--;
                    134:        kbp->kb_totalfree--;
                    135:        ksp->ks_memuse += 1 << indx;
                    136: out:
                    137:        kbp->kb_calls++;
                    138:        ksp->ks_inuse++;
                    139:        ksp->ks_calls++;
                    140:        if (ksp->ks_memuse > ksp->ks_maxused)
                    141:                ksp->ks_maxused = ksp->ks_memuse;
                    142: #else
                    143: out:
                    144: #endif
                    145:        splx(s);
                    146:        return ((qaddr_t)va);
                    147: }
                    148: 
                    149: #ifdef DIAGNOSTIC
                    150: long addrmask[] = { 0x00000000,
                    151:        0x00000001, 0x00000003, 0x00000007, 0x0000000f,
                    152:        0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
                    153:        0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
                    154:        0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
                    155: };
                    156: #endif /* DIAGNOSTIC */
                    157: 
                    158: /*
                    159:  * Free a block of memory allocated by malloc.
                    160:  */
                    161: void
                    162: free(addr, type)
                    163:        caddr_t addr;
                    164:        int type;
                    165: {
                    166:        register struct kmembuckets *kbp;
                    167:        register struct kmemusage *kup;
                    168:        long alloc, size;
                    169:        int s;
                    170: #ifdef KMEMSTATS
                    171:        register struct kmemstats *ksp = &kmemstats[type];
                    172: #endif
                    173: 
                    174:        kup = btokup(addr);
                    175:        size = 1 << kup->ku_indx;
                    176: #ifdef DIAGNOSTIC
                    177:        if (size > NBPG * CLSIZE)
                    178:                alloc = addrmask[BUCKETINDX(NBPG * CLSIZE)];
                    179:        else
                    180:                alloc = addrmask[kup->ku_indx];
                    181:        if (((u_long)addr & alloc) != 0) {
                    182:                printf("free: unaligned addr 0x%x, size %d, type %d, mask %d\n",
                    183:                        addr, size, type, alloc);
                    184:                panic("free: unaligned addr");
                    185:        }
                    186: #endif /* DIAGNOSTIC */
                    187:        kbp = &bucket[kup->ku_indx];
                    188:        s = splimp();
                    189:        if (size > MAXALLOCSAVE) {
                    190:                alloc = btokmemx(addr);
                    191:                (void) memfree(&kmempt[alloc], (int)kup->ku_pagecnt, 1);
                    192:                rmfree(kmemmap, (long)kup->ku_pagecnt, alloc + CLSIZE);
                    193:                if (wantkmemmap) {
                    194:                        wakeup((caddr_t)&wantkmemmap);
                    195:                        wantkmemmap = 0;
                    196:                }
                    197: #ifdef KMEMSTATS
                    198:                size = kup->ku_pagecnt << PGSHIFT;
                    199:                ksp->ks_memuse -= size;
                    200:                kup->ku_indx = 0;
                    201:                kup->ku_pagecnt = 0;
                    202:                if (ksp->ks_memuse + size >= ksp->ks_limit &&
                    203:                    ksp->ks_memuse < ksp->ks_limit)
                    204:                        wakeup((caddr_t)ksp);
                    205:                ksp->ks_inuse--;
                    206:                kbp->kb_total -= 1;
                    207: #endif
                    208:                splx(s);
                    209:                return;
                    210:        }
                    211: #ifdef KMEMSTATS
                    212:        kup->ku_freecnt++;
                    213:        if (kup->ku_freecnt >= kbp->kb_elmpercl)
                    214:                if (kup->ku_freecnt > kbp->kb_elmpercl)
                    215:                        panic("free: multiple frees");
                    216:                else if (kbp->kb_totalfree > kbp->kb_highwat)
                    217:                        kbp->kb_couldfree++;
                    218:        kbp->kb_totalfree++;
                    219:        ksp->ks_memuse -= size;
                    220:        if (ksp->ks_memuse + size >= ksp->ks_limit &&
                    221:            ksp->ks_memuse < ksp->ks_limit)
                    222:                wakeup((caddr_t)ksp);
                    223:        ksp->ks_inuse--;
                    224: #endif
                    225:        *(caddr_t *)addr = kbp->kb_next;
                    226:        kbp->kb_next = addr;
                    227:        splx(s);
                    228: }
                    229: 
                    230: /*
                    231:  * Initialize the kernel memory allocator
                    232:  */
                    233: kmeminit()
                    234: {
                    235:        register long indx;
                    236:        int npg;
                    237: 
                    238: #if    ((MAXALLOCSAVE & (MAXALLOCSAVE - 1)) != 0)
                    239:                ERROR!_kmeminit:_MAXALLOCSAVE_not_power_of_2
                    240: #endif
                    241: #if    (MAXALLOCSAVE > MINALLOCSIZE * 32768)
                    242:                ERROR!_kmeminit:_MAXALLOCSAVE_too_big
                    243: #endif
                    244: #if    (MAXALLOCSAVE < CLBYTES)
                    245:                ERROR!_kmeminit:_MAXALLOCSAVE_too_small
                    246: #endif
                    247:        npg = ekmempt - kmempt;
                    248:        rminit(kmemmap, (long)npg, (long)CLSIZE, "malloc map", npg);
                    249: #ifdef KMEMSTATS
                    250:        for (indx = 0; indx < MINBUCKET + 16; indx++) {
                    251:                if (1 << indx >= CLBYTES)
                    252:                        bucket[indx].kb_elmpercl = 1;
                    253:                else
                    254:                        bucket[indx].kb_elmpercl = CLBYTES / (1 << indx);
                    255:                bucket[indx].kb_highwat = 5 * bucket[indx].kb_elmpercl;
                    256:        }
                    257:        for (indx = 0; indx < M_LAST; indx++)
                    258:                kmemstats[indx].ks_limit = npg * NBPG * 6 / 10;
                    259: #endif
                    260: }

unix.superglobalmegacorp.com

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