Annotation of researchv8dc/sys/chunix/challoc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * challoc.c
        !             3:  * Storage allocation routines for the Chaos N.C.P. for allocating
        !             4:  * packets, connections, and (possibly) tty structures for connections treated
        !             5:  * as UNIX tty's
        !             6:  */
        !             7: #include "../chunix/chsys.h"
        !             8: #include "../chunix/chconf.h"
        !             9: #include "../chaos/chaos.h"
        !            10: #include "../h/buf.h"
        !            11: 
        !            12: #define BUFPRI PRIBIO          /* Sleep priority for buffers */
        !            13: #define        b_bits          b_blkno /* Bit map for chaos bufs in buffer (0=free) */
        !            14: #define b_list         b_resid /* Index in chsize that buffer belongs to */
        !            15: #define b_nfree        b_bcount        /* Number of free chaos buffers in buffer */
        !            16: #ifdef VMUNIX
        !            17: #define CHMAXBUF 25
        !            18: #define CHNMAXPKT 18
        !            19: #define CHBSIZE BUFSIZE
        !            20: #else
        !            21: #define CHMAXBUF 12
        !            22: #define CHNMAXPKT 9
        !            23: #ifdef UCB_BUFOUT
        !            24: #define CHBSIZE BUFSIZE
        !            25: extern char abuffers[NABUF][CHBSIZE];
        !            26: #else
        !            27: #define CHBSIZE (BSIZE(0)+BSLOP)
        !            28: extern char buffers[NBUF][CHBSIZE];
        !            29: #endif UCB_BUFOUT
        !            30: #endif VMUNIX
        !            31: 
        !            32: /*
        !            33:  * Structure for keeping track of various sizes of chaos buffers.
        !            34:  * Initialized values should be parameterized.
        !            35:  */
        !            36: struct chsize {
        !            37:        short ch_bufsize;       /* Size of packets to allocate from buffer */
        !            38:        short ch_mxbufs;        /* Maximum buffers to allocate to this size */
        !            39:        short ch_bufcount;      /* The count of buffers already allocated */
        !            40:        short ch_buffree;       /* Number of free buffers on this list now */
        !            41:        struct buf *ch_bufptr;  /* Pointer to buffers of this size */
        !            42: } Chsizes[] = {
        !            43: #define CHMINPKT 32
        !            44:        { CHMINPKT,     1, },
        !            45:        { 128,  2, },
        !            46:        { 512,  CHNMAXPKT, },
        !            47: #endif
        !            48: };
        !            49: 
        !            50: #define NSIZES (sizeof(Chsizes)/sizeof(Chsizes[0]))
        !            51: 
        !            52: int Chbufwait;         /* Someone's waiting for buffers */
        !            53: struct buf *Chbuflist; /* Unassigned buffers */
        !            54: int    Chnbufs;
        !            55: 
        !            56: /*
        !            57:  * Allocate a chunk at least "size" large,
        !            58:  * set flag means called from interrupt level - don't hang waiting for buffers
        !            59:  * just return NULL
        !            60:  */
        !            61: char *
        !            62: ch_alloc(size, flag)
        !            63: {
        !            64:        register struct chsize *sp;
        !            65:        register struct buf *bp;
        !            66:        register int j;
        !            67:        long bit;
        !            68:        int opl;
        !            69: 
        !            70:        opl = spl6();
        !            71: again:
        !            72:        for (sp = Chsizes; sp < &Chsizes[NSIZES]; sp++) {
        !            73:                if (sp->ch_bufsize < size)
        !            74:                        continue;
        !            75:                if (sp->ch_buffree == 0) {
        !            76:                        if (sp->ch_bufcount == sp->ch_mxbufs ||
        !            77:                            (bp = Chbuflist) == NULL)
        !            78:                                continue;
        !            79:                        Chbuflist = bp->av_forw;
        !            80:                        bp->av_forw = sp->ch_bufptr;
        !            81:                        sp->ch_bufptr = bp;
        !            82:                        bp->b_nfree = j = BSIZE(0) / sp->ch_bufsize;
        !            83:                        bp->b_bits = 0;
        !            84:                        bp->b_list = sp - Chsizes;
        !            85:                        sp->ch_buffree += j;
        !            86:                        sp->ch_bufcount++;
        !            87:                } else 
        !            88:                        for (bp = sp->ch_bufptr;; bp = bp->av_forw)
        !            89:                                if (bp == NULL)
        !            90:                                        panic("buffer lost somewhere");
        !            91:                                else if (bp->b_nfree != 0)
        !            92:                                        break;
        !            93:                /* Here bp points to a buffer to allocate */
        !            94:                for (bit = 1L, j = 0; ; bit <<= 1, j++)
        !            95:                        if (!(bit & bp->b_bits))
        !            96:                                break;
        !            97:                bp->b_bits |= bit;
        !            98:                bp->b_nfree--;
        !            99:                sp->ch_buffree--;
        !           100:                debug(DALLOC,printf("Alloc: size=%d,adr = %x\n", size, bp->b_un.b_addr+(j * sp->ch_bufsize)));
        !           101:                splx(opl);
        !           102:                return (bp->b_un.b_addr+(j * sp->ch_bufsize));
        !           103:        }
        !           104:        if (!flag) {
        !           105:                Chbufwait++;
        !           106:                sleep((caddr_t)&Chbufwait, BUFPRI);
        !           107:                goto again;
        !           108:        }
        !           109:        debug(DALLOC|DABNOR,printf("Alloc: size=%d, failed\n", size));
        !           110:        splx(opl);
        !           111:        return((caddr_t)0);
        !           112: }
        !           113: /*
        !           114:  * Free the previously allocated storage at "p"
        !           115:  */
        !           116: ch_free(p)
        !           117: char *p;
        !           118: {
        !           119:        register struct buf *bp;
        !           120:        register struct chsize *sp;
        !           121:        register int opl;
        !           122:        long bit;
        !           123: 
        !           124: #ifdef UCB_BUFOUT
        !           125:        bp = &abuf[(p - abuffers) / CHBSIZE];
        !           126: #else
        !           127:        bp = &buf[(p - buffers) / CHBSIZE];
        !           128: #endif
        !           129:        sp = &Chsizes[bp->b_list];
        !           130:        debug(DALLOC,printf("Free: addr=%x\n", p));
        !           131:        bit = 1L << ((p - bp->b_un.b_addr) / sp->ch_bufsize);
        !           132:        if (!(bp->b_bits & bit)) {
        !           133:                printf("Free: buffer %x already freed\n", p);
        !           134:                panic("Chaos buffer already freed");
        !           135:        }
        !           136:        bp->b_nfree++;
        !           137:        bp->b_bits &= ~bit;
        !           138:        sp->ch_buffree++;
        !           139:        opl = spl6();
        !           140:        if (Chbufwait) {
        !           141:                wakeup((caddr_t)&Chbufwait);
        !           142:                Chbufwait = 0;
        !           143:        }
        !           144:        splx(opl);
        !           145: }
        !           146: #ifdef DEBUG
        !           147: /*
        !           148:  * Check that address p is in the range of possible allocated packets
        !           149:  */
        !           150: ch_badaddr(p)
        !           151: char *p;
        !           152: {
        !           153:        register struct buf *bp;
        !           154:        register struct chsize *sp;
        !           155:        register int opl = spl6();
        !           156: 
        !           157:        for (sp = Chsizes; sp < &Chsizes[NSIZES]; sp++)
        !           158:                for (bp = sp->ch_bufptr; bp; bp = bp->av_forw)
        !           159:                        if (p >= bp->b_un.b_addr &&
        !           160:                            p < bp->b_un.b_addr + BSIZE(0)) {
        !           161:                                splx(opl);
        !           162:                                return(0);
        !           163:                        }
        !           164:        splx(opl);
        !           165:        return(1);
        !           166: }
        !           167: #endif
        !           168: /*
        !           169:  * Return the size of the place pointed at by "p"
        !           170:  */
        !           171: ch_size(p)
        !           172: char *p;
        !           173: {
        !           174:        register struct buf *bp;
        !           175: 
        !           176: #ifdef UCB_BUFOUT
        !           177:        bp = &abuf[(p - abuffers) / CHBSIZE];
        !           178: #else
        !           179:        bp = &buf[(p - buffers) / CHBSIZE];
        !           180: #endif
        !           181:        return (Chsizes[bp->b_list].ch_bufsize);
        !           182: }
        !           183: /*
        !           184:  * Allocate some space when a new connection is created
        !           185:  */
        !           186: ch_bufalloc()
        !           187: {
        !           188:        register int cnt;
        !           189:        register struct buf *bp;
        !           190:        struct buf *geteblk();
        !           191: 
        !           192:        if (sizeof(bp->b_bits) != 4)
        !           193:                panic("challoc bits");
        !           194:        if (Chnbufs < 8)
        !           195:                cnt = 4;
        !           196:        else
        !           197:                cnt = 1;
        !           198:        if ((Chnbufs + cnt) > CHMAXBUF)
        !           199:                return;
        !           200:        Chnbufs += cnt;
        !           201:        for (; cnt > 0; cnt--) {
        !           202: #ifndef VMUNIX
        !           203: #ifdef UCB_BUFOUT
        !           204:                if (abfreelist.av_forw == &abfreelist)
        !           205: #else
        !           206:                if (bfreelist.av_forw == &bfreelist)
        !           207: #endif
        !           208:                        break;
        !           209: #endif VMUNIX
        !           210:                bp = geteblk();
        !           211:                LOCK;
        !           212:                bp->av_forw = Chbuflist;
        !           213:                Chbuflist = bp;
        !           214:                UNLOCK;
        !           215:        }
        !           216:        Chnbufs -= cnt;
        !           217: }
        !           218: 
        !           219: ch_buffree()
        !           220: {
        !           221:        register int cnt;
        !           222:        register struct buf *bp;
        !           223: 
        !           224:        if (Chnbufs <= 8)
        !           225:                cnt = 4;
        !           226:        else
        !           227:                cnt = 1;
        !           228:        if (Chnbufs - cnt >= CHMAXBUF)
        !           229:                return;
        !           230:        LOCK;
        !           231:        for (; cnt > 0 && (bp = Chbuflist) != NULL; cnt--) {
        !           232:                Chbuflist = bp->av_forw;
        !           233: #ifdef UCB_BUFOUT
        !           234:                abrelse(bp);
        !           235: #else
        !           236:                brelse(bp);
        !           237: #endif
        !           238:                Chnbufs--;
        !           239:        }
        !           240:        UNLOCK;
        !           241: }

unix.superglobalmegacorp.com

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