|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.