USB bulk read & pthreads

Terry Lambert tlambert2 at mindspring.com
Thu May 22 09:00:39 PDT 2003


Jay Cornwall wrote:
> > I don't count it as a bug as noone ever told that it does.
> > It's even documented in ugen(4):
> >      The bulk transfer mode can be in or out depending on the endpoint.  To
> >      perform I/O on a bulk endpoint read(2) and write(2) should be used.
> > All I/O operations on a bulk endpoint are unbuffered.
> > non-blocking requires buffered I/O.
> 
> Yes, blocking I/O isn't a problem for this application (as it's thread-based).
> The problem arises from ugen blocking the entire process, rather than just
> the thread which invoked the blocking read.

It's the blocking I/O.

The FreeBSD default libc_r utilizes a call-conversion scheduler
that converts a blocking call into a non-blocking call plus a
thread context switch in a user-space scheduler.

If the conversion from a blocking call to a non-blocking call
fails, then it will hang waiting for the operation to complete.
For fd-based operations, the conversion is done on the basis of
setting the O_NDELAY flag on the descriptor, and using normal
fd system calls, which return -1 and an errno of "EAGAIN" when
the operation would have blocked.  The underlying code is then
expected to have started the entirety of the requested operation,
if it's a read.  Short reads and writes, if a block would occur
after a partial transfer, are wrappered to allow retry at a
later point, until the entire request is satisfied.

NB: The page fault path in the NBIO read-from-file case fails to
start the operation and then return immediately.  I personally
consider this a bug, but all it effectively does is add latency,
not hang, like you are experiencing.

-- Terry


More information about the freebsd-hackers mailing list