*BSD News Article 58305


Return to BSD News archive

Newsgroups: comp.unix.bsd.bsdi.misc,comp.unix.advocacy
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!news.mel.connect.com.au!munnari.OZ.AU!news.ecn.uoknor.edu!paladin.american.edu!zombie.ncsc.mil!news.mathworks.com!newsfeed.internetmci.com!howland.reston.ans.net!ix.netcom.com!netcom.com!bakul
From: bakul@netcom.com (Bakul Shah)
Subject: Re: multiple httpds vs threads vs ... (was BSDI Vs. NT...)
Message-ID: <bakulDK9GrA.B2p@netcom.com>
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
References: <taxfree.3.00C439A1@primenet.com> <4be592$6tb@madeline.ins.cwru.edu> <4bhfmp$gei@Mars.mcs.com> <DK5Crs.I77@metrics.com> <4bmsjp$7lv@elf.bsdi.com> <bakulDK7u6M.LrM@netcom.com> <4brlt5$8un@sungy.Germany.Sun.COM>
Date: Wed, 27 Dec 1995 19:57:09 GMT
Lines: 61
Sender: bakul@netcom22.netcom.com
Xref: euryale.cc.adfa.oz.au comp.unix.bsd.bsdi.misc:1860 comp.unix.advocacy:12683

Casper.Dik@Holland.Sun.COM writes:
>That's not correct.  Most modern implementations allow you to redefine
>FDSET_SIZE to anything you please by defining FDSET_SIZE before including
>the header that usually defines it (the header defines FDSET_SIZE only
>if not previously defined).

You can redefine FDSET_SIZE but the problem is that the *kernel*
routine implementing select() on some implementations uses
FDSET_SIZE or some such _compile time_ parameter to allocate
space on the kernel stack for select args.  So if your program is
compiled with a bigger FDSET_SIZE that the one used by the
kernel, you lose on fds beyond the kernel limit.  If the kernel
dynamically allocated space for select fdset args, a user can use
as large a fdset as his fd limit.

You should be able to use select() on any fd you can get but this
is not true for most select() implementations.

>System V Poll() is much better in that respect, as it gives the application
>full control over how many fds you use.  The set-size is yours to specifiy.
>(And poll allows to select for more than just read/write/exception).

It _is_ better but portable code can't rely on it exclusively.

[Speculation mode on]
Ideally I'd like to break up poll into a set of more efficient
syscalls.  Something like add_pollset(), remove_pollset(),
get_pollset() and check_pollset().  add_pollset adds new fds to
the set of fds we are interested in.  remove_pollset removes
them.  get_pollset tells us about the current set of interesting
fds.  check_pollset returns a set of fd on which interesting
events happened.  I'd also add a signal so that I don't have to
call check_poll until I am sure there is something waiting.
Given these, current poll() interface can be implemented
something like:

int
poll(struct pollfd * fds, int nfds, int timeout) {
	int n;
	struct pollfd fds_copy[nfds];
	struct timeval timeval = {timeout/1000, timeout%1000};
	memcpy(fds_copy, fds, nfds*sizeof(*fds));
	add_pollset(nfds, fds_copy);
	n = check_pollset(nfds, fds, timeout == -1 ? 0 : &timeval);
	remove_pollset(nfds, fds_copy);
	return n;
}

[Ofcourse, it would be silly to make three syscalls for poll() so
it would remain a syscall but something similar does happen in
the kernel.  Also, struct pollfd is not the ideal type for
{add,remove,get,check}_pollset but I wanted to keep the example
simple]

Typically the fd set of interest changes far less frequently than
the number of poll/select calls you make (you add/remove fds to
the set as clients arrive/leave).  At present the kernel has to
process every fd in the set every time poll/select is called,
which is quite wasteful for large fd sets.

Bakul Shah <bakul@netcom.com>