Annotation of researchv8dc/sys/chunix/challoc.c, revision 1.1.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.