[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)