summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_pipe.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1996-02-11 22:09:50 +0000
committerdyson <dyson@FreeBSD.org>1996-02-11 22:09:50 +0000
commita3a752bd16c86a841f9dbe7ed1efdfbbae49f627 (patch)
treefd58f049ea877055f1683bb0797e2f7a3161fcad /sys/kern/sys_pipe.c
parente46dad739e813e40c45db29ec1899a1cacd02a6c (diff)
downloadFreeBSD-src-a3a752bd16c86a841f9dbe7ed1efdfbbae49f627.zip
FreeBSD-src-a3a752bd16c86a841f9dbe7ed1efdfbbae49f627.tar.gz
Add ifdefs for non-freebsd system usage. Add missing select wakeups,
and make the select wakup code a little neater.
Diffstat (limited to 'sys/kern/sys_pipe.c')
-rw-r--r--sys/kern/sys_pipe.c90
1 files changed, 63 insertions, 27 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index fbce3db..91dc458 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -13,12 +13,10 @@
* documentation and/or other materials provided with the distribution.
* 3. Absolutely no warranty of function or purpose is made by the author
* John S. Dyson.
- * 4. This work was done expressly for inclusion into FreeBSD. Other use
- * is allowed if this notation is included.
- * 5. Modifications may be freely made to this file if the above conditions
+ * 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: sys_pipe.c,v 1.9 1996/02/07 06:41:56 dyson Exp $
+ * $Id: sys_pipe.c,v 1.10 1996/02/09 04:36:36 dyson Exp $
*/
#ifndef OLD_PIPE
@@ -83,6 +81,16 @@
#include <vm/vm_map.h>
#include <vm/vm_page.h>
+/*
+ * Use this define if you want to disable *fancy* VM things. Expect an
+ * approx 30% decrease in transfer rate. This could be useful for
+ * NetBSD or OpenBSD.
+ */
+/* #define PIPE_NODIRECT */
+
+/*
+ * interfaces to the outside world
+ */
static int pipe_read __P((struct file *fp, struct uio *uio,
struct ucred *cred));
static int pipe_write __P((struct file *fp, struct uio *uio,
@@ -121,11 +129,13 @@ static void pipebufferinit __P((struct pipe *cpipe));
static void pipeinit __P((struct pipe *cpipe));
static __inline int pipelock __P((struct pipe *cpipe, int catch));
static __inline void pipeunlock __P((struct pipe *cpipe));
+#ifndef PIPE_NODIRECT
static int pipe_build_write_buffer __P((struct pipe *wpipe, struct uio *uio));
static void pipe_destroy_write_buffer __P((struct pipe *wpipe));
static int pipe_direct_write __P((struct pipe *wpipe, struct uio *uio));
static void pipe_clone_write_buffer __P((struct pipe *wpipe));
static void pipe_mark_pages_clean __P((struct pipe *cpipe));
+#endif
static int pipewrite __P((struct pipe *wpipe, struct uio *uio, int nbio));
static void pipespace __P((struct pipe *cpipe));
@@ -198,6 +208,7 @@ pipespace(cpipe)
/*
* Create an object, I don't like the idea of paging to/from
* kernel_object.
+ * XXX -- minor change needed here for NetBSD/OpenBSD VM systems.
*/
cpipe->pipe_buffer.object = vm_object_allocate(OBJT_DEFAULT, npages);
cpipe->pipe_buffer.buffer = (caddr_t) vm_map_min(kernel_map);
@@ -205,6 +216,7 @@ pipespace(cpipe)
/*
* Insert the object into the kernel map, and allocate kva for it.
* The map entry is, by default, pageable.
+ * XXX -- minor change needed here for NetBSD/OpenBSD VM systems.
*/
error = vm_map_find(kernel_map, cpipe->pipe_buffer.object, 0,
(vm_offset_t *) &cpipe->pipe_buffer.buffer,
@@ -242,6 +254,7 @@ pipeinit(cpipe)
splx(s);
bzero(&cpipe->pipe_sel, sizeof cpipe->pipe_sel);
+#ifndef PIPE_NODIRECT
/*
* pipe data structure initializations to support direct pipe I/O
*/
@@ -249,6 +262,7 @@ pipeinit(cpipe)
cpipe->pipe_map.kva = 0;
cpipe->pipe_map.pos = 0;
cpipe->pipe_map.npages = 0;
+#endif
}
@@ -287,6 +301,17 @@ pipeunlock(cpipe)
return;
}
+static __inline void
+pipeselwakeup(cpipe)
+ struct pipe *cpipe;
+{
+ if (cpipe->pipe_state & PIPE_SEL) {
+ cpipe->pipe_state &= ~PIPE_SEL;
+ selwakeup(&cpipe->pipe_sel);
+ }
+}
+
+#ifndef PIPE_NODIRECT
#if 0
static void
pipe_mark_pages_clean(cpipe)
@@ -304,6 +329,7 @@ pipe_mark_pages_clean(cpipe)
}
}
#endif
+#endif
/* ARGSUSED */
static int
@@ -343,6 +369,7 @@ pipe_read(fp, uio, cred)
rpipe->pipe_buffer.cnt -= size;
nread += size;
+#ifndef PIPE_NODIRECT
/*
* Direct copy, bypassing a kernel buffer.
*/
@@ -365,6 +392,7 @@ pipe_read(fp, uio, cred)
rpipe->pipe_state &= ~PIPE_DIRECTW;
wakeup(rpipe);
}
+#endif
} else {
/*
* detect EOF condition
@@ -443,13 +471,14 @@ pipe_read(fp, uio, cred)
wakeup(rpipe);
}
}
- if (rpipe->pipe_state & PIPE_SEL) {
- rpipe->pipe_state &= ~PIPE_SEL;
- selwakeup(&rpipe->pipe_sel);
- }
+
+ if ((rpipe->pipe_buffer.size - rpipe->pipe_buffer.cnt) > 0)
+ pipeselwakeup(rpipe);
+
return error;
}
+#ifndef PIPE_NODIRECT
/*
* Map the sending processes' buffer into kernel space and wire it.
* This is similar to a physical write operation.
@@ -624,17 +653,13 @@ retry:
goto error1;
}
- if (wpipe->pipe_state & PIPE_WANTR) {
- wpipe->pipe_state &= ~PIPE_WANTR;
- wakeup(wpipe);
- }
-
error = 0;
while (!error && (wpipe->pipe_state & PIPE_DIRECTW)) {
if (wpipe->pipe_state & PIPE_EOF) {
pipelock(wpipe, 0);
pipe_destroy_write_buffer(wpipe);
pipeunlock(wpipe);
+ pipeselwakeup(wpipe);
wakeup(wpipe);
return EPIPE;
}
@@ -642,6 +667,7 @@ retry:
wpipe->pipe_state &= ~PIPE_WANTR;
wakeup(wpipe);
}
+ pipeselwakeup(wpipe);
error = tsleep(wpipe, PRIBIO|PCATCH, "pipdwt", 0);
}
@@ -662,6 +688,7 @@ error1:
wakeup(wpipe);
return error;
}
+#endif
static __inline int
pipewrite(wpipe, uio, nbio)
@@ -692,6 +719,7 @@ pipewrite(wpipe, uio, nbio)
orig_resid = uio->uio_resid;
while (uio->uio_resid) {
int space;
+#ifndef PIPE_NODIRECT
/*
* If the transfer is large, we can gain performance if
* we do process-to-process copies directly.
@@ -704,6 +732,7 @@ pipewrite(wpipe, uio, nbio)
}
continue;
}
+#endif
/*
* Pipe buffered writes cannot be coincidental with
@@ -766,6 +795,7 @@ pipewrite(wpipe, uio, nbio)
wpipe->pipe_state &= ~PIPE_WANTR;
wakeup(wpipe);
}
+
/*
* don't block on non-blocking I/O
*/
@@ -774,6 +804,12 @@ pipewrite(wpipe, uio, nbio)
break;
}
+ /*
+ * We have no more space and have something to offer,
+ * wake up selects.
+ */
+ pipeselwakeup(wpipe);
+
wpipe->pipe_state |= PIPE_WANTW;
if (error = tsleep(wpipe, (PRIBIO+1)|PCATCH, "pipewr", 0)) {
break;
@@ -817,11 +853,12 @@ pipewrite(wpipe, uio, nbio)
wpipe->pipe_mtime = time;
splx(s);
}
-
- if (wpipe->pipe_state & PIPE_SEL) {
- wpipe->pipe_state &= ~PIPE_SEL;
- selwakeup(&wpipe->pipe_sel);
- }
+ /*
+ * We have something to offer,
+ * wake up select.
+ */
+ if (wpipe->pipe_buffer.cnt > 0)
+ pipeselwakeup(wpipe);
--wpipe->pipe_busy;
return error;
@@ -869,7 +906,10 @@ pipe_ioctl(fp, cmd, data, p)
return (0);
case FIONREAD:
- *(int *)data = mpipe->pipe_buffer.cnt;
+ if (mpipe->pipe_state & PIPE_DIRECTW)
+ *(int *)data = mpipe->pipe_map.cnt;
+ else
+ *(int *)data = mpipe->pipe_buffer.cnt;
return (0);
case SIOCSPGRP:
@@ -968,10 +1008,7 @@ pipeclose(cpipe)
struct pipe *ppipe;
if (cpipe) {
- if (cpipe->pipe_state & PIPE_SEL) {
- cpipe->pipe_state &= ~PIPE_SEL;
- selwakeup(&cpipe->pipe_sel);
- }
+ pipeselwakeup(cpipe);
/*
* If the other side is blocked, wake it up saying that
@@ -987,10 +1024,7 @@ pipeclose(cpipe)
* Disconnect from peer
*/
if (ppipe = cpipe->pipe_peer) {
- if (ppipe->pipe_state & PIPE_SEL) {
- ppipe->pipe_state &= ~PIPE_SEL;
- selwakeup(&ppipe->pipe_sel);
- }
+ pipeselwakeup(ppipe);
ppipe->pipe_state |= PIPE_EOF;
wakeup(ppipe);
@@ -1006,12 +1040,14 @@ pipeclose(cpipe)
(vm_offset_t)cpipe->pipe_buffer.buffer,
cpipe->pipe_buffer.size);
}
+#ifndef PIPE_NODIRECT
if (cpipe->pipe_map.kva) {
amountpipekva -= cpipe->pipe_buffer.size + PAGE_SIZE;
kmem_free(kernel_map,
cpipe->pipe_map.kva,
cpipe->pipe_buffer.size + PAGE_SIZE);
}
+#endif
free(cpipe, M_TEMP);
}
}
OpenPOWER on IntegriCloud