Re: Thread implementations, poll, etc.

Richard Gooch (Richard.Gooch@atnf.CSIRO.AU)
Wed, 24 Jun 1998 19:11:58 +1000


Mike Ditto writes:
> I just got caught up on 3 days worth of interesting discussion; here are
> some points that I didn't see made. Everything I say here about poll()
> applies equally to select(), of course.

Have you read:
http://www.atnf.csiro.au/~rgooch/linux/docs/io-events.html ?

> Someone said that if regular files supported poll(), "tail -f" could use
> poll() instead of sleep(). This is not true; it is a common
> misconception about what poll actually does. A poll for reading doesn't
> mean "wake me when there are data which I can read". It means "wake me
> when a read() would not block interruptibly. A read() on a regular file
> will never block interruptibly (at least by tradition, interruptible NFS
> mounts notwithstanding). Regular files already support poll() fully and
> correctly.

Yep.

> Someone said that poll on regular files is the same as async I/O. It
> isn't. poll isn't I/O at all. Operations under any async I/O paradigm
> actually perform I/O and notify asynchronously of completion. poll
> never performs I/O, it only gives the caller stale information about
> whether certain hypothetical I/O operations would block. This is one of
> the flaws in select, poll, ioctl(FIONREAD) and similar kludges. Between
> the time that the call returns and the time you try to do something
> about it, things can change. If you are correctly using non-blocking
> operations, this is probably only a performance problem (you would just
> loop back into another poll), but if you assume that the information
> from poll is more than a hint, you can reach deadlock or some other
> failure.
>
> True async I/O requires that the actual I/O be asynchronous, not just a
> mechanism for waiting until it is safe to do synchronous I/O.

Yep.

> Someone claimed that poll() could benefit from a wake-one implementation
> or option. This doesn't make sense for two reasons. First, it just
> doesn't make sense to have more than one context polling for the same
> readiness condition, for the reasons above. Second, after the chosen
> thread is awoken, what should happen to the other polling threads? They
> are still in a poll() system call, one of the file descriptors they are
> polling is ready, and there is no real guarantee that the awoken thread
> will do anything with the ready fd any time soon. It may have other
> ready fds or other internal processing to do first, or just be hosed in
> general. The situation is one where the semantics of poll() say that
> the other threads should wake up, but you "don't want" them to, but
> there is no reasonable condition defined for when this special exception
> period should end.
>
> poll() is a substitute for multithreading and just wasn't meant to work
> well in conjunction with multithreading. Because of the nature of
> poll() it is most robust to multiplex your polling of any one condition
> through one thread and pass off the events to other threads, even though
> this has unfortunate performance costs.

Yep.

> Someone wondered what it would mean to be polling a file descriptor and
> have that file descriptor become closed (either by closing it in another
> thread, or by using some new asynchronous form of polling). The proper
> semantics of poll() say that the poll should immediately report the
> closed file descriptor as "ready" because a read() would not block, it
> would immediately return (with EBADF).

I don't recall seeing that. I did speculate what should happen if a FD
is ready, causing a event message to be sent, and then the FD is
closed by a different thread. Different story from poll(2) and closing
FDs, though.

> Some people proposed various forms of asynchronous I/O or asynchronous
> polling. Asynchronous I/O is not a bad idea, but it is a very different
> paradigm from that of Unix. I find the idea of asynchronous polling,
> however, absolutely hideous. It just adds a messy, complex interface on
> top of a flawed incomplete alternative to true threads. An asynchronous
> programming model would be much better based on true async I/O, with
> completion messages indicating that the I/O is complete.

Don't recall seeing that one.

> But all currently implemented or proposed asynchronous I/O schemes (of
> course there probably some of which I am not aware) are still incomplete
> alternatives to threads. There are many operations for which one needs
> to wait that are not strictly I/O operations, or at least do not use the
> read/write/file descriptor model. Examples: wait(), connect(),
> pause(). Threads are really the only way to get everything right.

We want to be careful not to create zillions of threads, though, as
they have a cost too.

> The idea of implementing async I/O on top of threads seems completely
> backward to me. If I were designing and implementing a OS from scratch,
> I would have the kernel provide only asynchronous I/O, and no threads.
> Every single system call would be asynchronous in structure, although
> most operations would no doubt be marked as already completed when the
> trap returned. One version of libc would wrap these asynchronous calls
> inside synchronous wrappers, doing an explicit wait for completion after
> every call, providing a traditional Unix-like model. Another version of
> libc would implement threads, doing a wait for completion only when all
> threads were sleeping. Another version of libc could make the
> asynchronous interfaces themselves available.

If userland AIO (using threads) works just as well as a kernel-space
AIO implementation, then there is no need for a kernel-space
implementation. We'll only know if both scheme are implemented and
benchmarked.

> Note that the above hypothetical system fails to give any parallelism
> benefit to a single running process on a MP system. This is fine by me.
> Threads are a programming paradigm, not a perfomance tool. If you want
> parallelism, use fork().

Not for my parallel rendering task, thanks. I'll use threads: it's a
more natural environment than fork(2).

> I'm sure at least that last statement will get some disagreement. :)

Yep.

Regards,

Richard....

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu