Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Oct 1998 11:10:00 -0800 (PST)
From:      Peter Wemm <peter@netplex.com.au>
To:        freebsd-bugs@FreeBSD.ORG
Subject:   Re: kern/8500: FreeBSD 3.0 thread scheduler is broken 
Message-ID:  <199810311910.LAA29905@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/8500; it has been noted by GNATS.

From: Peter Wemm <peter@netplex.com.au>
To: HighWind Software Information <info@highwind.com>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: kern/8500: FreeBSD 3.0 thread scheduler is broken 
Date: Sun, 01 Nov 1998 03:08:44 +0800

 HighWind Software Information wrote:
 > 
 >    > >Number:         8500
 >    > >Category:       kern
 >    > >Synopsis:       FreeBSD 3.0 thread scheduler is broken
 >    > 
 >    > >Description:
 >    > When an application has threads that are I/O intensive, that thread
 >    > unfairly steals cycles from all other threads. This makes writing
 >    > an MT program that does any real amount of I/O impossible.
 > 
 >    Yes, open(), read(), write(), etc block the entire process.  The libc_r 
 >    thread engine only works for things that can be select()ed apon, and read/
 >    write cannot (yet).
 > 
 > Ummm. Not to be rude.. But...
 > 
 > That is NOT TRUE AT ALL. read() and write() CERTAINLY are selected
 > apon and do NOT block the whole process when using libc_r.
 > 
 > Read /usr/src/lib/libc_r/uthread/uthread_write.c and see for yourself.
 
 Yes, but only if the file descriptor itself supports O_NONBLOCK mode..
 
 /* called by open() wrapper */
 _thread_fd_table_init(int fd)
 { ...
                 /* Get the flags for the file: */
                 if (fd >= 3 && (entry->flags =
                     _thread_sys_fcntl(fd, F_GETFL, 0)) == -1) {
                         ret = -1;
                     }
                 else {
  ...
 }
 
 And in write(), it just calls the write system call:
 write()
 {
 ....
                 /* Check if file operations are to block */
                 blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0);
 
                 /*
                  * Loop while no error occurs and until the expected number
                  * of bytes are written if performing a blocking write:
                  */
                 while (ret == 0) {
                         /* Perform a non-blocking write syscall: */
                             ^^^^^^^^^^^^^^^^^ - only if opened in O_NONBLOCK
                         n = _thread_sys_write(fd, buf + num, nbytes - num);
 
                         /* Check if one or more bytes were written: */
                         if (n > 0)
 
 It's similar for read().
 
 There's a couple of big ifs so far.  *If* you open the file in O_NONBLOCK 
 mode specifically, then you get non-blocking read/write syscalls.  The 
 syscalls themselves are only non-blocking *if* the underlying fd supports 
 it.  Sockets and pipes support it.  Files (at least on ufs/ffs) do not.  
 No matter whether you ask for O_NONBLOCK or not, you will always get a 
 blocking read/write with disk IO with read and write.
 
 >    The only alternatives are to use the aio/lio syscalls (which work), or 
 >    rfork().  libc_r could probably be modified to use rfork() to have the 
 >    read/write/open/close/etc done in parallel.
 > 
 > I don't think that is necessary.
 
 It is if you want the threading to continue while the disk is grinding 
 away.  aio_read() and aio_write() would probably be enough to help file 
 IO, but open() will still be blocking.
 
 Squid has some fairly extensive async disk-IO routines.  They happen to 
 use pthreads as a mechanism of having child processes do the blocking 
 work.  FreeBSD could use rfork() for arranging the blocking stuff in child 
 processes with shared address space.  It would be a lot of work though, 
 and would be a problem on SMP systems.
 
 > -Rob
 
 Cheers,
 -Peter
 
 

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199810311910.LAA29905>