From owner-freebsd-bugs@FreeBSD.ORG Mon May 5 20:40:32 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A340837B49A for ; Mon, 5 May 2003 20:40:28 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 344BC43FAF for ; Mon, 5 May 2003 20:40:28 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h463eSUp038516 for ; Mon, 5 May 2003 20:40:28 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h463eSLM038515; Mon, 5 May 2003 20:40:28 -0700 (PDT) Date: Mon, 5 May 2003 20:40:28 -0700 (PDT) Message-Id: <200305060340.h463eSLM038515@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: "Dorr H. Clark" Subject: Re: misc/41331: Pthread library open sets O_NONBLOCK flag andcauses unnecessary EAGAIN errors especially with /dev/stdout. X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: "Dorr H. Clark" List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 06 May 2003 03:40:32 -0000 The following reply was made to PR misc/41331; it has been noted by GNATS. From: "Dorr H. Clark" To: freebsd-gnats-submit@FreeBSD.org, alo@iki.fi Cc: Subject: Re: misc/41331: Pthread library open sets O_NONBLOCK flag and causes unnecessary EAGAIN errors especially with /dev/stdout. Date: Mon, 05 May 2003 20:37:20 -0700 42943 is a duplicate of 41331, or at best an extended symptom. First of all, both 41331 and 42943 occur on purpose, and this is not a regression introduced by some other change, it is part of the original pthread code. We believe that this behavior is a side effect of the FreeBSD threads implementation, and that 41331 and 42943 are normal behavior. These bugs can only plausibly be addressed by rearchitecting the threads implementation, possibly in the context of 5.x. In FreeBSD, the pthread implementation is as a user-level thread package, in other words, all threads execute in the context of a single process, and the thread scheduler is hidden in the threaded version of libc. As a side-effect of this implementation, when a blocking system call is executed, the kernel only knows about the process, and this results in all the threads being blocked. To avoid blocking the entire thread group, the stdin, stdout and stderr file descriptors are made non-blocking. Note that while these two bugs were filed against the recent 4.x releases, there is nothing new in this area. The code governing this behavior has 2.x and 3.x labels in the CVS tree. In 41331, there is a test program, and as part of our investigation we tried this program on both Solaris and Linux. Neither one exhibits the 41331 behavior, however readers who are familiar with the threads implementation will realize that these are three radically different threads implementations, accounting for the discrepancy. If the 41331 behavior is intolerable, there are two possible approaches, either wait for a pthreads implementation on top of the kernel threads in FreeBSD 5.0 or install the linuxthreads port, which simulates the Linux way of handling threads as separate processes. NOTE: The following code excerpt is from 4.7-STABLE ! Here are two code snips which control this behavior. code snip from libc_r/uthread/pthread_private.h : /* * Standard I/O file descriptors need special flag treatment since * setting one to non-blocking does all on *BSD. Sigh. This array * is used to store the initial flag settings. */ SCLASS int _pthread_stdio_flags[3]; code snip from uthread_fd.c : /* Check if a stdio descriptor: */ if ((fd < 3) && (_pthread_stdio_flags[fd] != -1)) /* * Use the stdio flags read by * _pthread_init() to avoid * mistaking the non-blocking * flag that, when set on one * stdio fd, is set on all stdio * fds. */ entry->flags = _pthread_stdio_flags[fd]; /* * Make the file descriptor non-blocking. * This might fail if the device driver does * not support non-blocking calls, or if the * driver is naturally non-blocking. */ saved_errno = errno; _thread_sys_fcntl(fd, F_SETFL, entry->flags | O_NONBLOCK); errno = saved_errno; Rashmi Venkatesh, engineer Dorr H. Clark, advisor COEN 284 - Operating Systems Case Study Santa Clara University, Santa Clara CA.