| plan 9 kernel history: overview | file list | diff list |
1990/0312/port/stream.c (diff list | history)
| 1990/03013/sys/src/9/port/stream.c:7,18 – 1990/0312/sys/src/9/port/stream.c:7,30 (short | long | prev | next) | ||
| 1990/0227 | #include "errno.h" #include "devtab.h" | |
| 1990/0312 | /* * process end line discipline */ | |
| 1990/0227 | static void stputq(Queue*, Block*); | |
| 1990/0312 | Qinfo procinfo = { stputq, nullput, 0, 0, "process" }; | |
| 1990/0227 | ||
| 1990/0312 | /* * line disciplines that can be pushed * * WARNING: this table should be the result of configuration */ extern Qinfo noetherinfo; extern Qinfo dkmuxinfo; extern Qinfo urpinfo; | |
| 1990/0227 | static Qinfo *lds[] = { &noetherinfo, | |
| 1990/0312 | &dkmuxinfo, &urpinfo, | |
| 1990/0227 | 0 }; | |
| 1990/03013/sys/src/9/port/stream.c:34,40 – 1990/0312/sys/src/9/port/stream.c:46,54 | ||
| 1990/0227 | */ typedef struct { int size; | |
| 1990/0312 | Blist; QLock; /* qlock for sleepers on r */ Rendez r; /* sleep here waiting for blocks */ | |
| 1990/0227 | } Bclass; Bclass bclass[Nclass]={ { 0 }, | |
| 1990/03013/sys/src/9/port/stream.c:108,114 – 1990/0312/sys/src/9/port/stream.c:122,130 | ||
| 1990/0227 | while(bcp->first == 0){ unlock(bcp); print("waiting for blocks\n"); | |
| 1990/0312 | qlock(bcp); | |
| 1990/0227 | sleep(&bcp->r, isblock, (void *)bcp); | |
| 1990/0312 | qunlock(bcp); | |
| 1990/0227 | lock(bcp); } bp = bcp->first; | |
| 1990/03013/sys/src/9/port/stream.c:128,152 – 1990/0312/sys/src/9/port/stream.c:144,176 | ||
| 1990/0227 | } /* | |
| 1990/0312 | * Free a block (or list of blocks). Poison its pointers so that * someone trying to access it after freeing will cause a dump. | |
| 1990/0227 | */ void freeb(Block *bp) { Bclass *bcp; | |
| 1990/0312 | int tries; | |
| 1990/0227 | bcp = &bclass[bp->flags & S_CLASS]; | |
| 1990/0312 | bp->rptr = bp->wptr = 0; | |
| 1990/0227 | if(bcp->first) bcp->last->next = bp; else bcp->first = bp; | |
| 1990/0312 | tries = 0; while(bp->next){ if(++tries > 10){ dumpstack(); panic("freeb"); } bp = bp->next; } | |
| 1990/0227 | bcp->last = bp; | |
| 1990/0312 | wakeup(&bcp->r); | |
| 1990/0227 | } /* | |
| 1990/03013/sys/src/9/port/stream.c:269,279 – 1990/0312/sys/src/9/port/stream.c:293,303 | ||
| 1990/0227 | q->last->next = bp; else q->first = bp; | |
| 1990/0312 | q->len += BLEN(bp); | |
| 1990/0227 | delim = bp->flags & S_DELIM; while(bp->next) { bp = bp->next; | |
| 1990/0312 | q->len += BLEN(bp); | |
| 1990/0227 | delim |= bp->flags & S_DELIM; } q->last = bp; | |
| 1990/03013/sys/src/9/port/stream.c:292,306 – 1990/0312/sys/src/9/port/stream.c:316,329 | ||
| 1990/0227 | q->last->next = bp; else q->first = bp; | |
| 1990/0312 | q->len += BLEN(bp); | |
| 1990/0227 | delim = bp->flags & S_DELIM; while(bp->next) { bp = bp->next; | |
| 1990/0312 | q->len += BLEN(bp); | |
| 1990/0227 | delim |= bp->flags & S_DELIM; } q->last = bp; | |
| 1990/03013/sys/src/9/port/stream.c:307,313 – 1990/0312/sys/src/9/port/stream.c:330,336 | ||
| 1990/0227 | /* * add a block to the start of a queue */ | |
| 1990/0312 | void | |
| 1990/0227 | putbq(Blist *q, Block *bp) { lock(q); | |
| 1990/03013/sys/src/9/port/stream.c:316,327 – 1990/0312/sys/src/9/port/stream.c:339,350 | ||
| 1990/0227 | else q->last = bp; q->first = bp; | |
| 1990/0312 | q->len += BLEN(bp); | |
| 1990/0227 | unlock(q); } /* | |
| 1990/0312 | * remove the first block from a queue | |
| 1990/0227 | */ Block * getq(Queue *q) | |
| 1990/03013/sys/src/9/port/stream.c:334,340 – 1990/0312/sys/src/9/port/stream.c:357,363 | ||
| 1990/0227 | q->first = bp->next; if(q->first == 0) q->last = 0; | |
| 1990/0312 | q->len -= BLEN(bp); | |
| 1990/0227 | if((q->flag&QHIWAT) && q->len < Streamhi/2){ wakeup(&q->other->next->other->r); q->flag &= ~QHIWAT; | |
| 1990/03013/sys/src/9/port/stream.c:344,349 – 1990/0312/sys/src/9/port/stream.c:367,376 | ||
| 1990/0227 | unlock(q); return bp; } | |
| 1990/0312 | /* * remove the first block from a list of blocks */ | |
| 1990/0227 | Block * getb(Blist *q) { | |
| 1990/03013/sys/src/9/port/stream.c:354,360 – 1990/0312/sys/src/9/port/stream.c:381,387 | ||
| 1990/0227 | q->first = bp->next; if(q->first == 0) q->last = 0; | |
| 1990/0312 | q->len -= BLEN(bp); | |
| 1990/0227 | bp->next = 0; } return bp; | |
| 1990/03013/sys/src/9/port/stream.c:361,366 – 1990/0312/sys/src/9/port/stream.c:388,467 | ||
| 1990/0227 | } /* | |
| 1990/0312 | * make sure the first block has n bytes */ Block * pullup(Block *bp, int n) { Block *nbp; int i; /* * this should almost always be true, the rest it * just for to avoid every caller checking. */ if(BLEN(bp) >= n) return bp; /* * if not enough room in the first block, * add another to the front of the list. if(bp->lim - bp->rptr < n){ nbp = allocb(n); nbp->next = bp; bp = nbp; } /* * copy bytes from the trailing blocks into the first */ n -= BLEN(bp); while(nbp = bp->next){ i = BLEN(nbp); if(i > n) { memcpy(bp->wptr, nbp->rptr, n); bp->wptr += n; nbp->rptr += n; return bp; } else { memcpy(bp->wptr, nbp->rptr, i); bp->wptr += i; bp->next = nbp->next; nbp->next = 0; freeb(nbp); } } freeb(bp); return 0; } /* * grow the front of a list of blocks by n bytes */ Block * prepend(Block *bp, int n) { Block *nbp; if(bp->base && (bp->rptr - bp->base)>=n){ /* * room for channel number in first block of message */ bp->rptr -= n; return bp; } else { /* * make new block, put message number at end */ nbp = allocb(2); nbp->next = bp; nbp->wptr = nbp->lim; nbp->rptr = nbp->wptr - n; return nbp; } } /* | |
| 1990/0227 | * put a block into the bit bucket */ void | |
| 1990/03013/sys/src/9/port/stream.c:415,421 – 1990/0312/sys/src/9/port/stream.c:516,522 | ||
| 1990/0227 | int len; len = strlen(name); | |
| 1990/0312 | if(BLEN(bp) < len) | |
| 1990/0227 | return 0; if(strncmp(name, (char *)bp->rptr, len)==0){ if(bp->rptr[len] == ' ') | |
| 1990/03013/sys/src/9/port/stream.c:622,627 – 1990/0312/sys/src/9/port/stream.c:723,729 | ||
| 1990/0227 | freeb(bp); q->flag |= QHUNGUP; q->other->flag |= QHUNGUP; | |
| 1990/0312 | wakeup(&q->other->r); | |
| 1990/0227 | } else { lock(q); if(q->first) | |
| 1990/03013/sys/src/9/port/stream.c:628,635 – 1990/0312/sys/src/9/port/stream.c:730,741 | ||
| 1990/0227 | q->last->next = bp; else q->first = bp; | |
| 1990/0312 | q->len += BLEN(bp); while(bp->next) { bp = bp->next; q->len += BLEN(bp); } | |
| 1990/0227 | q->last = bp; | |
| 1990/03013/sys/src/9/port/stream.c:651,658 – 1990/0312/sys/src/9/port/stream.c:757,763 | ||
| 1990/0227 | n = i; if(n<0) return 0; | |
| 1990/0312 | memcpy(buf, str + c->offset, n); | |
| 1990/0227 | return n; } | |
| 1990/03013/sys/src/9/port/stream.c:716,722 – 1990/0312/sys/src/9/port/stream.c:821,827 | ||
| 1990/0227 | continue; } | |
| 1990/0312 | i = BLEN(bp); | |
| 1990/0227 | if(i <= left){ memcpy(buf, bp->rptr, i); left -= i; | |
| 1990/03013/sys/src/9/port/stream.c:806,812 – 1990/0312/sys/src/9/port/stream.c:911,917 | ||
| 1990/0227 | * send the request as a single delimited block */ long | |
| 1990/0312 | streamwrite(Chan *c, void *a, long n, int docopy) | |
| 1990/0227 | { Stream *s; Block *bp; | |
| 1990/03013/sys/src/9/port/stream.c:846,852 – 1990/0312/sys/src/9/port/stream.c:951,957 | ||
| 1990/0227 | if(q->other->flag & QHUNGUP) error(0, Ehungup); | |
| 1990/0312 | if((GLOBAL(a) && !docopy) || n==0){ | |
| 1990/0227 | /* * `a' is global to the whole system, just create a * pointer to it and pass it on. | |
| 1990/03013/sys/src/9/port/stream.c:886,889 – 1990/0312/sys/src/9/port/stream.c:991,1018 | ||
| 1990/0227 | qunlock(&s->wrlock); poperror(); return n; | |
| 1990/0312 | } /* * like andrew's getmfields but no hidden state */ int getfields(char *lp, /* to be parsed */ char **fields, /* where to put pointers */ int n, /* number of pointers */ char sep /* separator */ ) { int i; for(i=0; lp && *lp && i<n; i++){ while(*lp == sep) *lp++=0; if(*lp == 0) break; fields[i]=lp; while(*lp && *lp != sep) lp++; } return i; | |
| 1990/0227 | } | |