Date: Mon, 17 Feb 1997 23:14:32 +0300 (MSK) From: =?KOI8-R?B?4c7E0sXKIP7F0s7P1w==?= <ache@nagual.ru> To: Bruce Evans <bde@zeta.org.au> Cc: cvs-all@freefall.freebsd.org, CVS-committers@freefall.freebsd.org, cvs-sys@freefall.freebsd.org, mpp@freefall.freebsd.org, peter@spinner.dialix.com Subject: Re: cvs commit: src/sys/sys types.h Message-ID: <Pine.BSF.3.95q.970217230822.1510A-100000@nagual.ru> In-Reply-To: <199702170639.RAA18161@godzilla.zeta.org.au>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 17 Feb 1997, Bruce Evans wrote: > It is really the allocation unit size. 2048 is almost arbitrary. It is > the next power of 2 up from the number of bits required for 6 fd_set's > with the current FD_SETSIZE (6 * 256 = 1536). Hmm. I don't think that this constant plays any essential role, the only requirement that re-allocation must not occurse too often. In my new variant I not use it at all and code looks much cleaner. > Don't round up to the allocation unit here. Set ni = roundup(uap->nd, > NFDBITS). Then if (ni <= (OLD_FD_SETSIZE = 32 * NBBY)), use an auto > buffer of size 6*OLD_FD_SETSIZE bits. Otherwise, use a malloced buffer > (malloc a larger one if ni > p->p_selbits_size). This can be simplified > by always mallocing and freeing at the end. Space can be saved by > reducing ni first for the common case when there are no exceptfd's etc. I implement somehing like you say. > >--- 549,579 ---- > > free (p->p_selbits, M_SELECT); > > > > while (p->p_selbits_size < ni) > >! p->p_selbits_size += > >! howmany(FD_ROUNDSIZE, NFDBITS) * > >! sizeof(fd_mask); > > This can be simplified to something like p_selbytes_allocated = > roundup2(6 * ni, FD_ROUNDSIZE) / NBBY. Don't use exactly this - > it assumes that FD_ROUNDSIZE is both a multiple of NBBY and a > power of 2. FD_ROUNDSIZE should be defined as a multiple of NBBY, > and it won't be a power of 2 on weird machines. As I already say I use much simpler thing here, just roundup(). > I think there is a problem caused by stupid handling of NULL fdsets. > Nothing is copied in, but selscan() wastes time scanning the buffers. > It depends on the current behaviour of bzeroing everything. Fixing > this would be a useful optimization than reducing the amount to > bzero :-). I fix this thing in selscan(). Updated patch variant: *** sys_generic.c.orig Tue Jan 14 23:11:28 1997 --- sys_generic.c Mon Feb 17 22:57:03 1997 *************** *** 508,513 **** --- 508,515 ---- return (error); } + #define FD_CHUNKSIZE 256 + static int nselcoll; int selwait; *************** *** 527,533 **** register struct select_args *uap; int *retval; { ! fd_mask *ibits[3], *obits[3]; struct timeval atv; int s, ncoll, error = 0, timo, i; u_int ni; --- 529,536 ---- register struct select_args *uap; int *retval; { ! fd_mask s_selbits[(3 + 3) * howmany(FD_CHUNKSIZE, NFDBITS)]; ! fd_mask *ibits[3], *obits[3], *selbits; struct timeval atv; int s, ncoll, error = 0, timo, i; u_int ni; *************** *** 538,571 **** if (uap->nd > p->p_fd->fd_nfiles) uap->nd = p->p_fd->fd_nfiles; /* forgiving; slightly wrong */ ! /* The amount of space we need to allocate */ ! ni = howmany(roundup2 (uap->nd, FD_SETSIZE), NFDBITS) * ! sizeof(fd_mask); ! ! if (ni > p->p_selbits_size) { ! if (p->p_selbits_size) ! free (p->p_selbits, M_SELECT); ! while (p->p_selbits_size < ni) ! p->p_selbits_size += 32; /* Increase by 256 bits */ ! p->p_selbits = malloc(p->p_selbits_size * 6, M_SELECT, ! M_WAITOK); } for (i = 0; i < 3; i++) { ! ibits[i] = (fd_mask *)(p->p_selbits + i * p->p_selbits_size); ! obits[i] = (fd_mask *)(p->p_selbits + (i + 3) * ! p->p_selbits_size); } ! ! /* ! * This buffer is usually very small therefore it's probably faster ! * to just zero it, rather than calculate what needs to be zeroed. ! */ ! bzero (p->p_selbits, p->p_selbits_size * 6); ! ! /* The amount of space we need to copyin/copyout */ ! ni = howmany(uap->nd, NFDBITS) * sizeof(fd_mask); #define getbits(name, x) \ if (uap->name && \ --- 541,587 ---- if (uap->nd > p->p_fd->fd_nfiles) uap->nd = p->p_fd->fd_nfiles; /* forgiving; slightly wrong */ ! /* The amount of space we need to copyin/copyout */ ! ni = howmany(uap->nd, NFDBITS) * sizeof(fd_mask); ! if (ni <= sizeof(s_selbits) / (3 + 3)) ! selbits = s_selbits; ! else { ! if (ni > p->p_selbits_size) { ! if (p->p_selbits_size) ! free (p->p_selbits, M_SELECT); ! ! p->p_selbits_size = roundup(ni, ! howmany(FD_CHUNKSIZE, NFDBITS) * ! sizeof(fd_mask)); ! p->p_selbits = malloc(p->p_selbits_size * 6, M_SELECT, ! M_WAITOK); ! } ! selbits = p->p_selbits; } + for (i = 0; i < 3; i++) { ! obits[i] = (fd_mask *)(selbits + i * ni); ! ibits[i] = (fd_mask *)(selbits + (i + 3) * ni); } ! i = 0; ! if (uap->ex) ! i = 3; ! else ! ibits[2] = NULL; ! if (uap->ou) { ! if (i == 0) ! i = 2; ! } else ! ibits[1] = NULL; ! if (uap->in) { ! if (i == 0) ! i = 1; ! } else ! ibits[0] = NULL; ! if (i != 0) ! bzero(selbits, i * ni); #define getbits(name, x) \ if (uap->name && \ *************** *** 654,670 **** static int flag[3] = { FREAD, FWRITE, 0 }; for (msk = 0; msk < 3; msk++) { ! for (i = 0; i < nfd; i += NFDBITS) { ! bits = ibits[msk][i/NFDBITS]; ! while ((j = ffs(bits)) && (fd = i + --j) < nfd) { ! bits &= ~(1 << j); ! fp = fdp->fd_ofiles[fd]; ! if (fp == NULL) ! return (EBADF); ! if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) { ! obits[msk][(fd)/NFDBITS] |= ! (1 << ((fd) % NFDBITS)); ! n++; } } } --- 670,688 ---- static int flag[3] = { FREAD, FWRITE, 0 }; for (msk = 0; msk < 3; msk++) { ! if (ibits[msk]) { ! for (i = 0; i < nfd; i += NFDBITS) { ! bits = ibits[msk][i/NFDBITS]; ! while ((j = ffs(bits)) && (fd = i + --j) < nfd) { ! bits &= ~(1 << j); ! fp = fdp->fd_ofiles[fd]; ! if (fp == NULL) ! return (EBADF); ! if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) { ! obits[msk][(fd)/NFDBITS] |= ! (1 << ((fd) % NFDBITS)); ! n++; ! } } } } -- Andrey A. Chernov <ache@null.net> http://www.nagual.ru/~ache/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95q.970217230822.1510A-100000>