[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Improved pipefs (update)
This is a update of the patches to improve the pipefs. I have
disabled Juergen's changes to pipe_write and pipe_read, since they
don't compile any more (sorry, Juergen), and i think it is wrong to
check for TS_HOLD there, it's an unclean mixing of different tty
layers. Use pagers!
IMHO this is much cleaner and simpler, but i may be biased :-).
--- pipefs.c~ Sat Jul 30 20:02:16 1994
+++ pipefs.c Sat Jul 30 20:17:42 1994
@@ -82,10 +82,10 @@
struct pipe {
int readers; /* number of readers of this pipe */
int writers; /* number of writers of this pipe */
- int head, tail; /* pipe head, tail (head == tail for empty) */
+ int start, len; /* pipe head index, size */
long rsel; /* process that did select() for reads */
long wsel; /* process that did select() for writes */
- char buf[PIPESIZ+4]; /* pipe data */
+ char buf[PIPESIZ]; /* pipe data */
};
struct fifo {
@@ -476,11 +476,11 @@
} else tty = 0;
/* set up the pipes appropriately */
- inp->head = inp->tail = 0;
+ inp->start = inp->len = 0;
inp->readers = selfread ? 1 : VIRGIN_PIPE; inp->writers = 1;
inp->rsel = inp->wsel = 0;
if (outp) {
- outp->head = outp->tail = 0;
+ outp->start = outp->len = 0;
outp->readers = 1; outp->writers = selfread ? 1 : VIRGIN_PIPE;
outp->wsel = outp->rsel = 0;
}
@@ -598,7 +598,7 @@
pipe_write(f, buf, nbytes)
FILEPTR *f; const char *buf; long nbytes;
{
- int ptail, phead, j;
+ int plen, j;
char *pbuf;
struct pipe *p;
struct fifo *this;
@@ -621,9 +621,7 @@
sleep (IO_Q, (long)&this->tty->state);
goto check_atomicity;
}
- r = p->tail - p->head;
- if (r < 0) r += PIPESIZ+4;
- r = PIPESIZ - r; /* r is the number of bytes we can write */
+ r = PIPESIZ - p->len; /* r is the number of bytes we can write */
if (r < nbytes) {
/* check for broken pipes */
if (p->readers == 0 || p->readers == VIRGIN_PIPE) {
@@ -643,11 +641,9 @@
}
while (nbytes > 0) {
- ptail = p->tail; phead = p->head;
- j = ptail+4;
- if (j >= PIPESIZ+4) j -= PIPESIZ+4;
- if (j != phead) {
-#if 1
+ plen = p->len;
+ if (plen < PIPESIZ) {
+#if 0 /* does not compile any more */
int free, wrap;
if (is_terminal(f) && !(f->flags & O_HEAD) &&
@@ -692,18 +688,26 @@
buf += free;
}
#else
- j -= 3;
- pbuf = &p->buf[ptail];
- do {
- *pbuf++ = *buf++;
- nbytes--; bytes_written++;
- if ( (ptail = j) == 0 )
- pbuf = &p->buf[0];
- j++;
- if (j >= PIPESIZ+4) j = 0;
- } while ( (nbytes > 0) && (j != phead) );
+ pbuf = &p->buf[(p->start + plen) & (PIPESIZ - 1)];
+ /* j is the amount that can be written continuously */
+ j = PIPESIZ - (pbuf - p->buf);
+ if (j > nbytes) j = nbytes;
+ if (j > PIPESIZ - plen) j = PIPESIZ - plen;
+ nbytes -= j; plen += j;
+ bytes_written += j;
+ memcpy (pbuf, buf, j);
+ buf += j;
+ if (nbytes > 0 && plen < PIPESIZ)
+ {
+ j = PIPESIZ - plen;
+ if (j > nbytes) j = nbytes;
+ nbytes -= j; plen += j;
+ bytes_written += j;
+ memcpy (p->buf, buf, j);
+ buf += j;
+ }
+ p->len = plen;
#endif
- p->tail = ptail;
} else { /* pipe full */
if (p->readers == 0 || p->readers == VIRGIN_PIPE) {
/* maybe some other signal is waiting for us? */
@@ -740,7 +744,7 @@
pipe_read(f, buf, nbytes)
FILEPTR *f; char *buf; long nbytes;
{
- int phead, ptail;
+ int plen, j;
struct fifo *this;
struct pipe *p;
long bytes_read = 0;
@@ -754,9 +758,9 @@
}
while (nbytes > 0) {
- phead = p->head; ptail = p->tail;
- if (ptail != phead) {
-#if 1
+ plen = p->len;
+ if (plen > 0) {
+#if 0 /* does not compile any more */
int left, wrap;
pbuf = p->buf + phead;
@@ -794,18 +798,30 @@
buf += left;
}
#else
- pbuf = &p->buf[phead];
- do {
- *buf++ = *pbuf++;
- nbytes--; bytes_read++;
- phead++;
- if (phead >= PIPESIZ+4) {
- phead = 0;
- pbuf = &p->buf[phead];
- }
- } while ( (nbytes > 0) && (phead != ptail) );
+ pbuf = &p->buf[p->start];
+ /* j is the amount that can be read continuously */
+ j = PIPESIZ - p->start;
+ if (j > nbytes) j = nbytes;
+ if (j > plen) j = plen;
+ nbytes -= j; plen -= j;
+ bytes_read += j;
+ p->start += j;
+ memcpy (buf, pbuf, j);
+ buf += j;
+ if (nbytes > 0 && plen > 0)
+ {
+ j = plen;
+ if (j > nbytes) j = nbytes;
+ nbytes -= j; plen -= j;
+ bytes_read += j;
+ p->start = j;
+ memcpy (buf, p->buf, j);
+ buf += j;
+ }
+ p->len = plen;
+ if (plen == 0 || p->start == PIPESIZ)
+ p->start = 0;
#endif
- p->head = phead;
}
else if (p->writers <= 0 || p->writers == VIRGIN_PIPE) {
TRACE(("pipe_read: no more writers"));
@@ -912,8 +928,7 @@
DEBUG(("pipe FIONREAD: no writers yet"));
r = -1;
} else {
- r = p->tail - p->head;
- if (r < 0) r += PIPESIZ+4;
+ r = p->len;
if (is_terminal(f)) {
if (!(f->flags & O_HEAD))
r = r >> 2; /* r /= 4 */
@@ -933,9 +948,7 @@
if (p->readers <= 0) {
r = -1;
} else {
- r = p->tail - p->head;
- if (r < 0) r += PIPESIZ+4;
- r = PIPESIZ - r;
+ r = PIPESIZ - p->len;
if (is_terminal(f)) {
if (f->flags & O_HEAD)
r = r >> 2; /* r /= 4 */
@@ -1002,11 +1015,11 @@
flushtype = *which;
if ((flushtype & 1) && this->inp) {
- this->inp->head = this->inp->tail;
+ this->inp->start = this->inp->len = 0;
wake(IO_Q, (long)this->inp);
}
if ((flushtype & 2) && this->outp) {
- this->outp->head = this->outp->tail;
+ this->outp->start = this->outp->len = 0;
wake(IO_Q, (long)this->outp);
}
break;
@@ -1017,8 +1030,7 @@
if (p->readers <= 0) {
r = -1;
} else {
- r = p->tail - p->head;
- if (r < 0) r += PIPESIZ+4;
+ r = p->len;
if (is_terminal(f) && (f->flags & O_HEAD))
r = r >> 2; /* r /= 4 */
}
@@ -1206,7 +1218,6 @@
{
struct fifo *this;
struct pipe *p;
- int j;
this = (struct fifo *)f->fc.index;
@@ -1218,7 +1229,7 @@
}
/* NOTE: if p->writers <= 0 then reads won't block (they'll fail) */
- if ((p->tail != p->head &&
+ if ((p->len > 0 &&
(!is_terminal(f) || !(f->flags & O_HEAD) ||
!(this->tty->state & TS_HOLD))) ||
p->writers <= 0) {
@@ -1237,9 +1248,7 @@
DEBUG(("write select on wrong end of pipe"));
return 0;
}
- j = p->tail+4;
- if (j >= PIPESIZ+4) j -= PIPESIZ+4;
- if ((j != p->head &&
+ if (p->len < PIPESIZ &&
(!is_terminal(f) || (f->flags & O_HEAD) ||
!(this->tty->state & TS_HOLD))) ||
p->readers <= 0)