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>