[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Improved pipefs



This patch changes the pipe fs to use the full size of the pipe buffer
instead of one less.  This may not look very much, but why shouldn't
MiNT be as good as Linux? :-)  Anyway, the data copying should be a
bit more efficient now.

--- pipefs.c~	Mon Jul 25 21:14:56 1994
+++ pipefs.c	Mon Jul 25 22:00:44 1994
@@ -76,7 +76,7 @@
 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];	/* pipe data */
@@ -469,11 +469,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;
 	}
@@ -591,7 +591,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;
@@ -607,9 +607,7 @@
 
 	if (nbytes > 0 && nbytes <= PIPE_BUF) {
 check_atomicity:
-		r = p->tail - p->head;
-		if (r < 0) r += PIPESIZ;
-		r = (PIPESIZ-1) - 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) {
@@ -629,20 +627,27 @@
 	}
 
 	while (nbytes > 0) {
-		ptail = p->tail; phead = p->head;
-		j = ptail+1;
-		if (j >= PIPESIZ) j = 0;
-		if (j != phead) {
-			pbuf = &p->buf[ptail];
-			do {
-				*pbuf++ = *buf++;
-				nbytes--; bytes_written++;
-				if ( (ptail = j) == 0 )
-					pbuf = &p->buf[0];
-				j++;
-				if (j >= PIPESIZ) j = 0;
-			} while ( (nbytes > 0) && (j != phead) );
-			p->tail = ptail;
+		plen = p->len;
+		if (plen < PIPESIZ) {
+			pbuf = &p->buf[(p->start + plen) & (PIPESIZ - 1)];
+			/* j is the amount that can be written continuously */
+			j = PIPESIZ - plen;
+			if (j > nbytes) j = nbytes;
+			nbytes -= j; plen += j;
+			bytes_written += j;
+			while (j--)
+			  *pbuf++ = *buf++;
+			if (nbytes > 0 && plen < PIPESIZ)
+			  {
+			    pbuf = p->buf;
+			    j = PIPESIZ - plen;
+			    if (j > nbytes) j = nbytes;
+			    nbytes -= j; plen += j;
+			    bytes_written += j;
+			    while (j--)
+			      *pbuf++ = *buf++;
+			  }
+			p->len = plen;
 		} else {		/* pipe full */
 			if (p->readers == 0 || p->readers == VIRGIN_PIPE) {
 			/* maybe some other signal is waiting for us? */
@@ -679,7 +684,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;
@@ -693,19 +698,26 @@
 	}
 
 	while (nbytes > 0) {
-		phead = p->head; ptail = p->tail;
-		if (ptail != phead) {
-			pbuf = &p->buf[phead];
-			do {
-				*buf++ = *pbuf++;
-				nbytes--; bytes_read++;
-				phead++;
-				if (phead >= PIPESIZ) {
-					phead = 0;
-					pbuf = &p->buf[phead];
-				}
-			} while ( (nbytes > 0) && (phead != ptail) );
-			p->head = phead;
+		plen = p->len;
+		if (plen > 0) {
+			pbuf = &p->buf[p->start];
+			/* j is the amount that can be read continuously */
+			j = plen < nbytes ? plen : nbytes;
+			nbytes -= j; plen -= j;
+			bytes_read += j;
+			while (j--)
+			  *buf++ = *pbuf++;
+			if (nbytes > 0 && plen > 0)
+			  {
+			    pbuf = p->buf;
+			    j = plen < nbytes ? plen : nbytes;
+			    nbytes -= j; plen -= j;
+			    bytes_read += j;
+			    while (j--)
+			      *buf++ = *pbuf++;
+			  }
+			p->len = plen;
+			p->start = pbuf - p->buf;
 		}
 		else if (p->writers <= 0 || p->writers == VIRGIN_PIPE) {
 			TRACE(("pipe_read: no more writers"));
@@ -754,8 +766,7 @@
 				DEBUG(("pipe FIONREAD: no writers"));
 				r = -1;
 			} else {
-				r = p->tail - p->head;
-				if (r < 0) r += PIPESIZ;
+				r = p->len;
 				if (is_terminal(f))
 					r = r >> 2;	/* r /= 4 */
 			}
@@ -767,9 +778,7 @@
 			if (p->readers <= 0) {
 				r = -1;
 			} else {
-				r = p->tail - p->head;
-				if (r < 0) r += PIPESIZ;
-				r = (PIPESIZ-1) - r;
+				r = PIPESIZ - p->len;
 				if (is_terminal(f))
 					r = r >> 2;	/* r /= 4 */
 			}
@@ -827,11 +836,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;
@@ -842,8 +851,7 @@
 			if (p->readers <= 0) {
 				r = -1;
 			} else {
-				r = p->tail - p->head;
-				if (r < 0) r += PIPESIZ;
+				r = p->len;
 				if (is_terminal(f))
 					r = r >> 2;	/* r /= 4 */
 			}
@@ -1031,7 +1039,6 @@
 {
 	struct fifo *this;
 	struct pipe *p;
-	int j;
 
 	this = (struct fifo *)f->fc.index;
 
@@ -1043,7 +1050,7 @@
 		}
 
 /* NOTE: if p->writers <= 0 then reads won't block (they'll fail) */
-		if (p->tail != p->head || p->writers <= 0) {
+		if (p->len > 0 || p->writers <= 0) {
 			return 1;
 		}
 
@@ -1057,9 +1064,7 @@
 			DEBUG(("write select on wrong end of pipe"));
 			return 0;
 		}
-		j = p->tail+1;
-		if (j >= PIPESIZ) j = 0;
-		if (j != p->head || p->readers <= 0)
+		if (p->len < PIPESIZ || p->readers <= 0)
 			return 1;	/* data may be written */
 		if (p->wsel)
 			return 2;	/* collision */

Diff exited abnormally with code 1 at Mon Jul 25 22:04:20

-- 
+------------------------------------------------------------------------+
Andreas Schwab                                      "And now for something
schwab@ls5.informatik.uni-dortmund.de                completely different"