Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Aug 2001 13:55:50 -0400 (EDT)
From:      Daniel Eischen <eischen@vigrid.com>
To:        Jonathan Chen <jon@freebsd.org>
Cc:        "Daniel M. Eischen" <eischen@vigrid.com>, hackers@freebsd.org
Subject:   Re: pthreads and poll()
Message-ID:  <Pine.SUN.3.91.1010814133403.3623A-100000@pcnet1.pcnet.com>
In-Reply-To: <20010814093518.A26202@enterprise.spock.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 14 Aug 2001, Jonathan Chen wrote:
> On Mon, Aug 13, 2001 at 01:18:52PM -0400, Daniel M. Eischen wrote:
> > We don't provide locking for fd's any longer (I thought this was only in
> > -current, but your results seem to indicate otherwise).  If we did, only
> > one thread would wake up.  The mistake in your sample seems to be that
> > you're having all threads block on the same fd.  Why?
> 
> Consider a threaded server application, where N threads are blocking on 
> M descriptors (M>>N).  The test code is merely a simplified version of this 
> scenario.  I don't think this is a mistake, is it?

Why not have one thread to poll and read the request handing it off
to a worker thread to execute?

Why even bother to poll?  You could use a mutex and condition variable
to protect the fd while reading from it.  After it reads what it wants,
it can signal the condition variable to wakeup the next thread.  poll(2)
is a system call, pthread_mutex_[un]lock(3), pthread_cond_signal(3),
and pthread_cond_wait(3) are not (at least in FreeBSD).

> > We took the approach in -current that it is up to the application to
> > provide locking for fd's.  Our libc_r also wraps poll() into non-blocking
> > calls which allows the other threads to run and "block" on the same
> > fd.  When we get blocking down in the kernel (KSEs or a linuxthreads
> > like approach), I'm not exactly sure what would happen.  From your
> > results (linuxthreads under FreeBSD), it looks like it should behave
> > as you expect.
> 
> Okay, I can understand why FreeBSD would do it this way, and why it might 
> be a good thing to leave it up to the application to provide the locking.  
> But on the flip side, it might be expensive to wake all the threads up when 
> only one has any real work to do.

It's not really any extra work in our current libc_r.  It has to
walk the list of threads waiting for I/O anyways.

> I'm at a loss though, on how I could efficiently do locking so only one
> thread actually read() on the fd.  If I create a mutex per fd, and lock it
> with one thread between poll() and read(), then other threads could do a
> blocking lock on the mutex, which would decrease the benefits of threading;
> or they could do non-blocking trylock's.  In this case I could either make
> the thread continue to poll as before (which might starve the thread with
> the lock) or I can turn off polling on that fd (which might create a
> situation where a thread polls for no fd's and never again wakes up).  I
> suppose I could be missing something incredibly simple, but where I stand
> right now I don't see a solution...
> 
> Yes, I suppose I could just make the fd's non-blocking and catch the error 
> on read(), but that's not too convenient and I was hoping for some other 
> simple way to do this...
> 
> Incidentally, I'm still curious, what does the POSIX spec say all this?

It doesn't cover poll(2).  You can see what Single Unix Specification
(version 2) has to say at:

  http://www.opengroup.org

The URL for poll(2) is below, but I'm not sure if you have to be a
member or not (membership is free) in order to view it:

  http://www.opengroup.org/onlinepubs/7908799/xsh/poll.html

With my pthreads hat on, polling the same file descriptor from
multiple threads seems like it should inform all interested threads.

-- 
Dan Eischen

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.SUN.3.91.1010814133403.3623A-100000>