diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2005-08-01 06:26:17 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2005-08-01 06:26:17 +0000 |
commit | dbedcf24fda95b4403397fc32202bbe9f8c661cf (patch) | |
tree | 4d1d2b5dc9b4a11d4c3b2e3117150ed5409a2efd /sys/kern | |
parent | 690c061598767430d8ee5fada3b2476df9f51fa9 (diff) |
sys_select() used to use 6 local fd_set's in case the width was <= the
size of an fd_set (ie. 256 bits), to avoid the malloc. that is a lot
of local storage. change the cross-over point to 32-bits, which is more
fair. if you select with large widths, you pay the price. tested by
dlg, read by millert and pascoe, run on all machines
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/sys_generic.c | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 4d3870b1b82..b1e2cd19144 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_generic.c,v 1.49 2004/06/24 19:35:24 tholo Exp $ */ +/* $OpenBSD: sys_generic.c,v 1.50 2005/08/01 06:26:16 deraadt Exp $ */ /* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */ /* @@ -62,7 +62,7 @@ #include <uvm/uvm_extern.h> -int selscan(struct proc *, fd_set *, fd_set *, int, register_t *); +int selscan(struct proc *, fd_set *, fd_set *, int, int, register_t *); int seltrue(dev_t, int, struct proc *); void pollscan(struct proc *, struct pollfd *, u_int, register_t *); @@ -652,7 +652,8 @@ sys_select(struct proc *p, void *v, register_t *retval) syscallarg(fd_set *) ex; syscallarg(struct timeval *) tv; } */ *uap = v; - fd_set bits[6], *pibits[3], *pobits[3]; + fd_mask bits[6]; + fd_set *pibits[3], *pobits[3]; struct timeval atv, rtv, ttv; int s, ncoll, error = 0, timo; u_int nd, ni; @@ -663,7 +664,7 @@ sys_select(struct proc *p, void *v, register_t *retval) nd = p->p_fd->fd_nfiles; } ni = howmany(nd, NFDBITS) * sizeof(fd_mask); - if (nd > FD_SETSIZE) { + if (nd > sizeof(bits[0])) { caddr_t mbits; mbits = malloc(ni * 6, M_TEMP, M_WAITOK); @@ -676,12 +677,12 @@ sys_select(struct proc *p, void *v, register_t *retval) pobits[2] = (fd_set *)&mbits[ni * 5]; } else { bzero(bits, sizeof(bits)); - pibits[0] = &bits[0]; - pibits[1] = &bits[1]; - pibits[2] = &bits[2]; - pobits[0] = &bits[3]; - pobits[1] = &bits[4]; - pobits[2] = &bits[5]; + pibits[0] = (fd_set *)&bits[0]; + pibits[1] = (fd_set *)&bits[1]; + pibits[2] = (fd_set *)&bits[2]; + pobits[0] = (fd_set *)&bits[3]; + pobits[1] = (fd_set *)&bits[4]; + pobits[2] = (fd_set *)&bits[5]; } #define getbits(name, x) \ @@ -712,7 +713,7 @@ sys_select(struct proc *p, void *v, register_t *retval) retry: ncoll = nselcoll; p->p_flag |= P_SELECT; - error = selscan(p, pibits[0], pobits[0], nd, retval); + error = selscan(p, pibits[0], pobits[0], nd, ni, retval); if (error || *retval) goto done; if (SCARG(uap, tv)) { @@ -754,16 +755,17 @@ done: #undef putbits } - if (pibits[0] != &bits[0]) + if (pibits[0] != (fd_set *)&bits[0]) free(pibits[0], M_TEMP); return (error); } int -selscan(p, ibits, obits, nfd, retval) +selscan(p, ibits, obits, nfd, ni, retval) struct proc *p; fd_set *ibits, *obits; int nfd; + int ni; register_t *retval; { caddr_t cibits = (caddr_t)ibits, cobits = (caddr_t)obits; @@ -771,17 +773,9 @@ selscan(p, ibits, obits, nfd, retval) register int msk, i, j, fd; register fd_mask bits; struct file *fp; - int ni, n = 0; + int n = 0; static const int flag[3] = { POLLIN, POLLOUT, POLLPRI }; - /* - * if nfd > FD_SETSIZE then the fd_set's contain nfd bits (rounded - * up to the next byte) otherwise the fd_set's are normal sized. - */ - ni = sizeof(fd_set); - if (nfd > FD_SETSIZE) - ni = howmany(nfd, NFDBITS) * sizeof(fd_mask); - for (msk = 0; msk < 3; msk++) { fd_set *pibits = (fd_set *)&cibits[msk*ni]; fd_set *pobits = (fd_set *)&cobits[msk*ni]; |